Re: [PATCH v2 2/2] lockd: change the proc_handler for nsm_use_hostnames from int to u8

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Eric


On 12/12/16 3:32 PM, Eric W. Biederman wrote:
Added Olaf Kirch the originator of nsm_use_hostnames to the cc.

Jia He <hejianet@xxxxxxxxx> writes:

nsm_use_hostnames is a module paramter and it will be exported to sysctl
procfs. This is to let user sometimes change it from userspace. But the
minimal unit for sysctl procfs read/write it sizeof(int).
In big endian system, the converting from/to  bool to/from int will cause
error for proc items.

This patch use a new proc_handler proc_dou8vec.

Suggested-by: Pan Xinhui <xinhui@xxxxxxxxxxxxxxxxxx>
Signed-off-by: Jia He <hejianet@xxxxxxxxx>
---
  fs/lockd/svc.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index fc4084e..7a4ad9d 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -561,7 +561,7 @@ static struct ctl_table nlm_sysctls[] = {
  		.data		= &nsm_use_hostnames,
  		.maxlen		= sizeof(int),
  		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler	= proc_dou8vec,
proc_dou8vec does not exist in my tree so I don't know what it does,
but if it's name is accurate this change is wrong.  As the maxlen has
not changed so you are implying that it is a vector of u8 and
sizeof(int) long.
Please see my previous patch mail in the same thread.
The new proc handler looks like:
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -2112,6 +2112,30 @@ static int proc_put_char(void __user **buf, size_t *size, char c)
        return 0;
 }

+
+static int do_proc_dou8vec_conv(bool *negp, unsigned long *lvalp,
+                               int *valp,
+                               int write, void *data)
+{
+       if (write) {
+               if (*negp)
+                       *(u8 *)valp = -*lvalp;
+               else
+                       *(u8 *)valp = *lvalp;
+       } else {
+               int val = *(u8 *)valp;
+
+               if (val < 0) {
+                       *negp = true;
+                       *lvalp = -(unsigned long)val;
+               } else {
+                       *negp = false;
+                       *lvalp = (unsigned long)val;
+               }
+       }
+       return 0;
+}
+

[...]
+int proc_dou8vec(struct ctl_table *table, int write,
+               void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+       return do_proc_dointvec(table, write, buffer, lenp, ppos,
+                               do_proc_dou8vec_conv, NULL);
+}
+
I didn't change much logic in
do_proc_dou8vec_conv compared with do_proc_dointvec_cov.
Just let the variable int *valp be used as a (u8 *)

Further this is wrong if nsm_use_hostnames is a bool as this sysctl
can be assigned values that are out of bounds for a bool.
I thought even without this patch, the assignment is also _correct_.
The error is just the output of procfs and sysctl

Furthermore this is wrong in that a bool is not necessarily a u8, the
size of bool is very architecture dependent.  So for either
nsm_use_hostnames needs to become an int, a proc_dobool helper needs
to be added, or the sysctl needs to be removed entirely as module
parameters can be edited at runtime through sysfs.
Yes, ;) this is what I did in Patchv1: change nsm_use_hostnames from
bool to u32/int. But as suggested by Pan Xinhui, I thought Patchv3
is better.
e.g. you can insmod lockd.ko nsm_use_hostnames=y if nsm_use_hostnames
is still bool type


But I completely agree that this decade old bug needs to be fixed.
indeed
Eric


  	},
  	{
  		.procname	= "nsm_local_state",

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux