linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Zev Weiss <zev@bewilderbeest.net>
To: Luis Chamberlain <mcgrof@kernel.org>, Kees Cook <keescook@chromium.org>
Cc: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org,
	Andrew Morton <akpm@linux-foundation.org>,
	yzaikin@google.com, brendanhiggins@google.com,
	Zev Weiss <zev@bewilderbeest.net>
Subject: [PATCH v2 3/3] kernel/sysctl.c: define minmax conv functions in terms of non-minmax versions
Date: Thu,  7 Feb 2019 06:34:26 -0600	[thread overview]
Message-ID: <20190207123426.9202-4-zev@bewilderbeest.net> (raw)
In-Reply-To: <20190207123426.9202-1-zev@bewilderbeest.net>

do_proc_do[u]intvec_minmax_conv() had included open-coded versions of
do_proc_do[u]intvec_conv(); the duplication led to buggy inconsistencies
(missing range checks).  To reduce the likelihood of such problems in
the future, we can instead refactor both to be defined in terms of their
non-bounded counterparts (plus the added check).

Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
---
 kernel/sysctl.c | 59 ++++++++++++++++++++++---------------------------
 1 file changed, 27 insertions(+), 32 deletions(-)

diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index a71c4b3935bc..4b6bce36737e 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -2562,32 +2562,26 @@ static int do_proc_dointvec_minmax_conv(bool *negp, unsigned long *lvalp,
 					int *valp,
 					int write, void *data)
 {
+	int tmp, ret;
 	struct do_proc_dointvec_minmax_conv_param *param = data;
+
+	/*
+	 * If writing, first do so via a temporary local int so we can
+	 * bounds-check it before touching *valp.
+	 */
+	int *ip = write ? &tmp : valp;
+
+	ret = do_proc_dointvec_conv(negp, lvalp, ip, write, data);
+	if (ret)
+		return ret;
+
 	if (write) {
-		int val;
-		if (*negp) {
-			if (*lvalp > (unsigned long) INT_MAX + 1)
-				return -EINVAL;
-			val = -*lvalp;
-		} else {
-			if (*lvalp > (unsigned long) INT_MAX)
-				return -EINVAL;
-			val = *lvalp;
-		}
-		if ((param->min && *param->min > val) ||
-		    (param->max && *param->max < val))
+		if ((param->min && *param->min > tmp) ||
+		    (param->max && *param->max < tmp))
 			return -EINVAL;
-		*valp = val;
-	} else {
-		int val = *valp;
-		if (val < 0) {
-			*negp = true;
-			*lvalp = -(unsigned long)val;
-		} else {
-			*negp = false;
-			*lvalp = (unsigned long)val;
-		}
+		*valp = tmp;
 	}
+
 	return 0;
 }
 
@@ -2636,22 +2630,23 @@ static int do_proc_douintvec_minmax_conv(unsigned long *lvalp,
 					 unsigned int *valp,
 					 int write, void *data)
 {
+	int ret;
+	unsigned int tmp;
 	struct do_proc_douintvec_minmax_conv_param *param = data;
 
-	if (write) {
-		unsigned int val = *lvalp;
+	/* write via temporary local uint for bounds-checking */
+	unsigned int *up = write ? &tmp : valp;
 
-		if (*lvalp > UINT_MAX)
-			return -EINVAL;
+	ret = do_proc_douintvec_conv(lvalp, up, write, data);
+	if (ret)
+		return ret;
 
-		if ((param->min && *param->min > val) ||
-		    (param->max && *param->max < val))
+	if (write) {
+		if ((param->min && *param->min > tmp) ||
+		    (param->max && *param->max < tmp))
 			return -ERANGE;
 
-		*valp = val;
-	} else {
-		unsigned int val = *valp;
-		*lvalp = (unsigned long) val;
+		*valp = tmp;
 	}
 
 	return 0;
-- 
2.20.1


  parent reply	other threads:[~2019-02-07 12:35 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-12-27 11:12 [PATCH 0/2] sysctl: fix range-checking in do_proc_dointvec_minmax_conv() Zev Weiss
2018-12-27 11:12 ` [PATCH 1/2] test_sysctl: add tests for >32-bit values written to 32-bit integers Zev Weiss
2018-12-27 11:12 ` [PATCH 2/2] kernel/sysctl.c: define minmax conv functions in terms of non-minmax versions Zev Weiss
2019-02-06 19:58   ` Luis Chamberlain
2019-02-07 12:34     ` [PATCH v2 0/3] sysctl: fix range-checking in do_proc_dointvec_minmax_conv() Zev Weiss
2019-02-07 12:34       ` [PATCH v2 1/3] test_sysctl: add tests for >32-bit values written to 32-bit integers Zev Weiss
2019-02-07 12:34       ` [PATCH v2 2/3] kernel/sysctl.c: add missing range check in do_proc_dointvec_minmax_conv Zev Weiss
2019-02-07 12:34       ` Zev Weiss [this message]
2019-02-07 15:51       ` [PATCH v2 0/3] sysctl: fix range-checking in do_proc_dointvec_minmax_conv() Luis Chamberlain
2019-02-07 16:54         ` Zev Weiss
2019-02-07 16:51       ` [PATCH v2 3/3] kernel/sysctl.c: define minmax conv functions in terms of non-minmax versions Zev Weiss
2019-02-05 16:23 ` [PATCH 0/2] sysctl: fix range-checking in do_proc_dointvec_minmax_conv() Zev Weiss

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190207123426.9202-4-zev@bewilderbeest.net \
    --to=zev@bewilderbeest.net \
    --cc=akpm@linux-foundation.org \
    --cc=brendanhiggins@google.com \
    --cc=keescook@chromium.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mcgrof@kernel.org \
    --cc=yzaikin@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).