Linux: Disable syscall probes if we have keyrings
authorSimon Wilkinson <sxw@inf.ed.ac.uk>
Thu, 20 May 2010 10:57:20 +0000 (11:57 +0100)
committerRuss Allbery <rra@stanford.edu>
Tue, 25 May 2010 04:15:26 +0000 (21:15 -0700)
If we are building for are kernel with keyrings, and we can
guarantee that we can make use of those keyrings, then we no longer
need to probe for the syscall table at all. Change our default
behaviour so that when these two conditions are true, syscall probing
is disabled. Both --enable-linux-syscall-probing and
--disable-linux-syscall-probing can be used to override the
autodetection and force things one way or the other.

We have to check that we can use the keyrings because there was a
window in the 2.6 kernel series where keryings were available, but
the key_type_keyring definiton (which we use to create the session
keyring) wasn't exported. In that situation, we attempt to traverse
the process table and use the type of init's session keyring. This
traversal is fragile, and if it fails, keyring PAGs will be disabled.
So, we still want to be able to fall back to patching the syscall
table, if we can, in this case.

FIXES 125215

Change-Id: I11ba5c68fe37609bbd6b9c9f7e7c699334f42ebc
Reviewed-on: http://gerrit.openafs.org/2002
Reviewed-by: Marc Dionne <marc.c.dionne@gmail.com>
Reviewed-by: Derrick Brashear <shadow@dementia.org>
Reviewed-by: Russ Allbery <rra@stanford.edu>
Tested-by: Russ Allbery <rra@stanford.edu>

acinclude.m4
src/afs/LINUX/osi_probe.c
src/afs/LINUX24/osi_probe.c

index 142bffe..2d1823d 100644 (file)
@@ -255,11 +255,10 @@ AC_ARG_ENABLE([optimize-pam],
     ,
     [enable_optimize_pam="yes"])
 AC_ARG_ENABLE([linux-syscall-probing],
-    [AS_HELP_STRING([--disable-linux-syscall-probing],
-       [disabling Linux syscall probing (defaults to enabled)])],
+    [AS_HELP_STRING([--enable-linux-syscall-probing],
+       [enable Linux syscall probing (defaults to autodetect)])],
     ,
-    [AC_DEFINE(ENABLE_LINUX_SYSCALL_PROBING, 1, 
-       [define to enable syscall table probes])])
+    [enable_linux_syscall_probing="maybe"])
     
 
 AC_ARG_WITH([xslt-processor],
@@ -918,9 +917,32 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*)
                 LINUX_KEY_ALLOC_NEEDS_CRED
                 LINUX_INIT_WORK_HAS_DATA
                 LINUX_REGISTER_SYSCTL_TABLE_NOFLAG
-                LINUX_EXPORTS_INIT_MM
-                 LINUX_EXPORTS_SYS_CHDIR
-                 LINUX_EXPORTS_SYS_OPEN
+
+                dnl If we are guaranteed that keyrings will work - that is
+                dnl  a) The kernel has keyrings enabled
+                dnl  b) The code is new enough to give us a key_type_keyring
+                dnl then we just disable syscall probing unless we've been
+                dnl told otherwise
+
+                AS_IF([test "$enable_linux_syscall_probing" = "maybe"],
+                  [AS_IF([test "$ac_cv_linux_keyring_support" = "yes" -a "$ac_cv_linux_exports_key_type_keyring" = "yes"],
+                         [enable_linux_syscall_probing="no"],
+                         [enable_linux_syscall_probing="yes"])
+                 ])
+
+                dnl Syscall probing needs a few tests of its own, and just
+                dnl won't work if the kernel doesn't export init_mm
+                AS_IF([test "$enable_linux_syscall_probing" = "yes"], [
+                   LINUX_EXPORTS_INIT_MM
+                  AS_IF([test "$ac_cv_linux_exports_init_mm" = "no"], [
+                     AC_MSG_ERROR(
+                      [Can't do syscall probing without exported init_mm])
+                   ])
+                  LINUX_EXPORTS_SYS_CHDIR
+                  LINUX_EXPORTS_SYS_OPEN
+                  AC_DEFINE(ENABLE_LINUX_SYSCALL_PROBING, 1,
+                            [define to enable syscall table probes])
+                ])
 
                 dnl Packaging and SMP build
                 if test "x$with_linux_kernel_packaging" = "xno" ; then
@@ -931,7 +953,9 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*)
 
                 dnl Syscall probing
                  if test "x$ac_cv_linux_config_modversions" = "xno" -o $AFS_SYSKVERS -ge 26; then
-                   AC_MSG_WARN([Cannot determine sys_call_table status. assuming it isn't exported])
+                  AS_IF([test "$enable_linux_syscall_probing" = "yes"], [
+                     AC_MSG_WARN([Cannot determine sys_call_table status. assuming it isn't exported])
+                  ])
                    ac_cv_linux_exports_sys_call_table=no
                   if test -f "$LINUX_KERNEL_PATH/include/asm/ia32_unistd.h"; then
                     ac_cv_linux_exports_ia32_sys_call_table=yes
index 5f87b70..c95f94c 100644 (file)
@@ -53,7 +53,7 @@
 # include "afs/param.h"
 #endif
 
-#if defined(ENABLE_LINUX_SYSCALL_PROBING) && defined(EXPORTED_INIT_MM)
+#if defined(ENABLE_LINUX_SYSCALL_PROBING)
 #include <linux/module.h> /* early to avoid printf->printk mapping */
 #include <scsi/scsi.h> /* for scsi_command_size */
 #ifndef OSI_PROBE_STANDALONE
index a731490..6527385 100644 (file)
@@ -52,7 +52,7 @@
 #include <afsconfig.h>
 #include "afs/param.h"
 #endif
-#if defined(ENABLE_LINUX_SYSCALL_PROBING) && defined(EXPORTED_INIT_MM)
+#if defined(ENABLE_LINUX_SYSCALL_PROBING)
 #ifdef AFS_LINUX24_ENV
 #include <linux/module.h> /* early to avoid printf->printk mapping */
 #ifndef OSI_PROBE_STANDALONE