+ sysctl-add-range-clamping-intvec-helper-functions.patch added to -mm tree

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

 



The patch titled
     Subject: sysctl: add range clamping intvec helper functions
has been added to the -mm tree.  Its filename is
     sysctl-add-range-clamping-intvec-helper-functions.patch

This patch should soon appear at
    http://ozlabs.org/~akpm/mmots/broken-out/sysctl-add-range-clamping-intvec-helper-functions.patch
and later at
    http://ozlabs.org/~akpm/mmotm/broken-out/sysctl-add-range-clamping-intvec-helper-functions.patch

Before you just go and hit "reply", please:
   a) Consider who else should be cc'ed
   b) Prefer to cc a suitable mailing list as well
   c) Ideally: find the original patch on the mailing list and do a
      reply-to-all to that, adding suitable additional cc's

*** Remember to use Documentation/SubmitChecklist when testing your code ***

The -mm tree is included into linux-next and is updated
there every 3-4 working days

------------------------------------------------------
From: Waiman Long <longman@xxxxxxxxxx>
Subject: sysctl: add range clamping intvec helper functions

Patch series "ipc: Clamp msgmni and shmmni to the real IPC_MNI limit".

The sysctl parameters msgmni and shmmni have an inherent limit of IPC_MNI
(32k).  However, users may not be aware of that because they can write a
value much higher than that without getting any error or notification. 
Reading the parameters back will show the newly written values which are
not real.

Enforcing the limit by failing sysctl parameter write, however, can break
existing user applications.  To address this dilemma, the following new
sysctl range clamping APIs are added:
  - proc_dointvec_clamp_minmax()
  - proc_douintvec_clamp_minmax()

This new set of APIs is then used to set the real limit for msgmni and
shmmni without breaking existing applications.  If any out of range value
is written to those sysctl parameters, the following warning will be
printed instead.

  Kernel parameter "shmmni" was set out of range [0, 32768], clamped to 32768.

Reading the values back will show 32768 instead of some fake values.


This patch (of 3):

The current intvec range helper functions will fail with error when users
try to assign an out-of-range value.

The following new non-failing range helper functions are now added:
 - proc_dointvec_clamp_minmax()
 - proc_douintvec_clamp_minmax()

The new helper functions will clamp the value to within the given
min/max range without failing it.

Link: http://lkml.kernel.org/r/1519059231-2456-2-git-send-email-longman@xxxxxxxxxx
Signed-off-by: Waiman Long <longman@xxxxxxxxxx>
Reviewed-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
Cc: Davidlohr Bueso <dave@xxxxxxxxxxxx>
Cc: Manfred Spraul <manfred@xxxxxxxxxxxxxxxx>
Cc: "Luis R. Rodriguez" <mcgrof@xxxxxxxxxx>
Cc: Kees Cook <keescook@xxxxxxxxxxxx>
Cc: Al Viro <viro@xxxxxxxxxxxxxxxxxx>
Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
---

 include/linux/sysctl.h |    6 ++
 kernel/sysctl.c        |   97 ++++++++++++++++++++++++++++++++++++---
 2 files changed, 96 insertions(+), 7 deletions(-)

diff -puN include/linux/sysctl.h~sysctl-add-range-clamping-intvec-helper-functions include/linux/sysctl.h
--- a/include/linux/sysctl.h~sysctl-add-range-clamping-intvec-helper-functions
+++ a/include/linux/sysctl.h
@@ -63,6 +63,12 @@ extern int proc_doulongvec_ms_jiffies_mi
 				      void __user *, size_t *, loff_t *);
 extern int proc_do_large_bitmap(struct ctl_table *, int,
 				void __user *, size_t *, loff_t *);
+extern int proc_dointvec_clamp_minmax(struct ctl_table *table, int write,
+				      void __user *buffer, size_t *lenp,
+				      loff_t *ppos);
+extern int proc_douintvec_clamp_minmax(struct ctl_table *table, int write,
+				       void __user *buffer, size_t *lenp,
+				       loff_t *ppos);
 
 /*
  * Register a set of sysctl names by calling register_sysctl_table
diff -puN kernel/sysctl.c~sysctl-add-range-clamping-intvec-helper-functions kernel/sysctl.c
--- a/kernel/sysctl.c~sysctl-add-range-clamping-intvec-helper-functions
+++ a/kernel/sysctl.c
@@ -2500,9 +2500,15 @@ static int proc_dointvec_minmax_sysadmin
 }
 #endif
 
+/*
+ * The clamping flag, if set, will clamp the input value to the range
+ * specified by the given min/max values instead of returning error when
+ * out of range.
+ */
 struct do_proc_dointvec_minmax_conv_param {
 	int *min;
 	int *max;
+	bool clamp;
 };
 
 static int do_proc_dointvec_minmax_conv(bool *negp, unsigned long *lvalp,
@@ -2512,9 +2518,18 @@ static int do_proc_dointvec_minmax_conv(
 	struct do_proc_dointvec_minmax_conv_param *param = data;
 	if (write) {
 		int val = *negp ? -*lvalp : *lvalp;
-		if ((param->min && *param->min > val) ||
-		    (param->max && *param->max < val))
-			return -EINVAL;
+		if (param->min && *param->min > val) {
+			if (param->clamp)
+				val = *param->min;
+			else
+				return -EINVAL;
+		}
+		if (param->max && *param->max < val) {
+			if (param->clamp)
+				val = *param->max;
+			else
+				return -EINVAL;
+		}
 		*valp = val;
 	} else {
 		int val = *valp;
@@ -2556,9 +2571,38 @@ int proc_dointvec_minmax(struct ctl_tabl
 				do_proc_dointvec_minmax_conv, &param);
 }
 
+/**
+ * proc_dointvec_clamp_minmax - read a vector of integers with min/max values
+ * @table: the sysctl table
+ * @write: %TRUE if this is a write to the sysctl file
+ * @buffer: the user buffer
+ * @lenp: the size of the user buffer
+ * @ppos: file position
+ *
+ * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
+ * values from/to the user buffer, treated as an ASCII string.
+ *
+ * This routine will clamp the values to within the range specified by
+ * table->extra1 (min) and table->extra2 (max).
+ *
+ * Returns 0 on success.
+ */
+int proc_dointvec_clamp_minmax(struct ctl_table *table, int write,
+		  void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+	struct do_proc_dointvec_minmax_conv_param param = {
+		.min = (int *) table->extra1,
+		.max = (int *) table->extra2,
+		.clamp = true,
+	};
+	return do_proc_dointvec(table, write, buffer, lenp, ppos,
+				do_proc_dointvec_minmax_conv, &param);
+}
+
 struct do_proc_douintvec_minmax_conv_param {
 	unsigned int *min;
 	unsigned int *max;
+	bool clamp;
 };
 
 static int do_proc_douintvec_minmax_conv(unsigned long *lvalp,
@@ -2573,10 +2617,18 @@ static int do_proc_douintvec_minmax_conv
 		if (*lvalp > UINT_MAX)
 			return -EINVAL;
 
-		if ((param->min && *param->min > val) ||
-		    (param->max && *param->max < val))
-			return -ERANGE;
-
+		if (param->min && *param->min > val) {
+			if (param->clamp)
+				val = *param->min;
+			else
+				return -ERANGE;
+		}
+		if (param->max && *param->max < val) {
+			if (param->clamp)
+				val = *param->max;
+			else
+				return -ERANGE;
+		}
 		*valp = val;
 	} else {
 		unsigned int val = *valp;
@@ -2614,6 +2666,37 @@ int proc_douintvec_minmax(struct ctl_tab
 	};
 	return do_proc_douintvec(table, write, buffer, lenp, ppos,
 				 do_proc_douintvec_minmax_conv, &param);
+}
+
+/**
+ * proc_douintvec_clamp_minmax - read a vector of uints with min/max values
+ * @table: the sysctl table
+ * @write: %TRUE if this is a write to the sysctl file
+ * @buffer: the user buffer
+ * @lenp: the size of the user buffer
+ * @ppos: file position
+ *
+ * Reads/writes up to table->maxlen/sizeof(unsigned int) unsigned integer
+ * values from/to the user buffer, treated as an ASCII string. Negative
+ * strings are not allowed.
+ *
+ * This routine will clamp the values to within the range specified by
+ * table->extra1 (min) and table->extra2 (max). There is a final sanity
+ * check for UINT_MAX to avoid having to support wrap around uses from
+ * userspace.
+ *
+ * Returns 0 on success.
+ */
+int proc_douintvec_clamp_minmax(struct ctl_table *table, int write,
+			  void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+	struct do_proc_douintvec_minmax_conv_param param = {
+		.min = (unsigned int *) table->extra1,
+		.max = (unsigned int *) table->extra2,
+		.clamp = true,
+	};
+	return do_proc_douintvec(table, write, buffer, lenp, ppos,
+				 do_proc_douintvec_minmax_conv, &param);
 }
 
 static int do_proc_dopipe_max_size_conv(unsigned long *lvalp,
_

Patches currently in -mm which might be from longman@xxxxxxxxxx are

list_lru-prefetch-neighboring-list-entries-before-acquiring-lock.patch
sysctl-add-range-clamping-intvec-helper-functions.patch
sysctl-warn-when-a-clamped-sysctl-parameter-is-set-out-of-range.patch
ipc-clamp-msgmni-and-shmmni-to-the-real-ipc_mni-limit.patch

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



[Index of Archives]     [Kernel Archive]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]

  Powered by Linux