]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
* Apply upstream patch from Jeffrey Hutzelman to fix syscall probing on debian/1.4.4.dfsg1-5
authorRuss Allbery <rra@debian.org>
Tue, 17 Jul 2007 16:22:59 +0000 (16:22 +0000)
committerRuss Allbery <rra@debian.org>
Tue, 17 Jul 2007 16:22:59 +0000 (16:22 +0000)
  AMD64 with Linux 2.6.22 kernels.  (Closes: #430179)

debian/changelog
src/afs/LINUX/osi_probe.c

index 2c1b045474ab87b9ad797897ddf354bc28e1a89d..1990b9e22a08d32b1dc708c4ab74962016c86b66 100644 (file)
@@ -1,5 +1,7 @@
 openafs (1.4.4.dfsg1-5) unstable; urgency=low
 
+  * Apply upstream patch from Jeffrey Hutzelman to fix syscall probing on
+    AMD64 with Linux 2.6.22 kernels.  (Closes: #430179)
   * Add a union to des_ks_struct and reorder includes to get the correct
     alignment for DES code on SPARC.  Thanks, Chaskiel Grundman.  Partly
     addresses #415952.
@@ -14,7 +16,7 @@ openafs (1.4.4.dfsg1-5) unstable; urgency=low
     KeyFile and CellServDB.old from /etc/openafs/server, and remove
     BosConfig from /etc/openafs.
 
- -- Russ Allbery <rra@debian.org>  Mon, 16 Jul 2007 11:55:16 -0700
+ -- Russ Allbery <rra@debian.org>  Tue, 17 Jul 2007 09:25:03 -0700
 
 openafs (1.4.4.dfsg1-4) unstable; urgency=low
 
index 16b5322dd687177e1801158a528341f85d3da3a4..1a812367f6e566e74018693ca4704bb4ed65220b 100644 (file)
@@ -59,6 +59,7 @@
 #include "afsincludes.h"
 #endif
 #include <linux/version.h>
+#include <linux/sched.h>
 #ifdef CONFIG_H_EXISTS
 #include <linux/config.h>
 #endif
@@ -153,6 +154,7 @@ MODULE_PARM_DESC(probe_ignore_syscalls, "Syscalls to ignore in table checks");
  * 0x0010 - detail - check_harder
  * 0x0020 - detail - check_harder/zapped
  * 0x0040 - automatically ignore setgroups and afs_syscall
+ * 0x0080 - detail - check_table_readable
  */
 static int probe_debug = 0x41;
 #ifdef module_param
@@ -298,6 +300,10 @@ typedef struct {
     int debug_ignore_NR[4];         /* syscalls to ignore for debugging */
 } probectl;
 
+#if defined(AFS_I386_LINUX26_ENV) || defined(AFS_AMD64_LINUX26_ENV)
+static int check_access(unsigned long, int);
+static int check_table_readable(probectl *, PROBETYPE *);
+#endif
 
 
 /********** Probing Configuration: sys_call_table **********/
@@ -940,6 +946,11 @@ static int check_table(probectl *P, PROBETYPE *ptr)
     PROBETYPE *x;
     int i, j;
 
+#if defined(AFS_I386_LINUX26_ENV) || defined(AFS_AMD64_LINUX26_ENV)
+    i = check_table_readable(P, ptr);
+    if (i >= 0) return i;
+#endif
+
     for (x = ptr, i = 0; i < _SS(NR_syscalls); i++, x++) {
 #ifdef OSI_PROBE_DEBUG
        if (probe_debug & 0x0040) {
@@ -1062,6 +1073,11 @@ static int check_harder(probectl *P, PROBETYPE *p)
     unsigned long ip1;
     int i, s;
 
+#if defined(AFS_I386_LINUX26_ENV) || defined(AFS_AMD64_LINUX26_ENV)
+    i = check_table_readable(P, p);
+    if (i >= 0) return 0;
+#endif
+
     /* Check zapped syscalls */
     for (i = 1; i < P->n_zapped_syscalls; i++) {
        if (p[_SS(P->zapped_syscalls[i])] != p[_SS(P->zapped_syscalls[0])]) {
@@ -1349,7 +1365,7 @@ static void *do_find_syscall_table(probectl *P, char **method)
 }
 
 #if defined(AFS_I386_LINUX26_ENV) || defined(AFS_AMD64_LINUX26_ENV)
-static int check_writable(unsigned long address
+static int check_access(unsigned long address, int mode
 { 
     pgd_t *pgd = pgd_offset_k(address);
 #ifdef PUD_SIZE
@@ -1374,10 +1390,34 @@ static int check_writable(unsigned long address)
        pte = (pte_t *)pmd;
     else
        pte = pte_offset_kernel(pmd, address);
-    if (pte_none(*pte) || !pte_present(*pte) || !pte_write(*pte))
+    if (pte_none(*pte) || !pte_present(*pte))
+       return 0;
+    if (mode && !pte_write(*pte))
        return 0;
     return 1;
 }
+
+static int check_table_readable(probectl *P, PROBETYPE *ptr)
+{
+    PROBETYPE *next_page;
+    int i = 0, delta;
+
+    while (i < _SS(NR_syscalls)) {
+       next_page = (PROBETYPE *)PAGE_ALIGN((unsigned long)(ptr+1));
+       delta = next_page - ptr;
+       if (!check_access((unsigned long)ptr, 0)) {
+#ifdef OSI_PROBE_DEBUG
+           if (probe_debug & 0x0080)
+               printk("<7>osi_probe: %s                      0x%016lx not readable; delta=0x%lx\n",
+                      P->symbol, (unsigned long)ptr, delta);
+#endif
+           return delta - 1;
+       }
+       ptr += delta;
+       i += delta;
+    }
+    return -1;
+}
 #endif
 
 void *osi_find_syscall_table(int which)
@@ -1405,7 +1445,7 @@ void *osi_find_syscall_table(int which)
     }
     printk("Found %s at 0x%lx (%s)\n", P->desc, (unsigned long)answer, method);
 #if defined(AFS_I386_LINUX26_ENV) || defined(AFS_AMD64_LINUX26_ENV)
-    if (!check_writable((unsigned long)answer)) {
+    if (!check_access((unsigned long)answer, 1)) {
        printk("Address 0x%lx is not writable.\n", (unsigned long)answer);
        printk("System call hooks will not be installed; proceeding anyway\n");
        return 0;