afs: fix kernel_write / kernel_read arguments 69/12769/3
authorMarcio Barbosa <mbarbosa@sinenomine.net>
Thu, 16 Nov 2017 22:24:03 +0000 (17:24 -0500)
committerBenjamin Kaduk <kaduk@mit.edu>
Tue, 28 Nov 2017 03:14:21 +0000 (22:14 -0500)
The order / content of the arguments passed to kernel_write and
kernel_read are not right. As a result, the kernel will panic if one of
the functions in question is called.

[kaduk@mit.edu: include configure check for multiple kernel_read()
variants, per linux commits bdd1d2d3d251c65b74ac4493e08db18971c09240
and e13ec939e96b13e664bb6cee361cc976a0ee621a]

FIXES 134440

Change-Id: I4753dee61f1b986bbe6a12b5568d1a8db30c65f8
Reviewed-on: https://gerrit.openafs.org/12769
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Tested-by: Marcio Brito Barbosa <mbarbosa@sinenomine.net>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>

acinclude.m4
src/afs/LINUX/osi_compat.h
src/cf/linux-test4.m4

index 703d3ea..8952776 100644 (file)
@@ -1195,6 +1195,7 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*)
                 LINUX_DOP_D_REVALIDATE_TAKES_UNSIGNED
                 LINUX_IOP_LOOKUP_TAKES_UNSIGNED
                 LINUX_D_INVALIDATE_IS_VOID
+                LINUX_KERNEL_READ_OFFSET_IS_LAST
 
                 dnl If we are guaranteed that keyrings will work - that is
                 dnl  a) The kernel has keyrings enabled
index 60cfdc1..62fce21 100644 (file)
@@ -659,7 +659,11 @@ afs_file_read(struct file *filp, char __user *buf, size_t len, loff_t *pos)
 #if defined(HAVE_LINUX___VFS_WRITE)
     return __vfs_read(filp, buf, len, pos);
 #elif defined(HAVE_LINUX_KERNEL_WRITE)
+# if defined(LINUX_KERNEL_READ_OFFSET_IS_LAST)
     return kernel_read(filp, buf, len, pos);
+# else
+    return kernel_read(filp, *pos, buf, len);
+# endif
 #else
     return filp->f_op->read(filp, buf, len, pos);
 #endif
@@ -671,7 +675,11 @@ afs_file_write(struct file *filp, char __user *buf, size_t len, loff_t *pos)
 #if defined(HAVE_LINUX___VFS_WRITE)
     return __vfs_write(filp, buf, len, pos);
 #elif defined(HAVE_LINUX_KERNEL_WRITE)
+# if defined(LINUX_KERNEL_READ_OFFSET_IS_LAST)
     return kernel_write(filp, buf, len, pos);
+# else
+    return kernel_write(filp, buf, len, *pos);
+# endif
 #else
     return filp->f_op->write(filp, buf, len, pos);
 #endif
index ed759e1..6746a10 100644 (file)
@@ -799,3 +799,15 @@ AC_DEFUN([LINUX_D_INVALIDATE_IS_VOID], [
                       [define if your d_invalidate returns void],
                       [])
 ])
+
+AC_DEFUN([LINUX_KERNEL_READ_OFFSET_IS_LAST], [
+  AC_CHECK_LINUX_BUILD([whether offset is the last argument to kernel_read],
+                       [ac_cv_linux_func_kernel_read_offset_is_last],
+                       [#include <linux/fs.h>],
+                       [
+                       ssize_t kernel_read(struct file *, void *, size_t, loff_t *);
+                       ],
+                       [KERNEL_READ_OFFSET_IS_LAST],
+                       [define if your kernel_read has offset as the last argument],
+                       [])
+])