From nobody Sat Feb 7 23:39:41 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 57845306480; Mon, 13 Oct 2025 13:25:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760361946; cv=none; b=QPOR/mAzDQeOwXazf+RdjZmxBfatklff2KwrVaFj8EZPrNW/9q3eE//epKxLy7MmTC7GkUpXMS/MlxlWpI3lzs5+PJ9LisrytDycsQioCRbwCXrsLl5bj0Yea04PrOqF2ufhXDFwB2nb6JLovw4qyEUtCy4pyHhZpiwLLnyWW4s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760361946; c=relaxed/simple; bh=xhYBn//i7aNfh3cHC6GieFmJFdKrx9dZXxNHLeNVBSo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=A+/dWWICdvsQ0TWso/v9iP7xiQyFzVtzpK9jCIE8y+E7LQVXRmsfry6RceFOrORL40F3r+lIBUHqhVHeFJUUiS6RHiBdvRCrU3sGPH3TuG2rxBYOjRIUuLYPgZoSAm5xNRt57r2M7DhBAjMC/sVUWq94Nj+QJb2G14qp1W7shdk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ST27FM3k; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ST27FM3k" Received: by smtp.kernel.org (Postfix) with ESMTPS id F3DDDC113D0; Mon, 13 Oct 2025 13:25:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760361946; bh=xhYBn//i7aNfh3cHC6GieFmJFdKrx9dZXxNHLeNVBSo=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=ST27FM3kboA1RoV9HVkd7bXi8AiaLhmtBON90ecc6qJbfMVELy0uYWEviVfihZKTR 7/plpqoDkCkdWbcsC8S7CEVTXF+LA5npQOz7laSezL+U05lSPcYw4o+2Jm+4fLjQE0 1lj3N2atKlMJC74S06DMgKiAMwp2BsAFXljRiN7KXEUbd4hxNNe2j305nMdCiU5928 c3NFoUJkHiCEmOC9JPoSwLsvzDdzIsWZ719Hhs9qujH/1tjx3M+hIj2YZeAyjCJPph UuzCxv+aNB1a/vKkkA+0Y9k5KW++O8sy5cXiOpJ41AhWo2YA7BgZ9r9e3J1Bi543aM 355efvqm0TtRA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id E3217CCD18D; Mon, 13 Oct 2025 13:25:45 +0000 (UTC) From: Joel Granados Date: Mon, 13 Oct 2025 15:24:51 +0200 Subject: [PATCH 1/8] sysctl: Replace void pointer with const pointer to ctl_table Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251013-jag-sysctl_conv-v1-1-4dc35ceae733@kernel.org> References: <20251013-jag-sysctl_conv-v1-0-4dc35ceae733@kernel.org> In-Reply-To: <20251013-jag-sysctl_conv-v1-0-4dc35ceae733@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Kees Cook Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, Joel Granados X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=16261; i=joel.granados@kernel.org; h=from:subject:message-id; bh=xhYBn//i7aNfh3cHC6GieFmJFdKrx9dZXxNHLeNVBSo=; b=owJ4nAHtARL+kA0DAAoBupfNUreWQU8ByyZiAGjs/dK76L/nGLIy58kIRfmDzQncHxGJlcTMT IynTSbFuwI5z4kBswQAAQoAHRYhBK5HCVcl5jElzssnkLqXzVK3lkFPBQJo7P3SAAoJELqXzVK3 lkFP9jAL/304c9CshnZuxNNrdRW46bPpDlACJI2nVjW15ouM5X/SqRAXHjM7O2elh3bqr7Ns9uO G0OoJqZMCum5OoJ4ahuBNZyqxNc/A+p8q1mGQENk5ObcvlFnwrCNhtjJG2t5BTV6uyR52QFLnOu z+lndzZSdp95+9oiz81wTZqgMUkix0NYhyYgjv+lG5k9pWGAoFLO/UqLRCecg4A1SGWeTn7Qtnh vMRguoaUNxQmimVxhgmTlm/N1BbyOuHZKcM8VliTfXC0dtUBH49Q/DBx3wTVZuuJeeyQUtfIJ8d +hkdSX9OGBFZniepzoahG369Pfv6IT1u+q57X0zTQ8bRqSavlAKjqekW9he1/mr9YqJ5nBGyipk t5OH2nXP/l0K76A+w+i6CkS4G3vmVjq1iFqhF+7DVlzFTdmM9JGd5KMxdcz7pXDPEzhhJd4beNm GKurEJo6qEazJOe2JRjgkUlIIyPRp939jOfL0WTJOrS3yFsHbcwjIPXTIcxWj43+lYmuszHfzU7 eM= X-Developer-Key: i=joel.granados@kernel.org; a=openpgp; fpr=F1F8E46D30F0F6C4A45FF4465895FAAC338C6E77 X-Endpoint-Received: by B4 Relay for joel.granados@kernel.org/default with auth_id=239 * Replace void* data in the converter functions with a const struct ctl_table* table as it was only getting forwarding values from ctl_table->extra{1,2}. * Remove the void* data in the do_proc_* functions as they already had a pointer to the ctl_table. * Remove min/max structures do_proc_do{uint,int}vec_minmax_conv_param; the min/max values get passed directly in ctl_table. * Keep min/max initialization in extra{1,2} in proc_dou8vec_minmax. * The do_proc_douintvec was adjusted outside sysctl.c as it is exported to fs/pipe.c. Signed-off-by: Joel Granados --- fs/pipe.c | 6 +- include/linux/sysctl.h | 5 +- kernel/sysctl.c | 180 ++++++++++++++++++---------------------------= ---- 3 files changed, 71 insertions(+), 120 deletions(-) diff --git a/fs/pipe.c b/fs/pipe.c index 731622d0738d41a9d918dc5048e95e38b3b0e049..2431f05cb788f5bd89660f0fc6f= 4c4696e17d5dd 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -1480,8 +1480,8 @@ static struct file_system_type pipe_fs_type =3D { =20 #ifdef CONFIG_SYSCTL static int do_proc_dopipe_max_size_conv(unsigned long *lvalp, - unsigned int *valp, - int write, void *data) + unsigned int *valp, int write, + const struct ctl_table *table) { if (write) { unsigned int val; @@ -1503,7 +1503,7 @@ static int proc_dopipe_max_size(const struct ctl_tabl= e *table, int write, void *buffer, size_t *lenp, loff_t *ppos) { return do_proc_douintvec(table, write, buffer, lenp, ppos, - do_proc_dopipe_max_size_conv, NULL); + do_proc_dopipe_max_size_conv); } =20 static const struct ctl_table fs_pipe_sysctls[] =3D { diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 92e9146b1104123d3dc0ff004bd681861e297581..2d3d6c141b0b0aee21f2708450b= 7b41d8041a8cb 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -238,9 +238,8 @@ bool sysctl_is_alias(char *param); int do_proc_douintvec(const struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos, int (*conv)(unsigned long *lvalp, - unsigned int *valp, - int write, void *data), - void *data); + unsigned int *valp, int write, + const struct ctl_table *table)); =20 extern int unaligned_enabled; extern int no_unaligned_warning; diff --git a/kernel/sysctl.c b/kernel/sysctl.c index cb6196e3fa993daa21704d190baf366084e014f7..f0a691ffb29067a019a857a62fa= 56185aab06c61 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -355,8 +355,8 @@ static void proc_put_char(void **buf, size_t *size, cha= r c) } =20 static int do_proc_dointvec_conv(bool *negp, unsigned long *lvalp, - int *valp, - int write, void *data) + int *valp, int write, + const struct ctl_table *table) { if (write) { if (*negp) { @@ -382,8 +382,8 @@ static int do_proc_dointvec_conv(bool *negp, unsigned l= ong *lvalp, } =20 static int do_proc_douintvec_conv(unsigned long *lvalp, - unsigned int *valp, - int write, void *data) + unsigned int *valp, int write, + const struct ctl_table *table) { if (write) { if (*lvalp > UINT_MAX) @@ -402,8 +402,7 @@ static int __do_proc_dointvec(void *tbl_data, const str= uct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos, int (*conv)(bool *negp, unsigned long *lvalp, int *valp, - int write, void *data), - void *data) + int write, const struct ctl_table *table)) { int *i, vleft, first =3D 1, err =3D 0; size_t left; @@ -444,12 +443,12 @@ static int __do_proc_dointvec(void *tbl_data, const s= truct ctl_table *table, sizeof(proc_wspace_sep), NULL); if (err) break; - if (conv(&neg, &lval, i, 1, data)) { + if (conv(&neg, &lval, i, 1, table)) { err =3D -EINVAL; break; } } else { - if (conv(&neg, &lval, i, 0, data)) { + if (conv(&neg, &lval, i, 0, table)) { err =3D -EINVAL; break; } @@ -474,11 +473,10 @@ static int __do_proc_dointvec(void *tbl_data, const s= truct ctl_table *table, static int do_proc_dointvec(const struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos, int (*conv)(bool *negp, unsigned long *lvalp, int *valp, - int write, void *data), - void *data) + int write, const struct ctl_table *table)) { return __do_proc_dointvec(table->data, table, write, - buffer, lenp, ppos, conv, data); + buffer, lenp, ppos, conv); } =20 static int do_proc_douintvec_w(unsigned int *tbl_data, @@ -486,9 +484,8 @@ static int do_proc_douintvec_w(unsigned int *tbl_data, void *buffer, size_t *lenp, loff_t *ppos, int (*conv)(unsigned long *lvalp, - unsigned int *valp, - int write, void *data), - void *data) + unsigned int *valp, int write, + const struct ctl_table *table)) { unsigned long lval; int err =3D 0; @@ -518,7 +515,7 @@ static int do_proc_douintvec_w(unsigned int *tbl_data, goto out_free; } =20 - if (conv(&lval, tbl_data, 1, data)) { + if (conv(&lval, tbl_data, 1, table)) { err =3D -EINVAL; goto out_free; } @@ -538,12 +535,12 @@ static int do_proc_douintvec_w(unsigned int *tbl_data, return err; } =20 -static int do_proc_douintvec_r(unsigned int *tbl_data, void *buffer, +static int do_proc_douintvec_r(unsigned int *tbl_data, + const struct ctl_table *table, void *buffer, size_t *lenp, loff_t *ppos, int (*conv)(unsigned long *lvalp, - unsigned int *valp, - int write, void *data), - void *data) + unsigned int *valp, int write, + const struct ctl_table *table)) { unsigned long lval; int err =3D 0; @@ -551,7 +548,7 @@ static int do_proc_douintvec_r(unsigned int *tbl_data, = void *buffer, =20 left =3D *lenp; =20 - if (conv(&lval, tbl_data, 0, data)) { + if (conv(&lval, tbl_data, 0, table)) { err =3D -EINVAL; goto out; } @@ -573,9 +570,8 @@ static int __do_proc_douintvec(void *tbl_data, const st= ruct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos, int (*conv)(unsigned long *lvalp, - unsigned int *valp, - int write, void *data), - void *data) + unsigned int *valp, int write, + const struct ctl_table *table)) { unsigned int *i, vleft; =20 @@ -601,19 +597,18 @@ static int __do_proc_douintvec(void *tbl_data, const = struct ctl_table *table, =20 if (write) return do_proc_douintvec_w(i, table, buffer, lenp, ppos, - conv, data); - return do_proc_douintvec_r(i, buffer, lenp, ppos, conv, data); + conv); + return do_proc_douintvec_r(i, table, buffer, lenp, ppos, conv); } =20 int do_proc_douintvec(const struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos, int (*conv)(unsigned long *lvalp, - unsigned int *valp, - int write, void *data), - void *data) + unsigned int *valp, int write, + const struct ctl_table *table)) { - return __do_proc_douintvec(table->data, table, write, - buffer, lenp, ppos, conv, data); + return __do_proc_douintvec(table->data, table, write, buffer, lenp, + ppos, conv); } =20 /** @@ -672,7 +667,7 @@ int proc_dobool(const struct ctl_table *table, int writ= e, void *buffer, int proc_dointvec(const struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos) { - return do_proc_dointvec(table, write, buffer, lenp, ppos, NULL, NULL); + return do_proc_dointvec(table, write, buffer, lenp, ppos, NULL); } =20 /** @@ -692,42 +687,28 @@ int proc_douintvec(const struct ctl_table *table, int= write, void *buffer, size_t *lenp, loff_t *ppos) { return do_proc_douintvec(table, write, buffer, lenp, ppos, - do_proc_douintvec_conv, NULL); + do_proc_douintvec_conv); } =20 -/** - * struct do_proc_dointvec_minmax_conv_param - proc_dointvec_minmax() rang= e checking structure - * @min: pointer to minimum allowable value - * @max: pointer to maximum allowable value - * - * The do_proc_dointvec_minmax_conv_param structure provides the - * minimum and maximum values for doing range checking for those sysctl - * parameters that use the proc_dointvec_minmax() handler. - */ -struct do_proc_dointvec_minmax_conv_param { - int *min; - int *max; -}; - static int do_proc_dointvec_minmax_conv(bool *negp, unsigned long *lvalp, - int *valp, - int write, void *data) + int *valp, int write, + const struct ctl_table *table) { - int tmp, ret; - struct do_proc_dointvec_minmax_conv_param *param =3D data; + int tmp, ret, *min, *max; /* * If writing, first do so via a temporary local int so we can * bounds-check it before touching *valp. */ int *ip =3D write ? &tmp : valp; =20 - ret =3D do_proc_dointvec_conv(negp, lvalp, ip, write, data); + ret =3D do_proc_dointvec_conv(negp, lvalp, ip, write, table); if (ret) return ret; =20 if (write) { - if ((param->min && *param->min > tmp) || - (param->max && *param->max < tmp)) + min =3D (int *) table->extra1; + max =3D (int *) table->extra2; + if ((min && *min > tmp) || (max && *max < tmp)) return -EINVAL; WRITE_ONCE(*valp, tmp); } @@ -754,45 +735,27 @@ static int do_proc_dointvec_minmax_conv(bool *negp, u= nsigned long *lvalp, int proc_dointvec_minmax(const struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos) { - struct do_proc_dointvec_minmax_conv_param param =3D { - .min =3D (int *) table->extra1, - .max =3D (int *) table->extra2, - }; return do_proc_dointvec(table, write, buffer, lenp, ppos, - do_proc_dointvec_minmax_conv, ¶m); + do_proc_dointvec_minmax_conv); } =20 -/** - * struct do_proc_douintvec_minmax_conv_param - proc_douintvec_minmax() ra= nge checking structure - * @min: pointer to minimum allowable value - * @max: pointer to maximum allowable value - * - * The do_proc_douintvec_minmax_conv_param structure provides the - * minimum and maximum values for doing range checking for those sysctl - * parameters that use the proc_douintvec_minmax() handler. - */ -struct do_proc_douintvec_minmax_conv_param { - unsigned int *min; - unsigned int *max; -}; - static int do_proc_douintvec_minmax_conv(unsigned long *lvalp, - unsigned int *valp, - int write, void *data) + unsigned int *valp, int write, + const struct ctl_table *table) { int ret; - unsigned int tmp; - struct do_proc_douintvec_minmax_conv_param *param =3D data; + unsigned int tmp, *min, *max; /* write via temporary local uint for bounds-checking */ unsigned int *up =3D write ? &tmp : valp; =20 - ret =3D do_proc_douintvec_conv(lvalp, up, write, data); + ret =3D do_proc_douintvec_conv(lvalp, up, write, table); if (ret) return ret; =20 if (write) { - if ((param->min && *param->min > tmp) || - (param->max && *param->max < tmp)) + min =3D (unsigned int *) table->extra1; + max =3D (unsigned int *) table->extra2; + if ((min && *min > tmp) || (max && *max < tmp)) return -ERANGE; =20 WRITE_ONCE(*valp, tmp); @@ -823,12 +786,8 @@ static int do_proc_douintvec_minmax_conv(unsigned long= *lvalp, int proc_douintvec_minmax(const struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos) { - struct do_proc_douintvec_minmax_conv_param param =3D { - .min =3D (unsigned int *) table->extra1, - .max =3D (unsigned int *) table->extra2, - }; return do_proc_douintvec(table, write, buffer, lenp, ppos, - do_proc_douintvec_minmax_conv, ¶m); + do_proc_douintvec_minmax_conv); } =20 /** @@ -854,28 +813,24 @@ int proc_dou8vec_minmax(const struct ctl_table *table= , int write, struct ctl_table tmp; unsigned int min =3D 0, max =3D 255U, val; u8 *data =3D table->data; - struct do_proc_douintvec_minmax_conv_param param =3D { - .min =3D &min, - .max =3D &max, - }; int res; =20 /* Do not support arrays yet. */ if (table->maxlen !=3D sizeof(u8)) return -EINVAL; =20 - if (table->extra1) - min =3D *(unsigned int *) table->extra1; - if (table->extra2) - max =3D *(unsigned int *) table->extra2; - tmp =3D *table; =20 tmp.maxlen =3D sizeof(val); tmp.data =3D &val; + if (!tmp.extra1) + tmp.extra1 =3D (unsigned int *) &min; + if (!tmp.extra2) + tmp.extra2 =3D (unsigned int *) &max; + val =3D READ_ONCE(*data); res =3D do_proc_douintvec(&tmp, write, buffer, lenp, ppos, - do_proc_douintvec_minmax_conv, ¶m); + do_proc_douintvec_minmax_conv); if (res) return res; if (write) @@ -1014,8 +969,8 @@ int proc_doulongvec_ms_jiffies_minmax(const struct ctl= _table *table, int write, =20 =20 static int do_proc_dointvec_jiffies_conv(bool *negp, unsigned long *lvalp, - int *valp, - int write, void *data) + int *valp, int write, + const struct ctl_table *table) { if (write) { if (*lvalp > INT_MAX / HZ) @@ -1040,8 +995,8 @@ static int do_proc_dointvec_jiffies_conv(bool *negp, u= nsigned long *lvalp, } =20 static int do_proc_dointvec_userhz_jiffies_conv(bool *negp, unsigned long = *lvalp, - int *valp, - int write, void *data) + int *valp, int write, + const struct ctl_table *table) { if (write) { if (USER_HZ < HZ && *lvalp > (LONG_MAX / HZ) * USER_HZ) @@ -1063,8 +1018,8 @@ static int do_proc_dointvec_userhz_jiffies_conv(bool = *negp, unsigned long *lvalp } =20 static int do_proc_dointvec_ms_jiffies_conv(bool *negp, unsigned long *lva= lp, - int *valp, - int write, void *data) + int *valp, int write, + const struct ctl_table *table) { if (write) { unsigned long jif =3D msecs_to_jiffies(*negp ? -*lvalp : *lvalp); @@ -1088,23 +1043,24 @@ static int do_proc_dointvec_ms_jiffies_conv(bool *n= egp, unsigned long *lvalp, } =20 static int do_proc_dointvec_ms_jiffies_minmax_conv(bool *negp, unsigned lo= ng *lvalp, - int *valp, int write, void *data) + int *valp, int write, + const struct ctl_table *table) { - int tmp, ret; - struct do_proc_dointvec_minmax_conv_param *param =3D data; + int tmp, ret, *min, *max; /* * If writing, first do so via a temporary local int so we can * bounds-check it before touching *valp. */ int *ip =3D write ? &tmp : valp; =20 - ret =3D do_proc_dointvec_ms_jiffies_conv(negp, lvalp, ip, write, data); + ret =3D do_proc_dointvec_ms_jiffies_conv(negp, lvalp, ip, write, table); if (ret) return ret; =20 if (write) { - if ((param->min && *param->min > tmp) || - (param->max && *param->max < tmp)) + min =3D (int *) table->extra1; + max =3D (int *) table->extra2; + if ((min && *min > tmp) || (max && *max < tmp)) return -EINVAL; *valp =3D tmp; } @@ -1130,18 +1086,14 @@ int proc_dointvec_jiffies(const struct ctl_table *t= able, int write, void *buffer, size_t *lenp, loff_t *ppos) { return do_proc_dointvec(table,write,buffer,lenp,ppos, - do_proc_dointvec_jiffies_conv,NULL); + do_proc_dointvec_jiffies_conv); } =20 int proc_dointvec_ms_jiffies_minmax(const struct ctl_table *table, int wri= te, void *buffer, size_t *lenp, loff_t *ppos) { - struct do_proc_dointvec_minmax_conv_param param =3D { - .min =3D (int *) table->extra1, - .max =3D (int *) table->extra2, - }; return do_proc_dointvec(table, write, buffer, lenp, ppos, - do_proc_dointvec_ms_jiffies_minmax_conv, ¶m); + do_proc_dointvec_ms_jiffies_minmax_conv); } =20 /** @@ -1163,7 +1115,7 @@ int proc_dointvec_userhz_jiffies(const struct ctl_tab= le *table, int write, void *buffer, size_t *lenp, loff_t *ppos) { return do_proc_dointvec(table, write, buffer, lenp, ppos, - do_proc_dointvec_userhz_jiffies_conv, NULL); + do_proc_dointvec_userhz_jiffies_conv); } =20 /** @@ -1185,7 +1137,7 @@ int proc_dointvec_ms_jiffies(const struct ctl_table *= table, int write, void *buf size_t *lenp, loff_t *ppos) { return do_proc_dointvec(table, write, buffer, lenp, ppos, - do_proc_dointvec_ms_jiffies_conv, NULL); + do_proc_dointvec_ms_jiffies_conv); } =20 /** --=20 2.50.1 From nobody Sat Feb 7 23:39:41 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 578C83064A7; Mon, 13 Oct 2025 13:25:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760361946; cv=none; b=PMFd5tgbXtieXJhvwCtGmnDhSbtBA7wZ0dCcMDfh/8WngtEpVBpnStB3IW0ZXJPj7bIvvco5gYEKaykhSIRx5EY869dw3wsEjAP0wcUruUHLrlPwGfJVyn7s48Sa1zDgijyPJg90BTpcnLY6bCUlWxXl3XnNAj2U4ZTM53g51v4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760361946; c=relaxed/simple; bh=Yb7SCKMM9yyjHxvSmVCws0zzI54RVCOIkVV6fK8yIW8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=CovfcPUNkrbhiYW+sf2defhSvaMYhIG8QMaWlscPzljvj98KO4o+LOYp8aUC1LLgCHHDfAYcrUleImCg6bxQkA9Ol8zUXlHHEw9UTxEMpMBAbPHqS5MZCkJ96t37FjjziX0RoQfqlFjForQ6H2M0YSmj6DN2qBrrSGdhmOwtXdo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=kw5RkbAQ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="kw5RkbAQ" Received: by smtp.kernel.org (Postfix) with ESMTPS id 10798C116C6; Mon, 13 Oct 2025 13:25:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760361946; bh=Yb7SCKMM9yyjHxvSmVCws0zzI54RVCOIkVV6fK8yIW8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=kw5RkbAQ4Gfef2PXPI6ko3ypYWUvz9u7gn7Ukp/O/1wqgVc0Fnm/8fuZHIWI31hTP mHV9l04/zghdbfmqWdohgB0K3ECSNnlT+Kgmt2ePXGAJVfRKVzKRYpwK3bLuD5z6Bk Ilkz5WZV2jcxvy/LS/lp4GWyzF8R8ElWfRdL/he209qpiNMagytO70B56I2DZ+m4/z N/tg1dGeRBm6UtWXbxjytX1zliZmtne223jOvz4/9R9EY96aVJF736t232YllkLyYM ypz8HrTViH+TRWx4OXbH5CLf0yJAznCzc2xRxGGmtHIN3HNr/yyxZpKirrQ9ntwhW5 S/SxDog8/jAFw== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id F206CCCD183; Mon, 13 Oct 2025 13:25:45 +0000 (UTC) From: Joel Granados Date: Mon, 13 Oct 2025 15:24:52 +0200 Subject: [PATCH 2/8] sysctl: Remove superfluous tbl_data param from "dovec" functions Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251013-jag-sysctl_conv-v1-2-4dc35ceae733@kernel.org> References: <20251013-jag-sysctl_conv-v1-0-4dc35ceae733@kernel.org> In-Reply-To: <20251013-jag-sysctl_conv-v1-0-4dc35ceae733@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Kees Cook Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, Joel Granados X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=6367; i=joel.granados@kernel.org; h=from:subject:message-id; bh=Yb7SCKMM9yyjHxvSmVCws0zzI54RVCOIkVV6fK8yIW8=; b=owJ4nAHtARL+kA0DAAoBupfNUreWQU8ByyZiAGjs/dPkczHhpnasOkJdj1xEHRrDVUE7lRQrG FGPm0A+4HVSO4kBswQAAQoAHRYhBK5HCVcl5jElzssnkLqXzVK3lkFPBQJo7P3TAAoJELqXzVK3 lkFPYBsL/RPScYsGMJU32qtKU5mXjKnko3sBib7y+rJ5pvSQ3UvnTtofkDDmLV1xPcmjup+7JlT WIPxFud+QRPxVVTZub2zLxuE+7c7EHRoDH+Y4GG/9L7oGhyiOsrRmuB7XcMQAyjf7kWQtXtlk+v 9D8WJk+FsTk5RI62ntH5Vb8lsdblCoHv6KTGXKSOVBt5fHkh0RK9mwNKD01MuvcSpgZsZkNR3tZ new29VWrD4WsGtwQBVMABHXkHrFLHEvDt62GpyAO8i0M4EOQyFJJmuH2YAv2WGZ1X+vtqXteLsr 42Yb06+AnrXhILQARfZKsTs2U4/AhVMnNhVzXu1UItnChvaTVlm3Mc5mWX3iQdPoif7GbSU1Z88 2PAZ7wTpNnKx3K0uPlF4XuK+HJhCZxTw+wYT2SgkXwxGR0I6YKAskWDGsLS5itlcLMyH0D4hEGV rT/hPgr2wsQWASRZ5/NbR+A96oYFKvknqv7SC/mnMLdpUaEGvKV0FyfBuGCMIby+zaeKOSSh6R4 +U= X-Developer-Key: i=joel.granados@kernel.org; a=openpgp; fpr=F1F8E46D30F0F6C4A45FF4465895FAAC338C6E77 X-Endpoint-Received: by B4 Relay for joel.granados@kernel.org/default with auth_id=239 Remove superfluous tbl_data param from do_proc_douintvec{,_r,_w} and __do_proc_do{intvec,uintvec,ulongvec_minmax}. There is no need to pass it as it is always contained within the ctl_table struct. Signed-off-by: Joel Granados --- kernel/sysctl.c | 61 ++++++++++++++++++++++++-----------------------------= ---- 1 file changed, 26 insertions(+), 35 deletions(-) diff --git a/kernel/sysctl.c b/kernel/sysctl.c index f0a691ffb29067a019a857a62fa56185aab06c61..0e249a1f99fec084db649782f5e= f8b37e40c6a7c 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -398,22 +398,22 @@ static int do_proc_douintvec_conv(unsigned long *lval= p, =20 static const char proc_wspace_sep[] =3D { ' ', '\t', '\n' }; =20 -static int __do_proc_dointvec(void *tbl_data, const struct ctl_table *tabl= e, - int write, void *buffer, - size_t *lenp, loff_t *ppos, - int (*conv)(bool *negp, unsigned long *lvalp, int *valp, - int write, const struct ctl_table *table)) +static int __do_proc_dointvec(const struct ctl_table *table, int write, + void *buffer, size_t *lenp, loff_t *ppos, + int (*conv)(bool *negp, unsigned long *lvalp, + int *valp, int write, + const struct ctl_table *table)) { int *i, vleft, first =3D 1, err =3D 0; size_t left; char *p; =20 - if (!tbl_data || !table->maxlen || !*lenp || (*ppos && !write)) { + if (!table->data || !table->maxlen || !*lenp || (*ppos && !write)) { *lenp =3D 0; return 0; } =20 - i =3D (int *) tbl_data; + i =3D (int *) table->data; vleft =3D table->maxlen / sizeof(*i); left =3D *lenp; =20 @@ -475,13 +475,10 @@ static int do_proc_dointvec(const struct ctl_table *t= able, int write, int (*conv)(bool *negp, unsigned long *lvalp, int *valp, int write, const struct ctl_table *table)) { - return __do_proc_dointvec(table->data, table, write, - buffer, lenp, ppos, conv); + return __do_proc_dointvec(table, write, buffer, lenp, ppos, conv); } =20 -static int do_proc_douintvec_w(unsigned int *tbl_data, - const struct ctl_table *table, - void *buffer, +static int do_proc_douintvec_w(const struct ctl_table *table, void *buffer, size_t *lenp, loff_t *ppos, int (*conv)(unsigned long *lvalp, unsigned int *valp, int write, @@ -515,7 +512,7 @@ static int do_proc_douintvec_w(unsigned int *tbl_data, goto out_free; } =20 - if (conv(&lval, tbl_data, 1, table)) { + if (conv(&lval, (unsigned int *) table->data, 1, table)) { err =3D -EINVAL; goto out_free; } @@ -535,8 +532,7 @@ static int do_proc_douintvec_w(unsigned int *tbl_data, return err; } =20 -static int do_proc_douintvec_r(unsigned int *tbl_data, - const struct ctl_table *table, void *buffer, +static int do_proc_douintvec_r(const struct ctl_table *table, void *buffer, size_t *lenp, loff_t *ppos, int (*conv)(unsigned long *lvalp, unsigned int *valp, int write, @@ -548,7 +544,7 @@ static int do_proc_douintvec_r(unsigned int *tbl_data, =20 left =3D *lenp; =20 - if (conv(&lval, tbl_data, 0, table)) { + if (conv(&lval, (unsigned int *) table->data, 0, table)) { err =3D -EINVAL; goto out; } @@ -566,22 +562,20 @@ static int do_proc_douintvec_r(unsigned int *tbl_data, return err; } =20 -static int __do_proc_douintvec(void *tbl_data, const struct ctl_table *tab= le, - int write, void *buffer, - size_t *lenp, loff_t *ppos, +static int __do_proc_douintvec(const struct ctl_table *table, int write, + void *buffer, size_t *lenp, loff_t *ppos, int (*conv)(unsigned long *lvalp, unsigned int *valp, int write, const struct ctl_table *table)) { - unsigned int *i, vleft; + unsigned int vleft; =20 - if (!tbl_data || !table->maxlen || !*lenp || (*ppos && !write)) { + if (!table->data || !table->maxlen || !*lenp || (*ppos && !write)) { *lenp =3D 0; return 0; } =20 - i =3D (unsigned int *) tbl_data; - vleft =3D table->maxlen / sizeof(*i); + vleft =3D table->maxlen / sizeof(unsigned int); =20 /* * Arrays are not supported, keep this simple. *Do not* add @@ -596,9 +590,8 @@ static int __do_proc_douintvec(void *tbl_data, const st= ruct ctl_table *table, conv =3D do_proc_douintvec_conv; =20 if (write) - return do_proc_douintvec_w(i, table, buffer, lenp, ppos, - conv); - return do_proc_douintvec_r(i, table, buffer, lenp, ppos, conv); + return do_proc_douintvec_w(table, buffer, lenp, ppos, conv); + return do_proc_douintvec_r(table, buffer, lenp, ppos, conv); } =20 int do_proc_douintvec(const struct ctl_table *table, int write, @@ -607,8 +600,7 @@ int do_proc_douintvec(const struct ctl_table *table, in= t write, unsigned int *valp, int write, const struct ctl_table *table)) { - return __do_proc_douintvec(table->data, table, write, buffer, lenp, - ppos, conv); + return __do_proc_douintvec(table, write, buffer, lenp, ppos, conv); } =20 /** @@ -839,9 +831,8 @@ int proc_dou8vec_minmax(const struct ctl_table *table, = int write, } EXPORT_SYMBOL_GPL(proc_dou8vec_minmax); =20 -static int __do_proc_doulongvec_minmax(void *data, - const struct ctl_table *table, int write, - void *buffer, size_t *lenp, loff_t *ppos, +static int __do_proc_doulongvec_minmax(const struct ctl_table *table, + int write, void *buffer, size_t *lenp, loff_t *ppos, unsigned long convmul, unsigned long convdiv) { unsigned long *i, *min, *max; @@ -849,12 +840,12 @@ static int __do_proc_doulongvec_minmax(void *data, size_t left; char *p; =20 - if (!data || !table->maxlen || !*lenp || (*ppos && !write)) { + if (!table->data || !table->maxlen || !*lenp || (*ppos && !write)) { *lenp =3D 0; return 0; } =20 - i =3D data; + i =3D table->data; min =3D table->extra1; max =3D table->extra2; vleft =3D table->maxlen / sizeof(unsigned long); @@ -917,8 +908,8 @@ static int do_proc_doulongvec_minmax(const struct ctl_t= able *table, int write, void *buffer, size_t *lenp, loff_t *ppos, unsigned long convmul, unsigned long convdiv) { - return __do_proc_doulongvec_minmax(table->data, table, write, - buffer, lenp, ppos, convmul, convdiv); + return __do_proc_doulongvec_minmax(table, write, buffer, lenp, ppos, + convmul, convdiv); } =20 /** --=20 2.50.1 From nobody Sat Feb 7 23:39:41 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4AC45261B9C; Mon, 13 Oct 2025 13:25:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760361946; cv=none; b=Zjf6IGnvmwXbOjCNWyaoTdAZQbToCyCbrFnLls6r4pb257xHRkia3L12fGMeF1a7wJeNRgHNS+qzfbl1/toGrtJnXdoKhNMoimRhLNMAODf3p62lvn8MMk8CTTOQjAxPQMr880Lm8VAt7tfB40yFKTDW9nnKn68rEQhEKCjs4Ug= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760361946; c=relaxed/simple; bh=UfEJu7bUmeezVz/Pc8RnUq8eKehGxWWFgOSUQwSlJQQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=NNbTW9AG/XU8oLFIOMY7bWGLLe6KIGoPEFkZWx2TwZ/w0KDVbO1LJk59prlbsWC20Z1oPxeHuDGsmp4FNr0ZGolffeys+ouGkJuTmN1D7kXfLZv22DUnS22azsDBVEEP8gq72MNxnR9rXp7ZQQjcklF8Aakv0iuboNlRVBsWmJo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=IgOobKQi; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="IgOobKQi" Received: by smtp.kernel.org (Postfix) with ESMTPS id 18E54C19421; Mon, 13 Oct 2025 13:25:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760361946; bh=UfEJu7bUmeezVz/Pc8RnUq8eKehGxWWFgOSUQwSlJQQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=IgOobKQiAWtd06+nvuNu1BE8tWqjH+alYEUwIA5C67adImCY6gCweacCkWg6DiZG+ NEJUQb1GIM61HMHSczkkZOg/fnh91H37QmWd8Hfeg46U5i0vAKDrnV1NR/2uettHDl SaNM9TpSYOtTeSyMedWMKknJwKrX6O8rRBAQ83dFX/zLweny2SXauNJctSodi5ONHz GMwhmd5KTExHVLNbNcX+ehJuZQ4G8fL8X1aJvXkk1aNkWkCQ5+XSf+JF3bS0SSDXGH mjK3/flqVbN2ISWMyn4XHr5KgkL6KkL2hkIoN78zK76TYZMQg5QfAP8OKAkJRrfmKw sDnsgRS7AVdYg== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0B23FCCD18E; Mon, 13 Oct 2025 13:25:46 +0000 (UTC) From: Joel Granados Date: Mon, 13 Oct 2025 15:24:53 +0200 Subject: [PATCH 3/8] sysctl: Remove superfluous __do_proc_* indirection Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251013-jag-sysctl_conv-v1-3-4dc35ceae733@kernel.org> References: <20251013-jag-sysctl_conv-v1-0-4dc35ceae733@kernel.org> In-Reply-To: <20251013-jag-sysctl_conv-v1-0-4dc35ceae733@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Kees Cook Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, Joel Granados X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=4478; i=joel.granados@kernel.org; h=from:subject:message-id; bh=UfEJu7bUmeezVz/Pc8RnUq8eKehGxWWFgOSUQwSlJQQ=; b=owJ4nAHtARL+kA0DAAoBupfNUreWQU8ByyZiAGjs/dMVrutsg30XpZDtsv/9tp+bDd6s5ipvr uLjKffqjVLldYkBswQAAQoAHRYhBK5HCVcl5jElzssnkLqXzVK3lkFPBQJo7P3TAAoJELqXzVK3 lkFP+E8L/2/b91K+4SuffVWeBi4OvbzW9camfH9Ei79wJfiO1NolpNZgbxdO9zt+2cCicaqoYfY Im8YOTkCb4ugAwkN/03E+9CwEx368J+JVdM2CnXrdgndkwB+dSEfOTjQE0kuWWfdhb1qEiE+SxB eSq9KZUO64YJ+QrebiX17M9PdInH8yeeOay0SORLpddVYFbmePzhnshLZk1qaBJGKrS3zrO0B0I dLbymIctCUSO5TZ9DqocF/EGc33iQnlKvgAbeCnq0GM7rny0ISwAOST/0BEKqg/AKf1zDXHLcaS P3Z+cAqT13wFvYiu0aLKxoAgrmBim5aWGteaOKZ53KYHKrEa2mg6OcVa0iPps7xX2DFX2KF9ce5 O1XVCEsV9wPnkMb6EkgC0wZkHJF5e8BUcm1A/JFnhiehcA8ALkAs6P+Hiz/41H+MW/SyEEju2TW 7QZUP0wdsOoXRHoZkhOarjUve3f61u9T94znMCibAAlfcefzxlAGIbHlfgWKYuVGYffpNYAFRY9 Tw= X-Developer-Key: i=joel.granados@kernel.org; a=openpgp; fpr=F1F8E46D30F0F6C4A45FF4465895FAAC338C6E77 X-Endpoint-Received: by B4 Relay for joel.granados@kernel.org/default with auth_id=239 Remove "__" from __do_proc_do{intvec,uintvec,ulongvec_minmax} internal functions and delete their corresponding do_proc_do* wrappers. These indirections are unnecessary as they do not add extra logic nor do they indicate a layer separation. Signed-off-by: Joel Granados --- kernel/sysctl.c | 52 +++++++++++++--------------------------------------- 1 file changed, 13 insertions(+), 39 deletions(-) diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 0e249a1f99fec084db649782f5ef8b37e40c6a7c..9b042d81fd1c6a32f60e2834a98= d48c1bc348de0 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -398,11 +398,11 @@ static int do_proc_douintvec_conv(unsigned long *lval= p, =20 static const char proc_wspace_sep[] =3D { ' ', '\t', '\n' }; =20 -static int __do_proc_dointvec(const struct ctl_table *table, int write, - void *buffer, size_t *lenp, loff_t *ppos, - int (*conv)(bool *negp, unsigned long *lvalp, - int *valp, int write, - const struct ctl_table *table)) + +static int do_proc_dointvec(const struct ctl_table *table, int write, + void *buffer, size_t *lenp, loff_t *ppos, + int (*conv)(bool *negp, unsigned long *lvalp, int *valp, + int write, const struct ctl_table *table)) { int *i, vleft, first =3D 1, err =3D 0; size_t left; @@ -470,14 +470,6 @@ static int __do_proc_dointvec(const struct ctl_table *= table, int write, return err; } =20 -static int do_proc_dointvec(const struct ctl_table *table, int write, - void *buffer, size_t *lenp, loff_t *ppos, - int (*conv)(bool *negp, unsigned long *lvalp, int *valp, - int write, const struct ctl_table *table)) -{ - return __do_proc_dointvec(table, write, buffer, lenp, ppos, conv); -} - static int do_proc_douintvec_w(const struct ctl_table *table, void *buffer, size_t *lenp, loff_t *ppos, int (*conv)(unsigned long *lvalp, @@ -526,7 +518,6 @@ static int do_proc_douintvec_w(const struct ctl_table *= table, void *buffer, =20 return 0; =20 - /* This is in keeping with old __do_proc_dointvec() */ bail_early: *ppos +=3D *lenp; return err; @@ -562,11 +553,10 @@ static int do_proc_douintvec_r(const struct ctl_table= *table, void *buffer, return err; } =20 -static int __do_proc_douintvec(const struct ctl_table *table, int write, - void *buffer, size_t *lenp, loff_t *ppos, - int (*conv)(unsigned long *lvalp, - unsigned int *valp, int write, - const struct ctl_table *table)) +int do_proc_douintvec(const struct ctl_table *table, int write, void *buff= er, + size_t *lenp, loff_t *ppos, + int (*conv)(unsigned long *lvalp, unsigned int *valp, + int write, const struct ctl_table *table)) { unsigned int vleft; =20 @@ -594,15 +584,6 @@ static int __do_proc_douintvec(const struct ctl_table = *table, int write, return do_proc_douintvec_r(table, buffer, lenp, ppos, conv); } =20 -int do_proc_douintvec(const struct ctl_table *table, int write, - void *buffer, size_t *lenp, loff_t *ppos, - int (*conv)(unsigned long *lvalp, - unsigned int *valp, int write, - const struct ctl_table *table)) -{ - return __do_proc_douintvec(table, write, buffer, lenp, ppos, conv); -} - /** * proc_dobool - read/write a bool * @table: the sysctl table @@ -831,9 +812,10 @@ int proc_dou8vec_minmax(const struct ctl_table *table,= int write, } EXPORT_SYMBOL_GPL(proc_dou8vec_minmax); =20 -static int __do_proc_doulongvec_minmax(const struct ctl_table *table, - int write, void *buffer, size_t *lenp, loff_t *ppos, - unsigned long convmul, unsigned long convdiv) +static int do_proc_doulongvec_minmax(const struct ctl_table *table, int wr= ite, + void *buffer, size_t *lenp, loff_t *ppos, + unsigned long convmul, + unsigned long convdiv) { unsigned long *i, *min, *max; int vleft, first =3D 1, err =3D 0; @@ -904,14 +886,6 @@ static int __do_proc_doulongvec_minmax(const struct ct= l_table *table, return err; } =20 -static int do_proc_doulongvec_minmax(const struct ctl_table *table, int wr= ite, - void *buffer, size_t *lenp, loff_t *ppos, unsigned long convmul, - unsigned long convdiv) -{ - return __do_proc_doulongvec_minmax(table, write, buffer, lenp, ppos, - convmul, convdiv); -} - /** * proc_doulongvec_minmax - read a vector of long integers with min/max va= lues * @table: the sysctl table --=20 2.50.1 From nobody Sat Feb 7 23:39:41 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7B8E83064AC; Mon, 13 Oct 2025 13:25:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760361946; cv=none; b=rYm8AjUu9Sii1CjLjGZb+WqRfeT5+Ua0sbHtchbBHxjvAbFVDra80LUTgsyg/OzEkL00f8gNT6jwtNYhEh5bAjsVdMy2Cb5vsdFZCVM/ec0RS4qDhUQffdDlX/A/pcP3p7zLG5eftJvCqAwL+q4jyxyTxlGTCX1D9m+mzDbckU8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760361946; c=relaxed/simple; bh=UsZpr7tzJfURt5nWobiw5O5X9RgHQGws0QBptGLRrMY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=kEfkW3jzLTcRzZaG19LhIlIA2tN3kF1JX8GJ/7wZxLHNvlLTkcgwUsbveD9rfGzoDJFm3jEfSt9ubDttFUaGqq7IbQW4Jgzl6FTHAYhm9eOiM+cmbnHuSwsNueZ1vMjN6oDhEdYnZDi+uYfR7AWIiMbQxHnP/sth9LHq73T5xRw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=b1nOwW7A; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="b1nOwW7A" Received: by smtp.kernel.org (Postfix) with ESMTPS id 230DAC19423; Mon, 13 Oct 2025 13:25:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760361946; bh=UsZpr7tzJfURt5nWobiw5O5X9RgHQGws0QBptGLRrMY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=b1nOwW7AfK9luogtTgs05zzCpml3/fzctXuhf1CFQNi8WAY51R0VvQf699LuSDsqm hNTGbXzOKos93saoe1Jo4zLaSNrRjbN2DjwqnWsybV8iglqxRPXt0dAd5jmBYsDZDv LtAwpRLIK66Hg2KAzfWG2az9q1ksV2BZ1VtuHUrvlQ/ohcNkdkdE1AuzSiPTaz/Krr 6Ij1xYLI+7F5EBqgQIdzRf6fCPPEHVZ5Ax3LhSVE3pTmrv6yBebQsWuhid1VbPtXUt Agf1C1vWRqGqj73FFX1jSQI27KC8by4Ctk0MytP6Z0w6RU1qVI1uQM6d4QFqq0DX8R RMP069X3y8TYg== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 197D2CCD190; Mon, 13 Oct 2025 13:25:46 +0000 (UTC) From: Joel Granados Date: Mon, 13 Oct 2025 15:24:54 +0200 Subject: [PATCH 4/8] sysctl: Indicate the direction of operation with macro names Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251013-jag-sysctl_conv-v1-4-4dc35ceae733@kernel.org> References: <20251013-jag-sysctl_conv-v1-0-4dc35ceae733@kernel.org> In-Reply-To: <20251013-jag-sysctl_conv-v1-0-4dc35ceae733@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Kees Cook Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, Joel Granados X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=30764; i=joel.granados@kernel.org; h=from:subject:message-id; bh=UsZpr7tzJfURt5nWobiw5O5X9RgHQGws0QBptGLRrMY=; b=owJ4nAHtARL+kA0DAAoBupfNUreWQU8ByyZiAGjs/dTA1+41uAmQnJdi2KW5yI496ZT1He0aX FT0Q5POC0aDc4kBswQAAQoAHRYhBK5HCVcl5jElzssnkLqXzVK3lkFPBQJo7P3UAAoJELqXzVK3 lkFPG3AL/30FerG4eudsbWgjEHJ6/n9EUtWM+r4RzxSER9a8jJ1tER5doCNmWl650Ec3Hty4BNr uzG1kEZAAsp3sV8h7bbPYut/x7I/YMs2IVZ0oi7h/CGieUrvo9HgNMtIN4AV2tDSj0K87FK/h9C ytY6onUqFccRMTIMHgYv+cSNnUCXu4XCverXnJCsmtIlODwA3le4/9Fx9UR/YkldAdYK22+8QH3 3dkT4qVDDPxzzXr6TmdADLJpYwzMGBje6ZOOuMsnGd0bSM13F4yP8sgFB0ukrU4kIWC7z6TErQX RaWsRyLydbkAQfcTonPirYK468hiZXOXC4IDw+Xx5Y6L8gxC2ShU++n1GpB0zS/NUs6dOEM2Rmb W2eM5o9+ptvRELeGCpx8++Ia1OkDLk3RGScr71RbyaowcHX2OHfsZRvxpNZvqyQKCZGjrRmyL32 mC+vTed1m2nOXuV1WRIAQR1w91Esha0Jmfk4zx84IVKk5kMqiY7y65p6TVABJSYjijb6xfuu0+8 JY= X-Developer-Key: i=joel.granados@kernel.org; a=openpgp; fpr=F1F8E46D30F0F6C4A45FF4465895FAAC338C6E77 X-Endpoint-Received: by B4 Relay for joel.granados@kernel.org/default with auth_id=239 Replace the "write" integer parameter with SYSCTL_USER_TO_KERN() and SYSCTL_KERN_TO_USER() that clearly indicate data flow direction in sysctl operations. "write" originates in proc_sysctl.c (proc_sys_{read,write}) and can take one of two values: "0" or "1" when called from proc_sys_read and proc_sys_write respectively. When write has a value of zero, data is "written" to a user space buffer from a kernel variable (usually ctl_table->data). Whereas when write has a value greater than zero, data is "written" to an internal kernel variable from a user space buffer. Remove this ambiguity by introducing macros that clearly indicate the direction of the "write". The write mode names in sysctl_writes_mode are left unchanged as these directly relate to the sysctl_write_strict file in /proc/sys where the word "write" unambiguously refers to writing to a file. Signed-off-by: Joel Granados --- kernel/sysctl.c | 252 ++++++++++++++++++++++++++++++----------------------= ---- 1 file changed, 136 insertions(+), 116 deletions(-) diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 9b042d81fd1c6a32f60e2834a98d48c1bc348de0..69148fe7359994b85c076b7b675= 0792b2d1c751e 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -30,6 +30,19 @@ EXPORT_SYMBOL(sysctl_vals); const unsigned long sysctl_long_vals[] =3D { 0, 1, LONG_MAX }; EXPORT_SYMBOL_GPL(sysctl_long_vals); =20 +/** + * + * "dir" originates from read_iter (dir =3D 0) or write_iter (dir =3D 1) + * in the file_operations struct at proc/proc_sysctl.c. Its value means + * one of two things for sysctl: + * 1. SYSCTL_USER_TO_KERN(dir) Writing to an internal kernel variable from= user + * space (dir > 0) + * 2. SYSCTL_KERN_TO_USER(dir) Writing to a user space buffer from a kernel + * variable (dir =3D=3D 0). + */ +#define SYSCTL_USER_TO_KERN(dir) (!!(dir)) +#define SYSCTL_KERN_TO_USER(dir) (!dir) + #if defined(CONFIG_SYSCTL) =20 /* Constants used for minimum and maximum */ @@ -55,7 +68,8 @@ static const int cap_last_cap =3D CAP_LAST_CAP; * to the buffer. * * These write modes control how current file position affects the behavio= r of - * updating sysctl values through the proc interface on each write. + * updating internal kernel (SYSCTL_USER_TO_KERN) sysctl values through th= e proc + * interface on each write. */ enum sysctl_writes_mode { SYSCTL_WRITES_LEGACY =3D -1, @@ -73,7 +87,7 @@ static enum sysctl_writes_mode sysctl_writes_strict =3D S= YSCTL_WRITES_STRICT; =20 #ifdef CONFIG_PROC_SYSCTL =20 -static int _proc_do_string(char *data, int maxlen, int write, +static int _proc_do_string(char *data, int maxlen, int dir, char *buffer, size_t *lenp, loff_t *ppos) { size_t len; @@ -84,7 +98,7 @@ static int _proc_do_string(char *data, int maxlen, int wr= ite, return 0; } =20 - if (write) { + if (SYSCTL_USER_TO_KERN(dir)) { if (sysctl_writes_strict =3D=3D SYSCTL_WRITES_STRICT) { /* Only continue writes not past the end of buffer. */ len =3D strlen(data); @@ -172,7 +186,7 @@ static bool proc_first_pos_non_zero_ignore(loff_t *ppos, /** * proc_dostring - read a string sysctl * @table: the sysctl table - * @write: %TRUE if this is a write to the sysctl file + * @dir: %TRUE if this is a write to the sysctl file * @buffer: the user buffer * @lenp: the size of the user buffer * @ppos: file position @@ -186,13 +200,13 @@ static bool proc_first_pos_non_zero_ignore(loff_t *pp= os, * * Returns 0 on success. */ -int proc_dostring(const struct ctl_table *table, int write, +int proc_dostring(const struct ctl_table *table, int dir, void *buffer, size_t *lenp, loff_t *ppos) { - if (write) + if (SYSCTL_USER_TO_KERN(dir)) proc_first_pos_non_zero_ignore(ppos, table); =20 - return _proc_do_string(table->data, table->maxlen, write, buffer, lenp, + return _proc_do_string(table->data, table->maxlen, dir, buffer, lenp, ppos); } =20 @@ -355,10 +369,10 @@ static void proc_put_char(void **buf, size_t *size, c= har c) } =20 static int do_proc_dointvec_conv(bool *negp, unsigned long *lvalp, - int *valp, int write, + int *valp, int dir, const struct ctl_table *table) { - if (write) { + if (SYSCTL_USER_TO_KERN(dir)) { if (*negp) { if (*lvalp > (unsigned long) INT_MAX + 1) return -EINVAL; @@ -382,10 +396,10 @@ static int do_proc_dointvec_conv(bool *negp, unsigned= long *lvalp, } =20 static int do_proc_douintvec_conv(unsigned long *lvalp, - unsigned int *valp, int write, + unsigned int *valp, int dir, const struct ctl_table *table) { - if (write) { + if (SYSCTL_USER_TO_KERN(dir)) { if (*lvalp > UINT_MAX) return -EINVAL; WRITE_ONCE(*valp, *lvalp); @@ -399,16 +413,17 @@ static int do_proc_douintvec_conv(unsigned long *lval= p, static const char proc_wspace_sep[] =3D { ' ', '\t', '\n' }; =20 =20 -static int do_proc_dointvec(const struct ctl_table *table, int write, +static int do_proc_dointvec(const struct ctl_table *table, int dir, void *buffer, size_t *lenp, loff_t *ppos, int (*conv)(bool *negp, unsigned long *lvalp, int *valp, - int write, const struct ctl_table *table)) + int dir, const struct ctl_table *table)) { int *i, vleft, first =3D 1, err =3D 0; size_t left; char *p; =20 - if (!table->data || !table->maxlen || !*lenp || (*ppos && !write)) { + if (!table->data || !table->maxlen || !*lenp || + (*ppos && SYSCTL_KERN_TO_USER(dir))) { *lenp =3D 0; return 0; } @@ -420,7 +435,7 @@ static int do_proc_dointvec(const struct ctl_table *tab= le, int write, if (!conv) conv =3D do_proc_dointvec_conv; =20 - if (write) { + if (SYSCTL_USER_TO_KERN(dir)) { if (proc_first_pos_non_zero_ignore(ppos, table)) goto out; =20 @@ -433,7 +448,7 @@ static int do_proc_dointvec(const struct ctl_table *tab= le, int write, unsigned long lval; bool neg; =20 - if (write) { + if (SYSCTL_USER_TO_KERN(dir)) { proc_skip_spaces(&p, &left); =20 if (!left) @@ -458,11 +473,11 @@ static int do_proc_dointvec(const struct ctl_table *t= able, int write, } } =20 - if (!write && !first && left && !err) + if (SYSCTL_KERN_TO_USER(dir) && !first && left && !err) proc_put_char(&buffer, &left, '\n'); - if (write && !err && left) + if (SYSCTL_USER_TO_KERN(dir) && !err && left) proc_skip_spaces(&p, &left); - if (write && first) + if (SYSCTL_USER_TO_KERN(dir) && first) return err ? : -EINVAL; *lenp -=3D left; out: @@ -473,7 +488,7 @@ static int do_proc_dointvec(const struct ctl_table *tab= le, int write, static int do_proc_douintvec_w(const struct ctl_table *table, void *buffer, size_t *lenp, loff_t *ppos, int (*conv)(unsigned long *lvalp, - unsigned int *valp, int write, + unsigned int *valp, int dir, const struct ctl_table *table)) { unsigned long lval; @@ -526,7 +541,7 @@ static int do_proc_douintvec_w(const struct ctl_table *= table, void *buffer, static int do_proc_douintvec_r(const struct ctl_table *table, void *buffer, size_t *lenp, loff_t *ppos, int (*conv)(unsigned long *lvalp, - unsigned int *valp, int write, + unsigned int *valp, int dir, const struct ctl_table *table)) { unsigned long lval; @@ -553,14 +568,15 @@ static int do_proc_douintvec_r(const struct ctl_table= *table, void *buffer, return err; } =20 -int do_proc_douintvec(const struct ctl_table *table, int write, void *buff= er, +int do_proc_douintvec(const struct ctl_table *table, int dir, void *buffer, size_t *lenp, loff_t *ppos, int (*conv)(unsigned long *lvalp, unsigned int *valp, - int write, const struct ctl_table *table)) + int dir, const struct ctl_table *table)) { unsigned int vleft; =20 - if (!table->data || !table->maxlen || !*lenp || (*ppos && !write)) { + if (!table->data || !table->maxlen || !*lenp || + (*ppos && SYSCTL_KERN_TO_USER(dir))) { *lenp =3D 0; return 0; } @@ -579,7 +595,7 @@ int do_proc_douintvec(const struct ctl_table *table, in= t write, void *buffer, if (!conv) conv =3D do_proc_douintvec_conv; =20 - if (write) + if (SYSCTL_USER_TO_KERN(dir)) return do_proc_douintvec_w(table, buffer, lenp, ppos, conv); return do_proc_douintvec_r(table, buffer, lenp, ppos, conv); } @@ -587,7 +603,7 @@ int do_proc_douintvec(const struct ctl_table *table, in= t write, void *buffer, /** * proc_dobool - read/write a bool * @table: the sysctl table - * @write: %TRUE if this is a write to the sysctl file + * @dir: %TRUE if this is a write to the sysctl file * @buffer: the user buffer * @lenp: the size of the user buffer * @ppos: file position @@ -600,7 +616,7 @@ int do_proc_douintvec(const struct ctl_table *table, in= t write, void *buffer, * * Returns 0 on success. */ -int proc_dobool(const struct ctl_table *table, int write, void *buffer, +int proc_dobool(const struct ctl_table *table, int dir, void *buffer, size_t *lenp, loff_t *ppos) { struct ctl_table tmp; @@ -616,10 +632,10 @@ int proc_dobool(const struct ctl_table *table, int wr= ite, void *buffer, tmp.data =3D &val; =20 val =3D READ_ONCE(*data); - res =3D proc_dointvec(&tmp, write, buffer, lenp, ppos); + res =3D proc_dointvec(&tmp, dir, buffer, lenp, ppos); if (res) return res; - if (write) + if (SYSCTL_USER_TO_KERN(dir)) WRITE_ONCE(*data, val); return 0; } @@ -627,7 +643,7 @@ int proc_dobool(const struct ctl_table *table, int writ= e, void *buffer, /** * proc_dointvec - read a vector of integers * @table: the sysctl table - * @write: %TRUE if this is a write to the sysctl file + * @dir: %TRUE if this is a write to the sysctl file * @buffer: the user buffer * @lenp: the size of the user buffer * @ppos: file position @@ -637,16 +653,16 @@ int proc_dobool(const struct ctl_table *table, int wr= ite, void *buffer, * * Returns 0 on success. */ -int proc_dointvec(const struct ctl_table *table, int write, void *buffer, +int proc_dointvec(const struct ctl_table *table, int dir, void *buffer, size_t *lenp, loff_t *ppos) { - return do_proc_dointvec(table, write, buffer, lenp, ppos, NULL); + return do_proc_dointvec(table, dir, buffer, lenp, ppos, NULL); } =20 /** * proc_douintvec - read a vector of unsigned integers * @table: the sysctl table - * @write: %TRUE if this is a write to the sysctl file + * @dir: %TRUE if this is a write to the sysctl file * @buffer: the user buffer * @lenp: the size of the user buffer * @ppos: file position @@ -656,15 +672,15 @@ int proc_dointvec(const struct ctl_table *table, int = write, void *buffer, * * Returns 0 on success. */ -int proc_douintvec(const struct ctl_table *table, int write, void *buffer, +int proc_douintvec(const struct ctl_table *table, int dir, void *buffer, size_t *lenp, loff_t *ppos) { - return do_proc_douintvec(table, write, buffer, lenp, ppos, + return do_proc_douintvec(table, dir, buffer, lenp, ppos, do_proc_douintvec_conv); } =20 static int do_proc_dointvec_minmax_conv(bool *negp, unsigned long *lvalp, - int *valp, int write, + int *valp, int dir, const struct ctl_table *table) { int tmp, ret, *min, *max; @@ -672,13 +688,13 @@ static int do_proc_dointvec_minmax_conv(bool *negp, u= nsigned long *lvalp, * If writing, first do so via a temporary local int so we can * bounds-check it before touching *valp. */ - int *ip =3D write ? &tmp : valp; + int *ip =3D SYSCTL_USER_TO_KERN(dir) ? &tmp : valp; =20 - ret =3D do_proc_dointvec_conv(negp, lvalp, ip, write, table); + ret =3D do_proc_dointvec_conv(negp, lvalp, ip, dir, table); if (ret) return ret; =20 - if (write) { + if (SYSCTL_USER_TO_KERN(dir)) { min =3D (int *) table->extra1; max =3D (int *) table->extra2; if ((min && *min > tmp) || (max && *max < tmp)) @@ -692,7 +708,7 @@ static int do_proc_dointvec_minmax_conv(bool *negp, uns= igned long *lvalp, /** * proc_dointvec_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 + * @dir: %TRUE if this is a write to the sysctl file * @buffer: the user buffer * @lenp: the size of the user buffer * @ppos: file position @@ -703,29 +719,30 @@ static int do_proc_dointvec_minmax_conv(bool *negp, u= nsigned long *lvalp, * This routine will ensure the values are within the range specified by * table->extra1 (min) and table->extra2 (max). * - * Returns 0 on success or -EINVAL on write when the range check fails. + * Returns 0 on success or -EINVAL when the range check fails and + * SYSCTL_USER_TO_KERN(dir) =3D=3D true */ -int proc_dointvec_minmax(const struct ctl_table *table, int write, +int proc_dointvec_minmax(const struct ctl_table *table, int dir, void *buffer, size_t *lenp, loff_t *ppos) { - return do_proc_dointvec(table, write, buffer, lenp, ppos, + return do_proc_dointvec(table, dir, buffer, lenp, ppos, do_proc_dointvec_minmax_conv); } =20 static int do_proc_douintvec_minmax_conv(unsigned long *lvalp, - unsigned int *valp, int write, + unsigned int *valp, int dir, const struct ctl_table *table) { int ret; unsigned int tmp, *min, *max; - /* write via temporary local uint for bounds-checking */ - unsigned int *up =3D write ? &tmp : valp; + /* When writing to the kernel use a temp local uint for bounds-checking */ + unsigned int *up =3D SYSCTL_USER_TO_KERN(dir) ? &tmp : valp; =20 - ret =3D do_proc_douintvec_conv(lvalp, up, write, table); + ret =3D do_proc_douintvec_conv(lvalp, up, dir, table); if (ret) return ret; =20 - if (write) { + if (SYSCTL_USER_TO_KERN(dir)) { min =3D (unsigned int *) table->extra1; max =3D (unsigned int *) table->extra2; if ((min && *min > tmp) || (max && *max < tmp)) @@ -740,7 +757,7 @@ static int do_proc_douintvec_minmax_conv(unsigned long = *lvalp, /** * proc_douintvec_minmax - read a vector of unsigned ints with min/max val= ues * @table: the sysctl table - * @write: %TRUE if this is a write to the sysctl file + * @dir: %TRUE if this is a write to the sysctl file * @buffer: the user buffer * @lenp: the size of the user buffer * @ppos: file position @@ -754,19 +771,20 @@ static int do_proc_douintvec_minmax_conv(unsigned lon= g *lvalp, * check for UINT_MAX to avoid having to support wrap around uses from * userspace. * - * Returns 0 on success or -ERANGE on write when the range check fails. + * Returns 0 on success or -ERANGE when range check failes and + * SYSCTL_USER_TO_KERN(dir) =3D=3D true */ -int proc_douintvec_minmax(const struct ctl_table *table, int write, +int proc_douintvec_minmax(const struct ctl_table *table, int dir, void *buffer, size_t *lenp, loff_t *ppos) { - return do_proc_douintvec(table, write, buffer, lenp, ppos, + return do_proc_douintvec(table, dir, buffer, lenp, ppos, do_proc_douintvec_minmax_conv); } =20 /** * proc_dou8vec_minmax - read a vector of unsigned chars with min/max valu= es * @table: the sysctl table - * @write: %TRUE if this is a write to the sysctl file + * @dir: %TRUE if this is a write to the sysctl file * @buffer: the user buffer * @lenp: the size of the user buffer * @ppos: file position @@ -778,9 +796,10 @@ int proc_douintvec_minmax(const struct ctl_table *tabl= e, int write, * This routine will ensure the values are within the range specified by * table->extra1 (min) and table->extra2 (max). * - * Returns 0 on success or an error on write when the range check fails. + * Returns 0 on success or an error on SYSCTL_USER_TO_KERN(dir) =3D=3D true + * and the range check fails. */ -int proc_dou8vec_minmax(const struct ctl_table *table, int write, +int proc_dou8vec_minmax(const struct ctl_table *table, int dir, void *buffer, size_t *lenp, loff_t *ppos) { struct ctl_table tmp; @@ -802,17 +821,17 @@ int proc_dou8vec_minmax(const struct ctl_table *table= , int write, tmp.extra2 =3D (unsigned int *) &max; =20 val =3D READ_ONCE(*data); - res =3D do_proc_douintvec(&tmp, write, buffer, lenp, ppos, + res =3D do_proc_douintvec(&tmp, dir, buffer, lenp, ppos, do_proc_douintvec_minmax_conv); if (res) return res; - if (write) + if (SYSCTL_USER_TO_KERN(dir)) WRITE_ONCE(*data, val); return 0; } EXPORT_SYMBOL_GPL(proc_dou8vec_minmax); =20 -static int do_proc_doulongvec_minmax(const struct ctl_table *table, int wr= ite, +static int do_proc_doulongvec_minmax(const struct ctl_table *table, int di= r, void *buffer, size_t *lenp, loff_t *ppos, unsigned long convmul, unsigned long convdiv) @@ -822,7 +841,8 @@ static int do_proc_doulongvec_minmax(const struct ctl_t= able *table, int write, size_t left; char *p; =20 - if (!table->data || !table->maxlen || !*lenp || (*ppos && !write)) { + if (!table->data || !table->maxlen || !*lenp || + (*ppos && SYSCTL_KERN_TO_USER(dir))) { *lenp =3D 0; return 0; } @@ -833,7 +853,7 @@ static int do_proc_doulongvec_minmax(const struct ctl_t= able *table, int write, vleft =3D table->maxlen / sizeof(unsigned long); left =3D *lenp; =20 - if (write) { + if (SYSCTL_USER_TO_KERN(dir)) { if (proc_first_pos_non_zero_ignore(ppos, table)) goto out; =20 @@ -845,7 +865,7 @@ static int do_proc_doulongvec_minmax(const struct ctl_t= able *table, int write, for (; left && vleft--; i++, first =3D 0) { unsigned long val; =20 - if (write) { + if (SYSCTL_USER_TO_KERN(dir)) { bool neg; =20 proc_skip_spaces(&p, &left); @@ -874,11 +894,11 @@ static int do_proc_doulongvec_minmax(const struct ctl= _table *table, int write, } } =20 - if (!write && !first && left && !err) + if (SYSCTL_KERN_TO_USER(dir) && !first && left && !err) proc_put_char(&buffer, &left, '\n'); - if (write && !err) + if (SYSCTL_USER_TO_KERN(dir) && !err) proc_skip_spaces(&p, &left); - if (write && first) + if (SYSCTL_USER_TO_KERN(dir) && first) return err ? : -EINVAL; *lenp -=3D left; out: @@ -889,7 +909,7 @@ static int do_proc_doulongvec_minmax(const struct ctl_t= able *table, int write, /** * proc_doulongvec_minmax - read a vector of long integers with min/max va= lues * @table: the sysctl table - * @write: %TRUE if this is a write to the sysctl file + * @dir: %TRUE if this is a write to the sysctl file * @buffer: the user buffer * @lenp: the size of the user buffer * @ppos: file position @@ -902,16 +922,16 @@ static int do_proc_doulongvec_minmax(const struct ctl= _table *table, int write, * * Returns 0 on success. */ -int proc_doulongvec_minmax(const struct ctl_table *table, int write, +int proc_doulongvec_minmax(const struct ctl_table *table, int dir, void *buffer, size_t *lenp, loff_t *ppos) { - return do_proc_doulongvec_minmax(table, write, buffer, lenp, ppos, 1l,= 1l); + return do_proc_doulongvec_minmax(table, dir, buffer, lenp, ppos, 1l, 1l); } =20 /** * proc_doulongvec_ms_jiffies_minmax - read a vector of millisecond values= with min/max values * @table: the sysctl table - * @write: %TRUE if this is a write to the sysctl file + * @dir: %TRUE if this is a write to the sysctl file * @buffer: the user buffer * @lenp: the size of the user buffer * @ppos: file position @@ -925,19 +945,19 @@ int proc_doulongvec_minmax(const struct ctl_table *ta= ble, int write, * * Returns 0 on success. */ -int proc_doulongvec_ms_jiffies_minmax(const struct ctl_table *table, int w= rite, +int proc_doulongvec_ms_jiffies_minmax(const struct ctl_table *table, int d= ir, void *buffer, size_t *lenp, loff_t *ppos) { - return do_proc_doulongvec_minmax(table, write, buffer, - lenp, ppos, HZ, 1000l); + return do_proc_doulongvec_minmax(table, dir, buffer, + lenp, ppos, HZ, 1000l); } =20 =20 static int do_proc_dointvec_jiffies_conv(bool *negp, unsigned long *lvalp, - int *valp, int write, + int *valp, int dir, const struct ctl_table *table) { - if (write) { + if (SYSCTL_USER_TO_KERN(dir)) { if (*lvalp > INT_MAX / HZ) return 1; if (*negp) @@ -960,10 +980,10 @@ static int do_proc_dointvec_jiffies_conv(bool *negp, = unsigned long *lvalp, } =20 static int do_proc_dointvec_userhz_jiffies_conv(bool *negp, unsigned long = *lvalp, - int *valp, int write, + int *valp, int dir, const struct ctl_table *table) { - if (write) { + if (SYSCTL_USER_TO_KERN(dir)) { if (USER_HZ < HZ && *lvalp > (LONG_MAX / HZ) * USER_HZ) return 1; *valp =3D clock_t_to_jiffies(*negp ? -*lvalp : *lvalp); @@ -983,10 +1003,10 @@ static int do_proc_dointvec_userhz_jiffies_conv(bool= *negp, unsigned long *lvalp } =20 static int do_proc_dointvec_ms_jiffies_conv(bool *negp, unsigned long *lva= lp, - int *valp, int write, + int *valp, int dir, const struct ctl_table *table) { - if (write) { + if (SYSCTL_USER_TO_KERN(dir)) { unsigned long jif =3D msecs_to_jiffies(*negp ? -*lvalp : *lvalp); =20 if (jif > INT_MAX) @@ -1008,7 +1028,7 @@ static int do_proc_dointvec_ms_jiffies_conv(bool *neg= p, unsigned long *lvalp, } =20 static int do_proc_dointvec_ms_jiffies_minmax_conv(bool *negp, unsigned lo= ng *lvalp, - int *valp, int write, + int *valp, int dir, const struct ctl_table *table) { int tmp, ret, *min, *max; @@ -1016,13 +1036,13 @@ static int do_proc_dointvec_ms_jiffies_minmax_conv(= bool *negp, unsigned long *lv * If writing, first do so via a temporary local int so we can * bounds-check it before touching *valp. */ - int *ip =3D write ? &tmp : valp; + int *ip =3D SYSCTL_USER_TO_KERN(dir) ? &tmp : valp; =20 - ret =3D do_proc_dointvec_ms_jiffies_conv(negp, lvalp, ip, write, table); + ret =3D do_proc_dointvec_ms_jiffies_conv(negp, lvalp, ip, dir, table); if (ret) return ret; =20 - if (write) { + if (SYSCTL_USER_TO_KERN(dir)) { min =3D (int *) table->extra1; max =3D (int *) table->extra2; if ((min && *min > tmp) || (max && *max < tmp)) @@ -1035,7 +1055,7 @@ static int do_proc_dointvec_ms_jiffies_minmax_conv(bo= ol *negp, unsigned long *lv /** * proc_dointvec_jiffies - read a vector of integers as seconds * @table: the sysctl table - * @write: %TRUE if this is a write to the sysctl file + * @dir: %TRUE if this is a write to the sysctl file * @buffer: the user buffer * @lenp: the size of the user buffer * @ppos: file position @@ -1047,24 +1067,24 @@ static int do_proc_dointvec_ms_jiffies_minmax_conv(= bool *negp, unsigned long *lv * * Returns 0 on success. */ -int proc_dointvec_jiffies(const struct ctl_table *table, int write, +int proc_dointvec_jiffies(const struct ctl_table *table, int dir, void *buffer, size_t *lenp, loff_t *ppos) { - return do_proc_dointvec(table,write,buffer,lenp,ppos, - do_proc_dointvec_jiffies_conv); + return do_proc_dointvec(table, dir, buffer, lenp, ppos, + do_proc_dointvec_jiffies_conv); } =20 -int proc_dointvec_ms_jiffies_minmax(const struct ctl_table *table, int wri= te, +int proc_dointvec_ms_jiffies_minmax(const struct ctl_table *table, int dir, void *buffer, size_t *lenp, loff_t *ppos) { - return do_proc_dointvec(table, write, buffer, lenp, ppos, + return do_proc_dointvec(table, dir, buffer, lenp, ppos, do_proc_dointvec_ms_jiffies_minmax_conv); } =20 /** * proc_dointvec_userhz_jiffies - read a vector of integers as 1/USER_HZ s= econds * @table: the sysctl table - * @write: %TRUE if this is a write to the sysctl file + * @dir: %TRUE if this is a write to the sysctl file * @buffer: the user buffer * @lenp: the size of the user buffer * @ppos: pointer to the file position @@ -1076,17 +1096,17 @@ int proc_dointvec_ms_jiffies_minmax(const struct ct= l_table *table, int write, * * Returns 0 on success. */ -int proc_dointvec_userhz_jiffies(const struct ctl_table *table, int write, +int proc_dointvec_userhz_jiffies(const struct ctl_table *table, int dir, void *buffer, size_t *lenp, loff_t *ppos) { - return do_proc_dointvec(table, write, buffer, lenp, ppos, + return do_proc_dointvec(table, dir, buffer, lenp, ppos, do_proc_dointvec_userhz_jiffies_conv); } =20 /** * proc_dointvec_ms_jiffies - read a vector of integers as 1 milliseconds * @table: the sysctl table - * @write: %TRUE if this is a write to the sysctl file + * @dir: %TRUE if this is a write to the sysctl file * @buffer: the user buffer * @lenp: the size of the user buffer * @ppos: the current position in the file @@ -1098,17 +1118,17 @@ int proc_dointvec_userhz_jiffies(const struct ctl_t= able *table, int write, * * Returns 0 on success. */ -int proc_dointvec_ms_jiffies(const struct ctl_table *table, int write, voi= d *buffer, +int proc_dointvec_ms_jiffies(const struct ctl_table *table, int dir, void = *buffer, size_t *lenp, loff_t *ppos) { - return do_proc_dointvec(table, write, buffer, lenp, ppos, + return do_proc_dointvec(table, dir, buffer, lenp, ppos, do_proc_dointvec_ms_jiffies_conv); } =20 /** * proc_do_large_bitmap - read/write from/to a large bitmap * @table: the sysctl table - * @write: %TRUE if this is a write to the sysctl file + * @dir: %TRUE if this is a write to the sysctl file * @buffer: the user buffer * @lenp: the size of the user buffer * @ppos: file position @@ -1122,7 +1142,7 @@ int proc_dointvec_ms_jiffies(const struct ctl_table *= table, int write, void *buf * * Returns 0 on success. */ -int proc_do_large_bitmap(const struct ctl_table *table, int write, +int proc_do_large_bitmap(const struct ctl_table *table, int dir, void *buffer, size_t *lenp, loff_t *ppos) { int err =3D 0; @@ -1132,12 +1152,12 @@ int proc_do_large_bitmap(const struct ctl_table *ta= ble, int write, unsigned long *tmp_bitmap =3D NULL; char tr_a[] =3D { '-', ',', '\n' }, tr_b[] =3D { ',', '\n', 0 }, c; =20 - if (!bitmap || !bitmap_len || !left || (*ppos && !write)) { + if (!bitmap || !bitmap_len || !left || (*ppos && SYSCTL_KERN_TO_USER(dir)= )) { *lenp =3D 0; return 0; } =20 - if (write) { + if (SYSCTL_USER_TO_KERN(dir)) { char *p =3D buffer; size_t skipped =3D 0; =20 @@ -1238,7 +1258,7 @@ int proc_do_large_bitmap(const struct ctl_table *tabl= e, int write, } =20 if (!err) { - if (write) { + if (SYSCTL_USER_TO_KERN(dir)) { if (*ppos) bitmap_or(bitmap, bitmap, tmp_bitmap, bitmap_len); else @@ -1254,85 +1274,85 @@ int proc_do_large_bitmap(const struct ctl_table *ta= ble, int write, =20 #else /* CONFIG_PROC_SYSCTL */ =20 -int proc_dostring(const struct ctl_table *table, int write, +int proc_dostring(const struct ctl_table *table, int dir, void *buffer, size_t *lenp, loff_t *ppos) { return -ENOSYS; } =20 -int proc_dobool(const struct ctl_table *table, int write, +int proc_dobool(const struct ctl_table *table, int dir, void *buffer, size_t *lenp, loff_t *ppos) { return -ENOSYS; } =20 -int proc_dointvec(const struct ctl_table *table, int write, +int proc_dointvec(const struct ctl_table *table, int dir, void *buffer, size_t *lenp, loff_t *ppos) { return -ENOSYS; } =20 -int proc_douintvec(const struct ctl_table *table, int write, +int proc_douintvec(const struct ctl_table *table, int dir, void *buffer, size_t *lenp, loff_t *ppos) { return -ENOSYS; } =20 -int proc_dointvec_minmax(const struct ctl_table *table, int write, +int proc_dointvec_minmax(const struct ctl_table *table, int dir, void *buffer, size_t *lenp, loff_t *ppos) { return -ENOSYS; } =20 -int proc_douintvec_minmax(const struct ctl_table *table, int write, +int proc_douintvec_minmax(const struct ctl_table *table, int dir, void *buffer, size_t *lenp, loff_t *ppos) { return -ENOSYS; } =20 -int proc_dou8vec_minmax(const struct ctl_table *table, int write, +int proc_dou8vec_minmax(const struct ctl_table *table, int dir, void *buffer, size_t *lenp, loff_t *ppos) { return -ENOSYS; } =20 -int proc_dointvec_jiffies(const struct ctl_table *table, int write, +int proc_dointvec_jiffies(const struct ctl_table *table, int dir, void *buffer, size_t *lenp, loff_t *ppos) { return -ENOSYS; } =20 -int proc_dointvec_ms_jiffies_minmax(const struct ctl_table *table, int wri= te, +int proc_dointvec_ms_jiffies_minmax(const struct ctl_table *table, int dir, void *buffer, size_t *lenp, loff_t *ppos) { return -ENOSYS; } =20 -int proc_dointvec_userhz_jiffies(const struct ctl_table *table, int write, +int proc_dointvec_userhz_jiffies(const struct ctl_table *table, int dir, void *buffer, size_t *lenp, loff_t *ppos) { return -ENOSYS; } =20 -int proc_dointvec_ms_jiffies(const struct ctl_table *table, int write, +int proc_dointvec_ms_jiffies(const struct ctl_table *table, int dir, void *buffer, size_t *lenp, loff_t *ppos) { return -ENOSYS; } =20 -int proc_doulongvec_minmax(const struct ctl_table *table, int write, +int proc_doulongvec_minmax(const struct ctl_table *table, int dir, void *buffer, size_t *lenp, loff_t *ppos) { return -ENOSYS; } =20 -int proc_doulongvec_ms_jiffies_minmax(const struct ctl_table *table, int w= rite, +int proc_doulongvec_ms_jiffies_minmax(const struct ctl_table *table, int d= ir, void *buffer, size_t *lenp, loff_t *ppos) { return -ENOSYS; } =20 -int proc_do_large_bitmap(const struct ctl_table *table, int write, +int proc_do_large_bitmap(const struct ctl_table *table, int dir, void *buffer, size_t *lenp, loff_t *ppos) { return -ENOSYS; @@ -1341,7 +1361,7 @@ int proc_do_large_bitmap(const struct ctl_table *tabl= e, int write, #endif /* CONFIG_PROC_SYSCTL */ =20 #if defined(CONFIG_SYSCTL) -int proc_do_static_key(const struct ctl_table *table, int write, +int proc_do_static_key(const struct ctl_table *table, int dir, void *buffer, size_t *lenp, loff_t *ppos) { struct static_key *key =3D (struct static_key *)table->data; @@ -1355,13 +1375,13 @@ int proc_do_static_key(const struct ctl_table *tabl= e, int write, .extra2 =3D SYSCTL_ONE, }; =20 - if (write && !capable(CAP_SYS_ADMIN)) + if (SYSCTL_USER_TO_KERN(dir) && !capable(CAP_SYS_ADMIN)) return -EPERM; =20 mutex_lock(&static_key_mutex); val =3D static_key_enabled(key); - ret =3D proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos); - if (write && !ret) { + ret =3D proc_dointvec_minmax(&tmp, dir, buffer, lenp, ppos); + if (SYSCTL_USER_TO_KERN(dir) && !ret) { if (val) static_key_enable(key); else --=20 2.50.1 From nobody Sat Feb 7 23:39:41 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 929633064BA; Mon, 13 Oct 2025 13:25:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760361946; cv=none; b=H/D2UJXk0EERVwf03DNg+EqSqHzwXJZZo4mczifz0uMTI2D+A5nCxN1M8A5EtM+ViKLd2mAEwjnkTjp3DUADsb8J59rFcPhIQgAfQYMQRXFvFoHewhFO/VSDsWcykTtjhOEgB7y89SZuaH7l6Edu3DAEMiX9HkV92gXP1bXjGXo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760361946; c=relaxed/simple; bh=caF6LtqiOd2vBnpLGcm75cb9MaprTYO9NBhODSG8Pjs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=rvaE8Q3xuDi5+VpiIDRXChZhtc+T5tP7ntQ3dJGeSK4Aum8OInvRm99Ya1JxEoPCHDXCRCyodJyuxrPJLDzbjH+bifaeMlglIzvXIRt8T9SLeHkJMebUou5RWbq5Vx6WA4ydN/7YXsDSQV2jgIRo9TO3cdJk1tGByO10tUQ+TI8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ZqjsPkvF; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ZqjsPkvF" Received: by smtp.kernel.org (Postfix) with ESMTPS id 2DD96C2BC87; Mon, 13 Oct 2025 13:25:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760361946; bh=caF6LtqiOd2vBnpLGcm75cb9MaprTYO9NBhODSG8Pjs=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=ZqjsPkvF7NZXKG04vrFy/XkXu60etzOQnoF8mQ8xV9VKyByu+27Gn2J4fSiyCiF8M HAu9m0ALm+GBNykuvuy8kP3UuTuGCB1jIjkO4IQ3/b2CjOuQ2fRxtIiW/R7zhNYvtm a8e7OoK3qG6unKBk0vhqjzHx1f5hZM5y9Q+N58XLPnJhPTOs0Y38fSqz3muoNr2Iwu AZGUtKx+17AXi3l4qbdft4aouAyzLK35Gf+MqelrejpywvxupML6ExixCLI1haK3hb vaMEc5Y4VFDaf7IpWDTlVGzP4k9sjnyZUioT2Z9JbER6qXXhUy1fgojr4jNcJU75Jm hIym82XvOKqKQ== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 26599CCD18D; Mon, 13 Oct 2025 13:25:46 +0000 (UTC) From: Joel Granados Date: Mon, 13 Oct 2025 15:24:55 +0200 Subject: [PATCH 5/8] sysctl: Discriminate between kernel and user converter params Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251013-jag-sysctl_conv-v1-5-4dc35ceae733@kernel.org> References: <20251013-jag-sysctl_conv-v1-0-4dc35ceae733@kernel.org> In-Reply-To: <20251013-jag-sysctl_conv-v1-0-4dc35ceae733@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Kees Cook Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, Joel Granados X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=10487; i=joel.granados@kernel.org; h=from:subject:message-id; bh=caF6LtqiOd2vBnpLGcm75cb9MaprTYO9NBhODSG8Pjs=; b=owJ4nAHtARL+kA0DAAoBupfNUreWQU8ByyZiAGjs/dUeDnpsGyIH0+uQfHFCHVtxdMaukP4tN sX0f0nHgFfm64kBswQAAQoAHRYhBK5HCVcl5jElzssnkLqXzVK3lkFPBQJo7P3VAAoJELqXzVK3 lkFPO9cL/3dkThP9AoTTf0gZUBxLU+lUJJ6WhDLKY5zadECEF9vMGg6vlZHheD25w4l1LkuQ4YQ sPfjKROIFnVTDOzjNzMfs0nddP/dRVlI+HAII8+62gGdYR/lPevS34eBNgO5mxW+LHqQI7aPlxC 4PuMpWwH8WFfCj+m8+LfHnghd6U8fA+f6C6ew6aj1dALSD901QR5tImp18qRzw/ZdxhZ1eB7Ad4 g98zGlFXk7Mq1N+ze9uF8jWV3hznfElS1qe78hzPVrGvJTtATqBJacaOsKjmDbWZqzEgJTUlVNs arU+4nFLnwJ+3MjRudmlcNnv2kiZlPD9xXjCbDWokSvOr5Jvic/ESrEfD8j5NeAbsZaKrNs+bEl hZThSTDYFOb0rr9R3rmWFBv1aZSX1OCjMwqC01x5z7xbqHO9jbzN5M7cgGKOP0VAP3IOgSCBV+c /2wPZmRmf6ADyhV6TiIwplgea0ScBCJ7YoE3Zq9+bmiOkJBNdAr3usdxkpfSZumCuy+bEUfAbE8 iQ= X-Developer-Key: i=joel.granados@kernel.org; a=openpgp; fpr=F1F8E46D30F0F6C4A45FF4465895FAAC338C6E77 X-Endpoint-Received: by B4 Relay for joel.granados@kernel.org/default with auth_id=239 Rename converter parameter to indicate data flow direction: "lvalp" to "u_ptr" indicating a user space parsed value pointer. "valp" to "k_ptr" indicating a kernel storage value pointer. This facilitates the identification of discrepancies between direction (copy to kernel or copy to user space) and the modified variable. This is a preparation commit for when the converter functions are exposed to the rest of the kernel. Signed-off-by: Joel Granados --- kernel/sysctl.c | 118 ++++++++++++++++++++++++++++------------------------= ---- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 69148fe7359994b85c076b7b6750792b2d1c751e..2091d2396c83ac68d621b3d158c= e1c490c392c4b 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -368,44 +368,44 @@ static void proc_put_char(void **buf, size_t *size, c= har c) } } =20 -static int do_proc_dointvec_conv(bool *negp, unsigned long *lvalp, - int *valp, int dir, +static int do_proc_dointvec_conv(bool *negp, unsigned long *u_ptr, + int *k_ptr, int dir, const struct ctl_table *table) { if (SYSCTL_USER_TO_KERN(dir)) { if (*negp) { - if (*lvalp > (unsigned long) INT_MAX + 1) + if (*u_ptr > (unsigned long) INT_MAX + 1) return -EINVAL; - WRITE_ONCE(*valp, -*lvalp); + WRITE_ONCE(*k_ptr, -*u_ptr); } else { - if (*lvalp > (unsigned long) INT_MAX) + if (*u_ptr > (unsigned long) INT_MAX) return -EINVAL; - WRITE_ONCE(*valp, *lvalp); + WRITE_ONCE(*k_ptr, *u_ptr); } } else { - int val =3D READ_ONCE(*valp); + int val =3D READ_ONCE(*k_ptr); if (val < 0) { *negp =3D true; - *lvalp =3D -(unsigned long)val; + *u_ptr =3D -(unsigned long)val; } else { *negp =3D false; - *lvalp =3D (unsigned long)val; + *u_ptr =3D (unsigned long)val; } } return 0; } =20 -static int do_proc_douintvec_conv(unsigned long *lvalp, - unsigned int *valp, int dir, +static int do_proc_douintvec_conv(unsigned long *u_ptr, + unsigned int *k_ptr, int dir, const struct ctl_table *table) { if (SYSCTL_USER_TO_KERN(dir)) { - if (*lvalp > UINT_MAX) + if (*u_ptr > UINT_MAX) return -EINVAL; - WRITE_ONCE(*valp, *lvalp); + WRITE_ONCE(*k_ptr, *u_ptr); } else { - unsigned int val =3D READ_ONCE(*valp); - *lvalp =3D (unsigned long)val; + unsigned int val =3D READ_ONCE(*k_ptr); + *u_ptr =3D (unsigned long)val; } return 0; } @@ -415,7 +415,7 @@ static const char proc_wspace_sep[] =3D { ' ', '\t', '\= n' }; =20 static int do_proc_dointvec(const struct ctl_table *table, int dir, void *buffer, size_t *lenp, loff_t *ppos, - int (*conv)(bool *negp, unsigned long *lvalp, int *valp, + int (*conv)(bool *negp, unsigned long *u_ptr, int *k_ptr, int dir, const struct ctl_table *table)) { int *i, vleft, first =3D 1, err =3D 0; @@ -487,8 +487,8 @@ static int do_proc_dointvec(const struct ctl_table *tab= le, int dir, =20 static int do_proc_douintvec_w(const struct ctl_table *table, void *buffer, size_t *lenp, loff_t *ppos, - int (*conv)(unsigned long *lvalp, - unsigned int *valp, int dir, + int (*conv)(unsigned long *u_ptr, + unsigned int *k_ptr, int dir, const struct ctl_table *table)) { unsigned long lval; @@ -540,8 +540,8 @@ static int do_proc_douintvec_w(const struct ctl_table *= table, void *buffer, =20 static int do_proc_douintvec_r(const struct ctl_table *table, void *buffer, size_t *lenp, loff_t *ppos, - int (*conv)(unsigned long *lvalp, - unsigned int *valp, int dir, + int (*conv)(unsigned long *u_ptr, + unsigned int *k_ptr, int dir, const struct ctl_table *table)) { unsigned long lval; @@ -570,7 +570,7 @@ static int do_proc_douintvec_r(const struct ctl_table *= table, void *buffer, =20 int do_proc_douintvec(const struct ctl_table *table, int dir, void *buffer, size_t *lenp, loff_t *ppos, - int (*conv)(unsigned long *lvalp, unsigned int *valp, + int (*conv)(unsigned long *u_ptr, unsigned int *k_ptr, int dir, const struct ctl_table *table)) { unsigned int vleft; @@ -679,18 +679,18 @@ int proc_douintvec(const struct ctl_table *table, int= dir, void *buffer, do_proc_douintvec_conv); } =20 -static int do_proc_dointvec_minmax_conv(bool *negp, unsigned long *lvalp, - int *valp, int dir, +static int do_proc_dointvec_minmax_conv(bool *negp, unsigned long *u_ptr, + int *k_ptr, int dir, const struct ctl_table *table) { int tmp, ret, *min, *max; /* - * If writing, first do so via a temporary local int so we can - * bounds-check it before touching *valp. + * If writing to a kernel variable, first do so via a temporary + * local int so we can bounds-check it before touching *k_ptr. */ - int *ip =3D SYSCTL_USER_TO_KERN(dir) ? &tmp : valp; + int *ip =3D SYSCTL_USER_TO_KERN(dir) ? &tmp : k_ptr; =20 - ret =3D do_proc_dointvec_conv(negp, lvalp, ip, dir, table); + ret =3D do_proc_dointvec_conv(negp, u_ptr, ip, dir, table); if (ret) return ret; =20 @@ -699,7 +699,7 @@ static int do_proc_dointvec_minmax_conv(bool *negp, uns= igned long *lvalp, max =3D (int *) table->extra2; if ((min && *min > tmp) || (max && *max < tmp)) return -EINVAL; - WRITE_ONCE(*valp, tmp); + WRITE_ONCE(*k_ptr, tmp); } =20 return 0; @@ -729,16 +729,16 @@ int proc_dointvec_minmax(const struct ctl_table *tabl= e, int dir, do_proc_dointvec_minmax_conv); } =20 -static int do_proc_douintvec_minmax_conv(unsigned long *lvalp, - unsigned int *valp, int dir, +static int do_proc_douintvec_minmax_conv(unsigned long *u_ptr, + unsigned int *k_ptr, int dir, const struct ctl_table *table) { int ret; unsigned int tmp, *min, *max; /* When writing to the kernel use a temp local uint for bounds-checking */ - unsigned int *up =3D SYSCTL_USER_TO_KERN(dir) ? &tmp : valp; + unsigned int *up =3D SYSCTL_USER_TO_KERN(dir) ? &tmp : k_ptr; =20 - ret =3D do_proc_douintvec_conv(lvalp, up, dir, table); + ret =3D do_proc_douintvec_conv(u_ptr, up, dir, table); if (ret) return ret; =20 @@ -748,7 +748,7 @@ static int do_proc_douintvec_minmax_conv(unsigned long = *lvalp, if ((min && *min > tmp) || (max && *max < tmp)) return -ERANGE; =20 - WRITE_ONCE(*valp, tmp); + WRITE_ONCE(*k_ptr, tmp); } =20 return 0; @@ -953,19 +953,19 @@ int proc_doulongvec_ms_jiffies_minmax(const struct ct= l_table *table, int dir, } =20 =20 -static int do_proc_dointvec_jiffies_conv(bool *negp, unsigned long *lvalp, - int *valp, int dir, +static int do_proc_dointvec_jiffies_conv(bool *negp, unsigned long *u_ptr, + int *k_ptr, int dir, const struct ctl_table *table) { if (SYSCTL_USER_TO_KERN(dir)) { - if (*lvalp > INT_MAX / HZ) + if (*u_ptr > INT_MAX / HZ) return 1; if (*negp) - WRITE_ONCE(*valp, -*lvalp * HZ); + WRITE_ONCE(*k_ptr, -*u_ptr * HZ); else - WRITE_ONCE(*valp, *lvalp * HZ); + WRITE_ONCE(*k_ptr, *u_ptr * HZ); } else { - int val =3D READ_ONCE(*valp); + int val =3D READ_ONCE(*k_ptr); unsigned long lval; if (val < 0) { *negp =3D true; @@ -974,21 +974,21 @@ static int do_proc_dointvec_jiffies_conv(bool *negp, = unsigned long *lvalp, *negp =3D false; lval =3D (unsigned long)val; } - *lvalp =3D lval / HZ; + *u_ptr =3D lval / HZ; } return 0; } =20 -static int do_proc_dointvec_userhz_jiffies_conv(bool *negp, unsigned long = *lvalp, - int *valp, int dir, +static int do_proc_dointvec_userhz_jiffies_conv(bool *negp, unsigned long = *u_ptr, + int *k_ptr, int dir, const struct ctl_table *table) { if (SYSCTL_USER_TO_KERN(dir)) { - if (USER_HZ < HZ && *lvalp > (LONG_MAX / HZ) * USER_HZ) + if (USER_HZ < HZ && (LONG_MAX / HZ) * USER_HZ < *u_ptr) return 1; - *valp =3D clock_t_to_jiffies(*negp ? -*lvalp : *lvalp); + *k_ptr =3D clock_t_to_jiffies(*negp ? -*u_ptr : *u_ptr); } else { - int val =3D *valp; + int val =3D *k_ptr; unsigned long lval; if (val < 0) { *negp =3D true; @@ -997,23 +997,23 @@ static int do_proc_dointvec_userhz_jiffies_conv(bool = *negp, unsigned long *lvalp *negp =3D false; lval =3D (unsigned long)val; } - *lvalp =3D jiffies_to_clock_t(lval); + *u_ptr =3D jiffies_to_clock_t(lval); } return 0; } =20 -static int do_proc_dointvec_ms_jiffies_conv(bool *negp, unsigned long *lva= lp, - int *valp, int dir, +static int do_proc_dointvec_ms_jiffies_conv(bool *negp, unsigned long *u_p= tr, + int *k_ptr, int dir, const struct ctl_table *table) { if (SYSCTL_USER_TO_KERN(dir)) { - unsigned long jif =3D msecs_to_jiffies(*negp ? -*lvalp : *lvalp); + unsigned long jif =3D msecs_to_jiffies(*negp ? -*u_ptr : *u_ptr); =20 if (jif > INT_MAX) return 1; - WRITE_ONCE(*valp, (int)jif); + WRITE_ONCE(*k_ptr, (int)jif); } else { - int val =3D READ_ONCE(*valp); + int val =3D READ_ONCE(*k_ptr); unsigned long lval; if (val < 0) { *negp =3D true; @@ -1022,23 +1022,23 @@ static int do_proc_dointvec_ms_jiffies_conv(bool *n= egp, unsigned long *lvalp, *negp =3D false; lval =3D (unsigned long)val; } - *lvalp =3D jiffies_to_msecs(lval); + *u_ptr =3D jiffies_to_msecs(lval); } return 0; } =20 -static int do_proc_dointvec_ms_jiffies_minmax_conv(bool *negp, unsigned lo= ng *lvalp, - int *valp, int dir, +static int do_proc_dointvec_ms_jiffies_minmax_conv(bool *negp, unsigned lo= ng *u_ptr, + int *k_ptr, int dir, const struct ctl_table *table) { int tmp, ret, *min, *max; /* - * If writing, first do so via a temporary local int so we can - * bounds-check it before touching *valp. + * If writing to a kernel var, first do so via a temporary local + * int so we can bounds-check it before touching *k_ptr. */ - int *ip =3D SYSCTL_USER_TO_KERN(dir) ? &tmp : valp; + int *ip =3D SYSCTL_USER_TO_KERN(dir) ? &tmp : k_ptr; =20 - ret =3D do_proc_dointvec_ms_jiffies_conv(negp, lvalp, ip, dir, table); + ret =3D do_proc_dointvec_ms_jiffies_conv(negp, u_ptr, ip, dir, table); if (ret) return ret; =20 @@ -1047,7 +1047,7 @@ static int do_proc_dointvec_ms_jiffies_minmax_conv(bo= ol *negp, unsigned long *lv max =3D (int *) table->extra2; if ((min && *min > tmp) || (max && *max < tmp)) return -EINVAL; - *valp =3D tmp; + *k_ptr =3D tmp; } return 0; } --=20 2.50.1 From nobody Sat Feb 7 23:39:41 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9289C3064B8; Mon, 13 Oct 2025 13:25:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760361946; cv=none; b=loHT3dPsS5tvhrGyPGJxB8gmUgTznKIZJkBNw7nBBonET91WYizy6HNxO/Kbj3AHM7C+g+UuTlihJhnxx/IzoTbaCluuxqrQs9q4enVJXEofQ7cA6l+n65soyZRZGV6DMSWsfRhW25L2juJPFhaGKZi8ZyKKUEcGI3MQw5XmEMw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760361946; c=relaxed/simple; bh=GZxezoIkNwtwUcjJV0zafwxh2Mgp77M2WJpzEUZyXTw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=YwTCXbLMiG0XQYatmUqYIWG9jrLGNf5LOxoZ2CH7r0m5ZBU+Czs/wSae+LiqAha0g1mD2fza3AyUme09ERAHuZ76eZIz4fQLKBr6mYPM9rMDS4OHu+Ag0Y7fnJh2rnE66quiQSIEe/3t9id/tviEVoCe/djeOwk05pd25pBo5c8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=A42pY3nu; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="A42pY3nu" Received: by smtp.kernel.org (Postfix) with ESMTPS id 3B6D9C4AF0F; Mon, 13 Oct 2025 13:25:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760361946; bh=GZxezoIkNwtwUcjJV0zafwxh2Mgp77M2WJpzEUZyXTw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=A42pY3nuW2rf41L7M965hz9nx5OcefhDY3GmuII++y6ifAMpxvEA+evp5/KdJ5sYU 41880VRamgDWy7ijUpNfUvJ9bfjb2vZVuOp3VkRn4ztDmGT2elAAcxzJ4Xnr7k4/hE WVc1p2PNG4YfgSN014J6YBVJT9INifeRQlhInQP9OEtb0V2TQQ/zhkKTdmZFk6rBjZ VuElQmCG5FMRcc0EOevbjOd8n8rBf9/Nop8bSU1Dgv7rVr3IBP62EJMvTGswGU3Yyt 8AoCJheQMlxOreSjI1u8Q/hoRj0MZiSZG7RHA9HAphAxt9cTSf9u4NjJygmft9cJ4o G22XuT6RPWsDQ== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 32606CCD18E; Mon, 13 Oct 2025 13:25:46 +0000 (UTC) From: Joel Granados Date: Mon, 13 Oct 2025 15:24:56 +0200 Subject: [PATCH 6/8] sysctl: Create converter functions with two new macros Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251013-jag-sysctl_conv-v1-6-4dc35ceae733@kernel.org> References: <20251013-jag-sysctl_conv-v1-0-4dc35ceae733@kernel.org> In-Reply-To: <20251013-jag-sysctl_conv-v1-0-4dc35ceae733@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Kees Cook Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, Joel Granados X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=6511; i=joel.granados@kernel.org; h=from:subject:message-id; bh=GZxezoIkNwtwUcjJV0zafwxh2Mgp77M2WJpzEUZyXTw=; b=owJ4nAHtARL+kA0DAAoBupfNUreWQU8ByyZiAGjs/dZC3kufkk8orzLfy7bRcGMF98YLAho53 x58t6KK+A06Q4kBswQAAQoAHRYhBK5HCVcl5jElzssnkLqXzVK3lkFPBQJo7P3WAAoJELqXzVK3 lkFPjFwL/2xX6bnDW0Hm5sw8n9KH8UTqwpqSY4bjUXrWPWdv/yFmFJur/1NfFTfi118ziuFL7Mq fgzu34VoHYI9JUkpGwg4DTnPnwkAuXpeY1bSWhEVzm8dNfiq2lfBq2ZMwn+bTvXADPCzjjzH3vo uVgtPvJzNGcldTTdeZHkzmjUz/eRFzsXEAk227ggobNnNsCOtclivbDxQ8xOeUlReO6BAshCTws PKA2sVCq12wGz7MEdYS/X+L51O+GulGm8JJYSsI/Q1vaMgowfVrGwhGe/vpuo9Lc+8A42DyrPi/ OchULIIMOZC6sU1L23jc7jZMnlhOC0n00scRFxrtLUWaMlomE900k/Z+lUNo5RReTKdXI1Wq6dd C6fOJqZNxSYutinQzgo2cznC69yOsdL7hy4FfNzSIIPkeiuY1Lv0e6EHPP+2D7h7oEHY25AxF6A VnWUG82YhqjWXPO3qN+FxnYhyZxyTlSuhUg6RDZyHV7msXZ3Qfc3yVV29jnsQmETl+NQ7tI4a36 7A= X-Developer-Key: i=joel.granados@kernel.org; a=openpgp; fpr=F1F8E46D30F0F6C4A45FF4465895FAAC338C6E77 X-Endpoint-Received: by B4 Relay for joel.granados@kernel.org/default with auth_id=239 Eight converter functions are created using two new macros (SYSCTL_USER_TO_KERN_INT_CONV & SYSCTL_KERN_TO_USER_INT_CONV); they are called from four pre-existing converter functions: do_proc_dointvec_conv and do_proc_dointvec{,_userhz,_ms}_jiffies_conv. The function names generated by the macros are differentiated by a string suffix passed as the first macro argument. The SYSCTL_USER_TO_KERN_INT_CONV macro first executes the u_ptr_op operation, then checks for overflow, assigns sign (-, +) and finally writes to the kernel var with WRITE_ONCE; it always returns an -EINVAL when an overflow is detected. The SYSCTL_KERN_TO_USER_INT_CONV uses READ_ONCE, casts to unsigned long, then executes the k_ptr_op before assigning the value to the user space buffer. The overflow check is always done against MAX_INT after applying {k,u}_ptr_op. This approach avoids rounding or precision errors that might occur when using the inverse operations. Signed-off-by: Joel Granados --- kernel/sysctl.c | 131 ++++++++++++++++++++++++++--------------------------= ---- 1 file changed, 61 insertions(+), 70 deletions(-) diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 2091d2396c83ac68d621b3d158ce1c490c392c4b..f47bb8af33fb1d2d1a2a7c13d7c= a093af82c6400 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -368,31 +368,65 @@ static void proc_put_char(void **buf, size_t *size, c= har c) } } =20 +#define SYSCTL_USER_TO_KERN_INT_CONV(name, u_ptr_op) \ +int sysctl_user_to_kern_int_conv##name(const bool *negp, \ + const unsigned long *u_ptr,\ + int *k_ptr) \ +{ \ + unsigned long u =3D u_ptr_op(*u_ptr); \ + if (*negp) { \ + if (u > (unsigned long) INT_MAX + 1) \ + return -EINVAL; \ + WRITE_ONCE(*k_ptr, -u); \ + } else { \ + if (u > (unsigned long) INT_MAX) \ + return -EINVAL; \ + WRITE_ONCE(*k_ptr, u); \ + } \ + return 0; \ +} + +#define SYSCTL_KERN_TO_USER_INT_CONV(name, k_ptr_op) \ +int sysctl_kern_to_user_int_conv##name(bool *negp, \ + unsigned long *u_ptr, \ + const int *k_ptr) \ +{ \ + int val =3D READ_ONCE(*k_ptr); \ + if (val < 0) { \ + *negp =3D true; \ + *u_ptr =3D -k_ptr_op((unsigned long)val); \ + } else { \ + *negp =3D false; \ + *u_ptr =3D k_ptr_op((unsigned long)val); \ + } \ + return 0; \ +} + +#define SYSCTL_CONV_IDENTITY(val) val +#define SYSCTL_CONV_MULT_HZ(val) ((val) * HZ) +#define SYSCTL_CONV_DIV_HZ(val) ((val) / HZ) + +static SYSCTL_USER_TO_KERN_INT_CONV(, SYSCTL_CONV_IDENTITY) +static SYSCTL_KERN_TO_USER_INT_CONV(, SYSCTL_CONV_IDENTITY) + +static SYSCTL_USER_TO_KERN_INT_CONV(_hz, SYSCTL_CONV_MULT_HZ) +static SYSCTL_KERN_TO_USER_INT_CONV(_hz, SYSCTL_CONV_DIV_HZ) + +static SYSCTL_USER_TO_KERN_INT_CONV(_userhz, clock_t_to_jiffies) +static SYSCTL_KERN_TO_USER_INT_CONV(_userhz, jiffies_to_clock_t) + +static SYSCTL_USER_TO_KERN_INT_CONV(_ms, msecs_to_jiffies) +static SYSCTL_KERN_TO_USER_INT_CONV(_ms, jiffies_to_msecs) + static int do_proc_dointvec_conv(bool *negp, unsigned long *u_ptr, int *k_ptr, int dir, const struct ctl_table *table) { if (SYSCTL_USER_TO_KERN(dir)) { - if (*negp) { - if (*u_ptr > (unsigned long) INT_MAX + 1) - return -EINVAL; - WRITE_ONCE(*k_ptr, -*u_ptr); - } else { - if (*u_ptr > (unsigned long) INT_MAX) - return -EINVAL; - WRITE_ONCE(*k_ptr, *u_ptr); - } - } else { - int val =3D READ_ONCE(*k_ptr); - if (val < 0) { - *negp =3D true; - *u_ptr =3D -(unsigned long)val; - } else { - *negp =3D false; - *u_ptr =3D (unsigned long)val; - } + return sysctl_user_to_kern_int_conv(negp, u_ptr, k_ptr); } - return 0; + + return sysctl_kern_to_user_int_conv(negp, u_ptr, k_ptr); } =20 static int do_proc_douintvec_conv(unsigned long *u_ptr, @@ -952,31 +986,14 @@ int proc_doulongvec_ms_jiffies_minmax(const struct ct= l_table *table, int dir, lenp, ppos, HZ, 1000l); } =20 - static int do_proc_dointvec_jiffies_conv(bool *negp, unsigned long *u_ptr, int *k_ptr, int dir, const struct ctl_table *table) { if (SYSCTL_USER_TO_KERN(dir)) { - if (*u_ptr > INT_MAX / HZ) - return 1; - if (*negp) - WRITE_ONCE(*k_ptr, -*u_ptr * HZ); - else - WRITE_ONCE(*k_ptr, *u_ptr * HZ); - } else { - int val =3D READ_ONCE(*k_ptr); - unsigned long lval; - if (val < 0) { - *negp =3D true; - lval =3D -(unsigned long)val; - } else { - *negp =3D false; - lval =3D (unsigned long)val; - } - *u_ptr =3D lval / HZ; + return sysctl_user_to_kern_int_conv_hz(negp, u_ptr, k_ptr); } - return 0; + return sysctl_kern_to_user_int_conv_hz(negp, u_ptr, k_ptr); } =20 static int do_proc_dointvec_userhz_jiffies_conv(bool *negp, unsigned long = *u_ptr, @@ -984,22 +1001,11 @@ static int do_proc_dointvec_userhz_jiffies_conv(bool= *negp, unsigned long *u_ptr const struct ctl_table *table) { if (SYSCTL_USER_TO_KERN(dir)) { - if (USER_HZ < HZ && (LONG_MAX / HZ) * USER_HZ < *u_ptr) - return 1; - *k_ptr =3D clock_t_to_jiffies(*negp ? -*u_ptr : *u_ptr); - } else { - int val =3D *k_ptr; - unsigned long lval; - if (val < 0) { - *negp =3D true; - lval =3D -(unsigned long)val; - } else { - *negp =3D false; - lval =3D (unsigned long)val; - } - *u_ptr =3D jiffies_to_clock_t(lval); + if (USER_HZ < HZ) + return -EINVAL; + return sysctl_user_to_kern_int_conv_userhz(negp, u_ptr, k_ptr); } - return 0; + return sysctl_kern_to_user_int_conv_userhz(negp, u_ptr, k_ptr); } =20 static int do_proc_dointvec_ms_jiffies_conv(bool *negp, unsigned long *u_p= tr, @@ -1007,24 +1013,9 @@ static int do_proc_dointvec_ms_jiffies_conv(bool *ne= gp, unsigned long *u_ptr, const struct ctl_table *table) { if (SYSCTL_USER_TO_KERN(dir)) { - unsigned long jif =3D msecs_to_jiffies(*negp ? -*u_ptr : *u_ptr); - - if (jif > INT_MAX) - return 1; - WRITE_ONCE(*k_ptr, (int)jif); - } else { - int val =3D READ_ONCE(*k_ptr); - unsigned long lval; - if (val < 0) { - *negp =3D true; - lval =3D -(unsigned long)val; - } else { - *negp =3D false; - lval =3D (unsigned long)val; - } - *u_ptr =3D jiffies_to_msecs(lval); + return sysctl_user_to_kern_int_conv_ms(negp, u_ptr, k_ptr); } - return 0; + return sysctl_kern_to_user_int_conv_ms(negp, u_ptr, k_ptr); } =20 static int do_proc_dointvec_ms_jiffies_minmax_conv(bool *negp, unsigned lo= ng *u_ptr, --=20 2.50.1 From nobody Sat Feb 7 23:39:41 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C9B7F307AD0; Mon, 13 Oct 2025 13:25:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760361949; cv=none; b=OJk0QV5zyuW5PDTA/V5IX4ZgXwifYAlrfqB37idb8Tvxz7h+ykHcRWhdGH2g4VObJiOmpmQwENhMz3LcC2jn1fmT/RvpkruR64x2+yCbWpM2emxE2ngIu2yIl3qJkFcuf+9uV8YiLBGTSmGR3PPYzgYZRTMmWejBi6cuRCLJvB0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760361949; c=relaxed/simple; bh=KD+2NkFaHlPghXWKYGaZ79Eguljp8JHhe47tIb8ZfcQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=aSv6YInVgv7XLFHSzhz0dS1FjZ/YanvdZxM4jtaWl7AHUhJG+mPAouoJfgTyDS+SKqYPN+MllHneMHtKSdFmSLlYQAdoHlLYZsJsMO1vG+Kmdz6PV7x8/77ScYsFtiUgMNZ9kOmpMh4migB6bajH8UNi5g6Gl/C0TG6cZpGRwko= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=UeDK6DC0; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="UeDK6DC0" Received: by smtp.kernel.org (Postfix) with ESMTPS id 489E8C2BCB3; Mon, 13 Oct 2025 13:25:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760361946; bh=KD+2NkFaHlPghXWKYGaZ79Eguljp8JHhe47tIb8ZfcQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=UeDK6DC0DyPaw3I6Hdo/23Q1HeGZDKuzanQsJXMe15mONoT2vq10yxaUovt5Hv4sz F+iZLqQ8VKifF+OXv0ESHIQYz5w/OesfB8KAKobowqlk5RaLHobT50CZ28qhgFra9O 9SPlRmJ54P0oFwqRSUF6l+WF8sRmeHR9egFYhQXBhTA+wPccgIv4r8hzDNSeic50Hf 95q+7hyFQcno1FKnpGJQ9BfpgKI/jUETr5eD2dZpxH+UzsvrXAHazkU/qMK4BFDODx clPxZA186oNKodgEkWXdoE7nlAPnHrKANn9GET5OWxa7yizmMfm//0apiwggDEfiWW RcX7UIhRN0IQg== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3F568CCD183; Mon, 13 Oct 2025 13:25:46 +0000 (UTC) From: Joel Granados Date: Mon, 13 Oct 2025 15:24:57 +0200 Subject: [PATCH 7/8] sysctl: Create integer converters with one macro Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251013-jag-sysctl_conv-v1-7-4dc35ceae733@kernel.org> References: <20251013-jag-sysctl_conv-v1-0-4dc35ceae733@kernel.org> In-Reply-To: <20251013-jag-sysctl_conv-v1-0-4dc35ceae733@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Kees Cook Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, Joel Granados X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=5636; i=joel.granados@kernel.org; h=from:subject:message-id; bh=KD+2NkFaHlPghXWKYGaZ79Eguljp8JHhe47tIb8ZfcQ=; b=owJ4nAHtARL+kA0DAAoBupfNUreWQU8ByyZiAGjs/dZ4z6dKRy2SnciVVaoN23htdr/J/6Gjp G+LGXNRlUS+zYkBswQAAQoAHRYhBK5HCVcl5jElzssnkLqXzVK3lkFPBQJo7P3WAAoJELqXzVK3 lkFP2hoMAIfK8UBYrYgEhDWMM1XXpWxQzBIvdpBOZfKVhIuEfKeJ4dJiq4gCeVX2J2xTWkqtol1 HhOmrSO61bRFsrLpqzd9QU6Eg/tXW6qawjjhvnXuKMlM5t1+NjxgGrOOWcI0sKlqluAwvlnZsgI Pr+a7XjVRHCHOP/XsvWZhImvqpemjvCz1Zq2+1P0TP3IBOJf8fEvnrPyWj5wBx8Z5y7TxjIoUi4 ev/Uu1U+XJ2uCpiNkBAcwZgc+1E9EmkmpNq0J68LIbGgwgrO1fOm0T/ou8pngzWO+MQIxmpkcYv VFQHQYuKitc3bo7ATbCJZO60CVP4lCyExs9rDwJ1+oyTuNzGbSKEdFPS6E3y6H3n1l2g7vpvmdf 59XkG879Q+sBVSKJlnn+6U/k2l4YW9G2MwFnoVFxoCsolEEF5H2uYDNjtFJykYJuW58r1IxMGK3 yyDKHMRonXn23Qe85STRlDUGfwwKBeb+C6GMBtbaxwaqQnkzJBY4l4W8Q0Mj9kZ9TR9NEfovxk8 Y4= X-Developer-Key: i=joel.granados@kernel.org; a=openpgp; fpr=F1F8E46D30F0F6C4A45FF4465895FAAC338C6E77 X-Endpoint-Received: by B4 Relay for joel.granados@kernel.org/default with auth_id=239 New SYSCTL_INT_CONV_CUSTOM macro creates "bi-directional" converters from a user-to-kernel and a kernel-to-user functions. Replace integer versions of do_proc_*_conv functions with the ones from the new macro. Rename "_dointvec_" to just "_int_" as these converters are not applied to vectors and the "do" is already in the name. Move the USER_HZ validation directly into proc_dointvec_userhz_jiffies() Signed-off-by: Joel Granados --- kernel/sysctl.c | 72 ++++++++++++++++++++---------------------------------= ---- 1 file changed, 25 insertions(+), 47 deletions(-) diff --git a/kernel/sysctl.c b/kernel/sysctl.c index f47bb8af33fb1d2d1a2a7c13d7ca093af82c6400..e7dc4b79e93ea9ab929ce046514= 3aed74be444e5 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -418,17 +418,25 @@ static SYSCTL_KERN_TO_USER_INT_CONV(_userhz, jiffies_= to_clock_t) static SYSCTL_USER_TO_KERN_INT_CONV(_ms, msecs_to_jiffies) static SYSCTL_KERN_TO_USER_INT_CONV(_ms, jiffies_to_msecs) =20 -static int do_proc_dointvec_conv(bool *negp, unsigned long *u_ptr, - int *k_ptr, int dir, - const struct ctl_table *table) -{ - if (SYSCTL_USER_TO_KERN(dir)) { - return sysctl_user_to_kern_int_conv(negp, u_ptr, k_ptr); - } - - return sysctl_kern_to_user_int_conv(negp, u_ptr, k_ptr); +#define SYSCTL_INT_CONV_CUSTOM(name, user_to_kern, kern_to_user) \ +int do_proc_int_conv##name(bool *negp, unsigned long *u_ptr, int *k_ptr,\ + int dir, const struct ctl_table *table) \ +{ \ + if (SYSCTL_USER_TO_KERN(dir)) \ + return user_to_kern(negp, u_ptr, k_ptr); \ + return kern_to_user(negp, u_ptr, k_ptr); \ } =20 +static SYSCTL_INT_CONV_CUSTOM(, sysctl_user_to_kern_int_conv, + sysctl_kern_to_user_int_conv) +static SYSCTL_INT_CONV_CUSTOM(_jiffies, sysctl_user_to_kern_int_conv_hz, + sysctl_kern_to_user_int_conv_hz) +static SYSCTL_INT_CONV_CUSTOM(_userhz_jiffies, + sysctl_user_to_kern_int_conv_userhz, + sysctl_kern_to_user_int_conv_userhz) +static SYSCTL_INT_CONV_CUSTOM(_ms_jiffies, sysctl_user_to_kern_int_conv_ms, + sysctl_kern_to_user_int_conv_ms) + static int do_proc_douintvec_conv(unsigned long *u_ptr, unsigned int *k_ptr, int dir, const struct ctl_table *table) @@ -467,7 +475,7 @@ static int do_proc_dointvec(const struct ctl_table *tab= le, int dir, left =3D *lenp; =20 if (!conv) - conv =3D do_proc_dointvec_conv; + conv =3D do_proc_int_conv; =20 if (SYSCTL_USER_TO_KERN(dir)) { if (proc_first_pos_non_zero_ignore(ppos, table)) @@ -724,7 +732,7 @@ static int do_proc_dointvec_minmax_conv(bool *negp, uns= igned long *u_ptr, */ int *ip =3D SYSCTL_USER_TO_KERN(dir) ? &tmp : k_ptr; =20 - ret =3D do_proc_dointvec_conv(negp, u_ptr, ip, dir, table); + ret =3D do_proc_int_conv(negp, u_ptr, ip, dir, table); if (ret) return ret; =20 @@ -986,38 +994,6 @@ int proc_doulongvec_ms_jiffies_minmax(const struct ctl= _table *table, int dir, lenp, ppos, HZ, 1000l); } =20 -static int do_proc_dointvec_jiffies_conv(bool *negp, unsigned long *u_ptr, - int *k_ptr, int dir, - const struct ctl_table *table) -{ - if (SYSCTL_USER_TO_KERN(dir)) { - return sysctl_user_to_kern_int_conv_hz(negp, u_ptr, k_ptr); - } - return sysctl_kern_to_user_int_conv_hz(negp, u_ptr, k_ptr); -} - -static int do_proc_dointvec_userhz_jiffies_conv(bool *negp, unsigned long = *u_ptr, - int *k_ptr, int dir, - const struct ctl_table *table) -{ - if (SYSCTL_USER_TO_KERN(dir)) { - if (USER_HZ < HZ) - return -EINVAL; - return sysctl_user_to_kern_int_conv_userhz(negp, u_ptr, k_ptr); - } - return sysctl_kern_to_user_int_conv_userhz(negp, u_ptr, k_ptr); -} - -static int do_proc_dointvec_ms_jiffies_conv(bool *negp, unsigned long *u_p= tr, - int *k_ptr, int dir, - const struct ctl_table *table) -{ - if (SYSCTL_USER_TO_KERN(dir)) { - return sysctl_user_to_kern_int_conv_ms(negp, u_ptr, k_ptr); - } - return sysctl_kern_to_user_int_conv_ms(negp, u_ptr, k_ptr); -} - static int do_proc_dointvec_ms_jiffies_minmax_conv(bool *negp, unsigned lo= ng *u_ptr, int *k_ptr, int dir, const struct ctl_table *table) @@ -1029,7 +1005,7 @@ static int do_proc_dointvec_ms_jiffies_minmax_conv(bo= ol *negp, unsigned long *u_ */ int *ip =3D SYSCTL_USER_TO_KERN(dir) ? &tmp : k_ptr; =20 - ret =3D do_proc_dointvec_ms_jiffies_conv(negp, u_ptr, ip, dir, table); + ret =3D do_proc_int_conv_ms_jiffies(negp, u_ptr, ip, dir, table); if (ret) return ret; =20 @@ -1062,7 +1038,7 @@ int proc_dointvec_jiffies(const struct ctl_table *tab= le, int dir, void *buffer, size_t *lenp, loff_t *ppos) { return do_proc_dointvec(table, dir, buffer, lenp, ppos, - do_proc_dointvec_jiffies_conv); + do_proc_int_conv_jiffies); } =20 int proc_dointvec_ms_jiffies_minmax(const struct ctl_table *table, int dir, @@ -1090,8 +1066,10 @@ int proc_dointvec_ms_jiffies_minmax(const struct ctl= _table *table, int dir, int proc_dointvec_userhz_jiffies(const struct ctl_table *table, int dir, void *buffer, size_t *lenp, loff_t *ppos) { + if (USER_HZ < HZ) + return -EINVAL; return do_proc_dointvec(table, dir, buffer, lenp, ppos, - do_proc_dointvec_userhz_jiffies_conv); + do_proc_int_conv_userhz_jiffies); } =20 /** @@ -1113,7 +1091,7 @@ int proc_dointvec_ms_jiffies(const struct ctl_table *= table, int dir, void *buffe size_t *lenp, loff_t *ppos) { return do_proc_dointvec(table, dir, buffer, lenp, ppos, - do_proc_dointvec_ms_jiffies_conv); + do_proc_int_conv_ms_jiffies); } =20 /** --=20 2.50.1 From nobody Sat Feb 7 23:39:41 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7F6DD3064B5; Mon, 13 Oct 2025 13:25:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760361946; cv=none; b=XipFsE8r+9AwWiQ/CZ6EuTxo4U8b2C1nbUhRMVMjo1OGdz6H45qdxo1MdUA2ZDokiJdsj4A+CWQpK1b2Em8NkwmCGadFOiu7v5WDQX0uarZ9G1atVYIWUFETRp2A4KM/Hj4GDLFU41m3T0fXyMYrtlLdkjtQLhXKR3Od7gcRmmE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760361946; c=relaxed/simple; bh=WFmYwNqRtEEV71HErtXjnELu0hh+bKYykNpfWVGpcO8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=II5nzJo5TebGNhu5FYKi8wfe3al+gjK9CIgWlbzXGRF3LsFkYhfjELhsScse27mueGWmy92t4t9tVUECbPPNvpDplOUnRs2mnT/jf+HlJN64YE0R8l+74KkYYnUAgA//l9nOkfHqTUKfvesc8CumSiSbS8MhGbS/Tn/OWSaMtiE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=YZNHLTiq; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="YZNHLTiq" Received: by smtp.kernel.org (Postfix) with ESMTPS id 55C98C19424; Mon, 13 Oct 2025 13:25:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760361946; bh=WFmYwNqRtEEV71HErtXjnELu0hh+bKYykNpfWVGpcO8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=YZNHLTiqwdKK3nithG9TiIiULn/p8sdDGbmWMp1YV2/hgLPwSQStiyW1vl5TWpJNF mtJpo5bbq6pZwKkSx9FnWNZAmQZWqMm3bbve3Y/bQazXWSPsQnIcXQGPDVJDUqidpG +q2C/PIRnYuOizFdGDd0xNyoXzJ2GWXEjG9UZEjuOMdUud2rGchSSMUm/E8xchaP3j mX571tNiaWVJg2Og/u4JQRqxobXVLlxOi9P0o81o0Rryo0xNGGojNKr+BkqrBTrE58 YfAZMFa6BEUW40G03sXHfsISEL6DwoMxt3sjFnfqSVBUQzzLbwhlUnoWfK4DE/3buV qOn1dnOVfc2vg== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4BC6FCCD190; Mon, 13 Oct 2025 13:25:46 +0000 (UTC) From: Joel Granados Date: Mon, 13 Oct 2025 15:24:58 +0200 Subject: [PATCH 8/8] sysctl: Add optional range checking to SYSCTL_INT_CONV_CUSTOM Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251013-jag-sysctl_conv-v1-8-4dc35ceae733@kernel.org> References: <20251013-jag-sysctl_conv-v1-0-4dc35ceae733@kernel.org> In-Reply-To: <20251013-jag-sysctl_conv-v1-0-4dc35ceae733@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Kees Cook Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, Joel Granados X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=6108; i=joel.granados@kernel.org; h=from:subject:message-id; bh=WFmYwNqRtEEV71HErtXjnELu0hh+bKYykNpfWVGpcO8=; b=owJ4nAHtARL+kA0DAAoBupfNUreWQU8ByyZiAGjs/df2qPSmaNQsmWp35kE3R6r63EL/tLd3D jxjLSoMwd++h4kBswQAAQoAHRYhBK5HCVcl5jElzssnkLqXzVK3lkFPBQJo7P3XAAoJELqXzVK3 lkFPJi8MAIsUkiq0T8pTVzJVdJ/BJTkqWnf5Um2Na/zccXAaszr1sCjtpLDsIvXs+lUxaBiARZE P4eq/fFNTFmaT4sq4jYdC3EPtORgZ61iyjZzGI3553loRzVKs46qzAs3U9XToNARkYbLxaEpNg8 WLzOrqMC0opJtspwPgs2utluKOs9GALRizcUaGF32CatM8H02sG4G3wF3Fz3eY1bYTe6TvtvYKc 96LMMkjvkG6mPQ3DGXyq5JYJ8ZHyDfv+JgIIHIuGzEKnhB/Zpu0DR2AJGLQOUnmMXJvwA/LNqyt 74asicQIoxXhTItx6XsxZOoQyegEakioEs033CKM80g4mcMuOpwwU5cp+hT3OtNIGMcOFjg6SAL vC+LrNATNM6heKtwR6O9Ps4v+kKafUcVoPvsqYwSPhiG+BFcGp+sxdx55R9x7WXXbKljQryrr1r DQSqbHwsg+grMOmu+zyAfPiNyBTJILnJM+CsNIgzRfUe3ed6Yx6Qnik6BNyUkxpL5FrNrOgWz57 Ro= X-Developer-Key: i=joel.granados@kernel.org; a=openpgp; fpr=F1F8E46D30F0F6C4A45FF4465895FAAC338C6E77 X-Endpoint-Received: by B4 Relay for joel.granados@kernel.org/default with auth_id=239 Extend the SYSCTL_INT_CONV_CUSTOM macro with a k_ptr_range_check parameter to conditionally generate range validation code. When enabled, validation is done against table->extra1 (min) and table->extra2 (max) bounds before assignment. Add base minmax and ms_jiffies_minmax converter instances that utilize the range checking functionality. Signed-off-by: Joel Granados --- kernel/sysctl.c | 106 +++++++++++++++++++++-------------------------------= ---- 1 file changed, 40 insertions(+), 66 deletions(-) diff --git a/kernel/sysctl.c b/kernel/sysctl.c index e7dc4b79e93ea9ab929ce0465143aed74be444e5..60f7618083516a24530f46f6eab= ccd108e90c74f 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -402,6 +402,34 @@ int sysctl_kern_to_user_int_conv##name(bool *negp, \ return 0; \ } =20 +/** + * To range check on a converted value, use a temp k_ptr + * When checking range, value should be within (tbl->extra1, tbl->extra2) + */ +#define SYSCTL_INT_CONV_CUSTOM(name, user_to_kern, kern_to_user, \ + k_ptr_range_check) \ +int do_proc_int_conv##name(bool *negp, unsigned long *u_ptr, int *k_ptr,\ + int dir, const struct ctl_table *tbl) \ +{ \ + if (SYSCTL_KERN_TO_USER(dir)) \ + return kern_to_user(negp, u_ptr, k_ptr); \ + \ + if (k_ptr_range_check) { \ + int tmp_k, ret; \ + if (!tbl) \ + return -EINVAL; \ + ret =3D user_to_kern(negp, u_ptr, &tmp_k); \ + if (ret) \ + return ret; \ + if ((tbl->extra1 && *(int *)tbl->extra1 > tmp_k) || \ + (tbl->extra2 && *(int *)tbl->extra2 < tmp_k)) \ + return -EINVAL; \ + WRITE_ONCE(*k_ptr, tmp_k); \ + } else \ + return user_to_kern(negp, u_ptr, k_ptr); \ + return 0; \ +} + #define SYSCTL_CONV_IDENTITY(val) val #define SYSCTL_CONV_MULT_HZ(val) ((val) * HZ) #define SYSCTL_CONV_DIV_HZ(val) ((val) / HZ) @@ -418,24 +446,21 @@ static SYSCTL_KERN_TO_USER_INT_CONV(_userhz, jiffies_= to_clock_t) static SYSCTL_USER_TO_KERN_INT_CONV(_ms, msecs_to_jiffies) static SYSCTL_KERN_TO_USER_INT_CONV(_ms, jiffies_to_msecs) =20 -#define SYSCTL_INT_CONV_CUSTOM(name, user_to_kern, kern_to_user) \ -int do_proc_int_conv##name(bool *negp, unsigned long *u_ptr, int *k_ptr,\ - int dir, const struct ctl_table *table) \ -{ \ - if (SYSCTL_USER_TO_KERN(dir)) \ - return user_to_kern(negp, u_ptr, k_ptr); \ - return kern_to_user(negp, u_ptr, k_ptr); \ -} - static SYSCTL_INT_CONV_CUSTOM(, sysctl_user_to_kern_int_conv, - sysctl_kern_to_user_int_conv) + sysctl_kern_to_user_int_conv, false) static SYSCTL_INT_CONV_CUSTOM(_jiffies, sysctl_user_to_kern_int_conv_hz, - sysctl_kern_to_user_int_conv_hz) + sysctl_kern_to_user_int_conv_hz, false) static SYSCTL_INT_CONV_CUSTOM(_userhz_jiffies, sysctl_user_to_kern_int_conv_userhz, - sysctl_kern_to_user_int_conv_userhz) + sysctl_kern_to_user_int_conv_userhz, false) static SYSCTL_INT_CONV_CUSTOM(_ms_jiffies, sysctl_user_to_kern_int_conv_ms, - sysctl_kern_to_user_int_conv_ms) + sysctl_kern_to_user_int_conv_ms, false) + +static SYSCTL_INT_CONV_CUSTOM(_minmax, sysctl_user_to_kern_int_conv, + sysctl_kern_to_user_int_conv, true) +static SYSCTL_INT_CONV_CUSTOM(_ms_jiffies_minmax, + sysctl_user_to_kern_int_conv_ms, + sysctl_kern_to_user_int_conv_ms, true) =20 static int do_proc_douintvec_conv(unsigned long *u_ptr, unsigned int *k_ptr, int dir, @@ -721,32 +746,6 @@ int proc_douintvec(const struct ctl_table *table, int = dir, void *buffer, do_proc_douintvec_conv); } =20 -static int do_proc_dointvec_minmax_conv(bool *negp, unsigned long *u_ptr, - int *k_ptr, int dir, - const struct ctl_table *table) -{ - int tmp, ret, *min, *max; - /* - * If writing to a kernel variable, first do so via a temporary - * local int so we can bounds-check it before touching *k_ptr. - */ - int *ip =3D SYSCTL_USER_TO_KERN(dir) ? &tmp : k_ptr; - - ret =3D do_proc_int_conv(negp, u_ptr, ip, dir, table); - if (ret) - return ret; - - if (SYSCTL_USER_TO_KERN(dir)) { - min =3D (int *) table->extra1; - max =3D (int *) table->extra2; - if ((min && *min > tmp) || (max && *max < tmp)) - return -EINVAL; - WRITE_ONCE(*k_ptr, tmp); - } - - return 0; -} - /** * proc_dointvec_minmax - read a vector of integers with min/max values * @table: the sysctl table @@ -768,7 +767,7 @@ int proc_dointvec_minmax(const struct ctl_table *table,= int dir, void *buffer, size_t *lenp, loff_t *ppos) { return do_proc_dointvec(table, dir, buffer, lenp, ppos, - do_proc_dointvec_minmax_conv); + do_proc_int_conv_minmax); } =20 static int do_proc_douintvec_minmax_conv(unsigned long *u_ptr, @@ -994,31 +993,6 @@ int proc_doulongvec_ms_jiffies_minmax(const struct ctl= _table *table, int dir, lenp, ppos, HZ, 1000l); } =20 -static int do_proc_dointvec_ms_jiffies_minmax_conv(bool *negp, unsigned lo= ng *u_ptr, - int *k_ptr, int dir, - const struct ctl_table *table) -{ - int tmp, ret, *min, *max; - /* - * If writing to a kernel var, first do so via a temporary local - * int so we can bounds-check it before touching *k_ptr. - */ - int *ip =3D SYSCTL_USER_TO_KERN(dir) ? &tmp : k_ptr; - - ret =3D do_proc_int_conv_ms_jiffies(negp, u_ptr, ip, dir, table); - if (ret) - return ret; - - if (SYSCTL_USER_TO_KERN(dir)) { - min =3D (int *) table->extra1; - max =3D (int *) table->extra2; - if ((min && *min > tmp) || (max && *max < tmp)) - return -EINVAL; - *k_ptr =3D tmp; - } - return 0; -} - /** * proc_dointvec_jiffies - read a vector of integers as seconds * @table: the sysctl table @@ -1045,7 +1019,7 @@ int proc_dointvec_ms_jiffies_minmax(const struct ctl_= table *table, int dir, void *buffer, size_t *lenp, loff_t *ppos) { return do_proc_dointvec(table, dir, buffer, lenp, ppos, - do_proc_dointvec_ms_jiffies_minmax_conv); + do_proc_int_conv_ms_jiffies_minmax); } =20 /** --=20 2.50.1