From nobody Sun Feb 8 00:55:14 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 9EA30334393; Thu, 16 Oct 2025 12:58:19 +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=1760619499; cv=none; b=ujPaQM7NTEzDHXBCwnRJw4WzeRBJwddl0pMKlRbMGdCwsTYWDK3piDYtmFYXQXIPCzREXw9jM2XOXTx7ONxcC9kSdQYCDtiNmLbmhpkgsdFEcCBDtTLI7Xu2+YbjItPbBiBOo7tVe9pCaT3VjxwcU9DWUO+7boDnmxRfI9GLq0o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760619499; c=relaxed/simple; bh=xhYBn//i7aNfh3cHC6GieFmJFdKrx9dZXxNHLeNVBSo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=iJ83eqbScHcJZZVygRkDf0nPVu9rxNKKPzn8IRwGepT8BM69ykgZXFeT1fHF3DaTvVa1fL9QuCxiSkR9BGnwd2cRoA7yF3O8Mt7pxuippfJ2Ph4A6JCZitkmS2hVSsfEgjbeQTpZc6tQxqg0yYXzrq5L7zTK37B76jwVD3Kd4PU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ftZkmP5i; 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="ftZkmP5i" Received: by smtp.kernel.org (Postfix) with ESMTPS id 3A9A7C113D0; Thu, 16 Oct 2025 12:58:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760619499; bh=xhYBn//i7aNfh3cHC6GieFmJFdKrx9dZXxNHLeNVBSo=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=ftZkmP5ity1FNH0WB0Jr1IQ/Py5VujM3BF/8VEhqCzCrwO7CAiel9u8ry97s7xaRG g4C+ywli5aK5lux5LvLGMURl0tqcjBB4ny9OhlTgxwsIjaksT6cbY4pl/3Fua/IEOE 97bFfptrhS69frm62Z9OTsGUGuDLp8SeEsKXkishP/z4Rg2vrwZ70H8tWPEznFlBA2 bUg2WATsfX7yy5QgY3I49uX1/Pw2IYFkwTrx++OPov2tQfnmSDfod4WFqlIQ9dhK4F 4tuEWgmEbIbmqt1R/i4y9k30lu6v+Ov9vW2cN0JvWAUWpNmhUdi9/twMfJmC5p3FEG 7/kPSPCBE4LHw== 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 27907CCD183; Thu, 16 Oct 2025 12:58:19 +0000 (UTC) From: Joel Granados Date: Thu, 16 Oct 2025 14:57:47 +0200 Subject: [PATCH v2 01/11] 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: <20251016-jag-sysctl_conv-v2-1-a2f16529acc4@kernel.org> References: <20251016-jag-sysctl_conv-v2-0-a2f16529acc4@kernel.org> In-Reply-To: <20251016-jag-sysctl_conv-v2-0-a2f16529acc4@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Kees Cook , Joel Granados Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org 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+kA0DAAoBupfNUreWQU8ByyZiAGjw6+LWrVllGc+KDl2poCDQhw1suA4i1uuur 5zTsITSaPVXPYkBswQAAQoAHRYhBK5HCVcl5jElzssnkLqXzVK3lkFPBQJo8OviAAoJELqXzVK3 lkFPdgML/2U0UVjjAbJYRA2fNRLNQJpx4Y3e9QgonmeSu1beWFC4ZgpGZzEQWH3ao8bZUUlmjJ4 k6Sa7LITF8GiL8PbXqix3Vgmsx3XFVQZwneJPJCCZ9YUyNeJm1eQnyn0HKoUgYsLPZlEbXfEHq2 pErPVCvOriafPdHPpQvuafOT1jhYRQoKKaCtK4oNEgKxHf69sgtijIDFbF7eW2b1XmHkCBZwEX2 00jS7lA04jw1NYARSQAka7FHgdNGPFUCdVb5WB8S6tBlc0XfS/Xr1f3DFsdlWO+aCs2BZPNovqS miQlv77Ycwl6Qqjp4/dCrbRp1moHg5SuqgIU+u7BmZ1igmdrGp9sKXYrCx0wiTTu59hD51WKp1p 2Fwv3UdjmbwC6qiDRKJFsUxjj/3uvIGscVYPObr7CfjNgXP8wcfoztl/lT1daDAy9MlQaiBoV+t L3Exk+kq3bi6o40GCLR3El0GvZq8vEbCJbhgfSHw0Ox8sv3Wrh1tpoTCeylz4I1VBfIGHVKCW/6 CA= 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 Sun Feb 8 00:55:14 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 9E9B4334391; Thu, 16 Oct 2025 12:58:19 +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=1760619499; cv=none; b=NF9OC9XFjjOsfWTF97GBSDQQabsYOq+CsXrXo2gb6yPRUq58OTcRfy0lT+42RjMtzudPlWmSCqWcBMBJB+P8gEjsMrlaA5cahu6vdB1nTW+FBYxz6g509vvQTFbk1M0gaw4f1+PmixRBJPwz3h1+5lm0jeYdmR1eAxMyyTo5R8E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760619499; c=relaxed/simple; bh=Yb7SCKMM9yyjHxvSmVCws0zzI54RVCOIkVV6fK8yIW8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Rku7IeK0C1PpZRtcha8+LAf5lBhECKJCjSMM9Lx2TC1/VJ5LHSMr4uHrVj5X4nIR5bc+FSzktr8Wf0590utJXuwIAep3NDepk97NDF1bavW2SC4IRmAj82Yg9ykybxKHTqCt7xBBIRJZNiuS9CoTdREIT7Fz/rdhCwm8IndNAx0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=IlcP+TCZ; 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="IlcP+TCZ" Received: by smtp.kernel.org (Postfix) with ESMTPS id 4F517C4CEF1; Thu, 16 Oct 2025 12:58:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760619499; bh=Yb7SCKMM9yyjHxvSmVCws0zzI54RVCOIkVV6fK8yIW8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=IlcP+TCZ94Pw+woBWTB/4GQngfIVtxJpitJjiefrAkK9KXt0UwyvbnBxyT9xU/yxl hLM9bN/746FleusLj85o+9sQsR81KhcQ7l+o77eqidFdT8pdWNH9tbTJjsyBsyCXQh Gh6puYim1nZpIttCi4WlLoBGUhx9TCrW+CLfAbQA1t2kB5cxr2Nf4YNni+sjOdryBt WgX9ApHHTyxGZmQj+j21QCy0c3mGn5nok+F6RQsaELdcIK6Qz7pnrG0R5+9tkNX3l2 DVoRZZ0+clKiOkqTScJFZv/RTqfm6nuYwa1P5W+QSOYNOFxD1JnVTK4iYgONw+sRh2 CCKSmcQPtbH4A== 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 3951FCCD19A; Thu, 16 Oct 2025 12:58:19 +0000 (UTC) From: Joel Granados Date: Thu, 16 Oct 2025 14:57:48 +0200 Subject: [PATCH v2 02/11] 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: <20251016-jag-sysctl_conv-v2-2-a2f16529acc4@kernel.org> References: <20251016-jag-sysctl_conv-v2-0-a2f16529acc4@kernel.org> In-Reply-To: <20251016-jag-sysctl_conv-v2-0-a2f16529acc4@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Kees Cook , Joel Granados Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org 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+kA0DAAoBupfNUreWQU8ByyZiAGjw6+OSwnAXSecEofoSJdhYwp4eSvfkdDhS8 C24y4JH6ghvjokBswQAAQoAHRYhBK5HCVcl5jElzssnkLqXzVK3lkFPBQJo8OvjAAoJELqXzVK3 lkFP5/MMAITRsBv4MBXKnGnO2Ka7asmGMwePdBHETEaYo+hnr7RtplAW3NcxcvgAWsKChiVEInh yXYX00joNa1hElqQHlQJkOhcdDNosbtvAAR2J3SuLUebXnt7Y41HF2RP/h6z8GCBEddkgsybQcd xB2cJhyuSJZrSM76Gov1A72YPgWFCHHfctlQB3NiPhRuO9fAYbACCAvlUbwkG9ySK2XngyuGcdJ XQ8dXNGKV1HlMQ8P3wRmEgbavP0cu8kzo4qqlgpi/O0HA8dyTW9FOg+2EFL160ai8Eg14Hju2dp MaSLNRRAZUgKP+aYeB9M2ncOirGZiMFZJKC+LcWvfOZqLuQwrxadUbE8uIfEwvLAe2joA73LUqZ ZzSg+vbM1MA0ZqsLTNY2PgUwwGCwti6tXUlX6aSxnkZKjYIi3rYDX4SsaFzRGtIybiwQbJKzpwV ok4bGt/NH4dTT5+GSIBIUhvPeWghcaRsnfZ5gqVyj2TIldgieSGkXn5kjVweS5GUDJLY++kitw5 +w= 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 Sun Feb 8 00:55:14 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 8634033438E; Thu, 16 Oct 2025 12:58:19 +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=1760619499; cv=none; b=pr7Bn/bgaeIS63uQR/3Bz+YntHkZoKtyEii4bmiG4gLjagrkNpE48DxX5yNFtDfDlnc0gCVpW7duV0bgNaqNeYWjhVwY4Vnv2tU6BV2UPiQTChfiUAxTY2rE6riB/Yr3+ZxzXFS3/B5EE7zPaWWVYQPlfnil/H6M+oQ7orLpNVU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760619499; c=relaxed/simple; bh=UfEJu7bUmeezVz/Pc8RnUq8eKehGxWWFgOSUQwSlJQQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=QKzUp72mRHJBJF/iTDI83o+c9QKtcwYMCb9jh3us9t6n1CQ3G2eMs/yAUqBuEK9sxc1zjly/25ognryu7bDBW8iqZG53Xp8WwaGfuoMSGY5JJ8L8SMZMXqqHHus7pRZ3GZeDGOJIwtF0pTazNcqaLxuv9eG2myCpXLCHuk2A4+0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=OAuIECk2; 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="OAuIECk2" Received: by smtp.kernel.org (Postfix) with ESMTPS id 5D61CC19422; Thu, 16 Oct 2025 12:58:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760619499; bh=UfEJu7bUmeezVz/Pc8RnUq8eKehGxWWFgOSUQwSlJQQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=OAuIECk22iGEwatBNEtK6TzLItdkhZ0Xw1GYw8zfTHQjGAKPv34+5xvkDwSARho4D qZ2+P/g0Vt1YttC4ZtiPHQFnMAnGlexJ+x0WuZ3uUxhWNq30xwZLZ9+NS58pOx8Y7N NMNwWeHUyoMdrbNVrhIU3xNZbJ9M7MYGIG9m8QmRo7sFUjGGqXk/XkGBOi0DMJRoa3 eQC9g7VPT/ot6G15nROlvGiTCgLCGlgg+6QzPPqM93wYk2b+GyxAO5QpmcCkH9A5KT Vg+Ue17UM/C93NVdP0bfNkckTbv4MjRBUX/PVuVIykhybYS7DUWyuQedVl0E5hUeYr nfOwJEAKrbbjQ== 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 48FD8CCD194; Thu, 16 Oct 2025 12:58:19 +0000 (UTC) From: Joel Granados Date: Thu, 16 Oct 2025 14:57:49 +0200 Subject: [PATCH v2 03/11] 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: <20251016-jag-sysctl_conv-v2-3-a2f16529acc4@kernel.org> References: <20251016-jag-sysctl_conv-v2-0-a2f16529acc4@kernel.org> In-Reply-To: <20251016-jag-sysctl_conv-v2-0-a2f16529acc4@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Kees Cook , Joel Granados Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org 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+kA0DAAoBupfNUreWQU8ByyZiAGjw6+MIGEYxSaaph0qVHOhefHfkfDKmlBKnb QH5OaC8vGlEm4kBswQAAQoAHRYhBK5HCVcl5jElzssnkLqXzVK3lkFPBQJo8OvjAAoJELqXzVK3 lkFPtNYMAIjhKuRUY3vIWDeR+bScXo5UDL4ltfdcia2UE/je/MHiMvVu7s68UMnpn5tZLP9WuMO hxp9k5U5XJxzQVotVkxnOQ/8Aw11UXmti2Wnw6mVuB47PmVbRkCgCJOo/szMJq6oetjB/AvOEhm qhzGsC3nIHiHHS/8CBf/UBSv2/dGml80Hy5Ls6z917Yw2OueWGJjQIn/iRH7l60EGnijzVpsaIG YdkO2TrrBiaT/WSWWVEmq9abNvkCjfyy0X29ZS1zarluZxbBVZMHka6TbyyxFWoSbbwyG2YZLLH synccm/s7hKCHN9g0i9HttTbheiQDERVBzZ12v0ZFOM2M+8/D61Qo0CTXK4EMsbLsSEftZXVb7d mZLOTlMnqynwW2ZSugLT7aKk8ghA7QOuZLGCUzLmbkBp3aMTHV0rnorj/kqHJgyyb2ZkzOPYpMn mBLrKqlRkLsSpatiUoOAY2s8AvAPwMcGraS9ESR3SAs6lbm5d3/XWRNbyWZPF3F+NKheNQsiji9 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 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 Sun Feb 8 00:55:14 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 8626A33438B; Thu, 16 Oct 2025 12:58:19 +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=1760619499; cv=none; b=IAnI/Sr56d0UPzn1xfxVI+AiR69rdPrB+t20HyRagkcAmy/DJD1s4eUQrfWbqH+Bol0efFcg0NJWCDPlNS657wmrHbYc1pRdLz0rzGWCtT1s2lysKDPcyl0KrQipHEJOf/OxH0dwG19x+V+QD+XxOZW83gJbT8O3mujku+ySORA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760619499; c=relaxed/simple; bh=UsZpr7tzJfURt5nWobiw5O5X9RgHQGws0QBptGLRrMY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=J10rZSDzrql+p3msRMldxhPKAZXO29GsbrIWaYh9aGmbjIqLz8yalfhzqSwsBdudahZon0IW3lGYrW2+MRyyqY+tBRbPf3Az5Zj7c7nfxUcUOwZ2zuOjOO19br+nf4CVTiCAFMlXAfpYzltKkBO6z5GhF8kgswCymY03hbNq/n4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=pOu6QtsK; 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="pOu6QtsK" Received: by smtp.kernel.org (Postfix) with ESMTPS id 64C63C116D0; Thu, 16 Oct 2025 12:58:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760619499; bh=UsZpr7tzJfURt5nWobiw5O5X9RgHQGws0QBptGLRrMY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=pOu6QtsKxN+qPA/vhGXtegxZTZXBep9WB1duXWjAz8nICPaaosX7m4Gt9YHlxVo1Z FuUt31sFv+1h6dTIpyyY+UtXEAro7f2y6JXDiMNPXHK6WglcBBlDFWWU8hzC3fvSqP 5CK3wfSmJ/VeKuWtRUoedmOf22YmODEA81PoqfSv/OsklpxQIrFmGAyBh3jn7bILju r9PXvSyQY7vlMq1cITIcQuy65ge7K04muP5cyl5sDUVMPPqBrKnaoE+/4Nf9fHxgko zmws3V2nZpidyGcyKLxV6MnwdCoakbLzKU6DWNQ/bwhn6j7dXRt0mqVx9MYGUA6HnM aHMD/joK+7Bww== 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 5BA28CCD19F; Thu, 16 Oct 2025 12:58:19 +0000 (UTC) From: Joel Granados Date: Thu, 16 Oct 2025 14:57:50 +0200 Subject: [PATCH v2 04/11] 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: <20251016-jag-sysctl_conv-v2-4-a2f16529acc4@kernel.org> References: <20251016-jag-sysctl_conv-v2-0-a2f16529acc4@kernel.org> In-Reply-To: <20251016-jag-sysctl_conv-v2-0-a2f16529acc4@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Kees Cook , Joel Granados Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org 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+kA0DAAoBupfNUreWQU8ByyZiAGjw6+ResRnrBBQq9KbFjQ6vVOxFEsu0YX9NK /tNVw5f0DjOG4kBswQAAQoAHRYhBK5HCVcl5jElzssnkLqXzVK3lkFPBQJo8OvkAAoJELqXzVK3 lkFPMMgL/1uapkxeALEEY3BBP3M9OYu2zI6yYEi426myeSupZ7yCH72rq1pZ1teMAZTW9SZFJK4 ewQEMhDLlmJyGDXUzjo8XwAzBg73fqLH8PB/uL/y28enJoe1qsW3kNGXtRpaZdPhCbrY0HaIEZH Sw7vFQmy/mbaeCe+Iij1dMNp+N9rrFp4tofcf0VDh8TQ3kmVo2t/noJXOQ4NiWyspL9L80PTNdT BhP3HowUHvHQFhzEtIw/E7+T1x/8zLplTcKeyRrgsyUHdiqoSa3fwOAq/aX4/p9W3c01hWXJV1B 5b6J4xVYi93hJjP0F3+fc6OlCWNbcNJLKQFTPKgJ7JSpjORtADBrZfZRLKgqOkFqdsEUvrKMbTR OFWubJoN1MQAzN+G+O6/ZcTNz2LJJnix6KFn4YOVzgy3w528il/ap3EG0RKLLBz3MMZS+sq/VlQ RvApzzCXG458G6KR5dR4CRa5zfQYsa6Gu0/laHWyb++1hgI3hVI/yKPetfQ/opC05ZS+ELqxxk6 vY= 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 Sun Feb 8 00:55:14 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 C3025335BAA; Thu, 16 Oct 2025 12:58:19 +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=1760619499; cv=none; b=KWHqpUtzqXnebUlubEvOR/71AnRSQJU/rgJcA+8n9juwhcqK6ipgND1eWCena+ny5WBv73MEa09aG//W8kaWr1fTBrfbllkBq81p5iqIR7W42Jralv+rLvlXmTYiAvDEXwGjafxAu1t17ZEqZ1n/4DtfcL1Jh1xh12940lRcmmM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760619499; c=relaxed/simple; bh=caF6LtqiOd2vBnpLGcm75cb9MaprTYO9NBhODSG8Pjs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=T/uUP9oXJPu2nsUq2xd7pGx1oxEbj2HQxJGKyV0dtW9Ts1LN1ixKwVqIWrZ6WW4HLnoyRGnkE0AqlXHBnRZbxb60wxuNfA7O2fan1lZM2hzY8vF+E0Jy4ZU1fOn0GapabUl3TcRlb4d9K+Y5p34z8U65DijZaV24ggrTTQvzJT8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=V5sUawpT; 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="V5sUawpT" Received: by smtp.kernel.org (Postfix) with ESMTPS id 7BD3FC116C6; Thu, 16 Oct 2025 12:58:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760619499; bh=caF6LtqiOd2vBnpLGcm75cb9MaprTYO9NBhODSG8Pjs=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=V5sUawpT6W+CEezGCv/9Z6vzae2xtWzkc1Xz3dz28uUu9TwdZ29GwhNZY9YE06OVT CYSR/KAbJJM8Hpa32ckh5cK5bB4I4TqxBfqBo4xNUE9YYTkFveqxE5LcfIFBCsadP8 ChwYTDJBFOJ0/HkoiIuDEYzHjslrU/2G3rArHfeb5TutQkv7xCC52rUFNbgFf8p6ix YJupMcGFXbukHRa7Vv4rsW5o3CA/Hbbjj1Kk/junza4sC4NDdbsYwu/WCzktRvmlIy mcD7UeE/bDKAX3ahO9U6PFxR97d/zaq0TRo3fX7MZPC4g0k1p00EEvqBOZq6rxzxsH ZIck26xt3stmQ== 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 6AD26CCD199; Thu, 16 Oct 2025 12:58:19 +0000 (UTC) From: Joel Granados Date: Thu, 16 Oct 2025 14:57:51 +0200 Subject: [PATCH v2 05/11] 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: <20251016-jag-sysctl_conv-v2-5-a2f16529acc4@kernel.org> References: <20251016-jag-sysctl_conv-v2-0-a2f16529acc4@kernel.org> In-Reply-To: <20251016-jag-sysctl_conv-v2-0-a2f16529acc4@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Kees Cook , Joel Granados Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org 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+kA0DAAoBupfNUreWQU8ByyZiAGjw6+Xo/DWkTqf4p34t9NR3oKE+NpWRETSqc UU6UJscRCSDqIkBswQAAQoAHRYhBK5HCVcl5jElzssnkLqXzVK3lkFPBQJo8OvlAAoJELqXzVK3 lkFPovkL/RSNrtB9ZOKCTVD1Vpo75QuIt+V9KUxHxs87zneamA3MXSkBLylGYPBqt5/4IYwdeYk kpWaXHkLZKkOi4PJ+DNtLFIrFMg9QQ3lcAP53QGbrkBSRil7lWJdYaTUq7uT5n7Xl0iSi7wMopk Sd57rl5HqYPFOHRBEu1H6QBGVbvq2SftGyFDnx/rvrHDz7CuXRMvC4pe6zZcwvfw1HKCL1FlZN1 5QqJOk1Zf5ePyvRTLUFoA+TQoo1zDO7OKTH7G0V9rBo/iQX0y9Ex54CmiXE+zT5f/poT7Leyjij iX7ZrRTQg9c/WtqJfp9o1DwsjeQDT3XycABlIlHTcNVCowgrGPLdkcUJyGcRsC3uDpNnJeSY088 nIzjIl8CazdX3/lq2CSjzKV2uIzjUqHOT7IMnPbZNVCgCIp9luLNdxMr3kJm6fUVqGxhru6GsCn W3HrdbZrO9qxK8+7X7zwRCGylh+n+dio8wfr0TiMFdtdWV/4o3+ScVPskSoDXP7B8lvSQIWiDp7 KI= 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 Sun Feb 8 00:55:14 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 D13BF335BB2; Thu, 16 Oct 2025 12:58:19 +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=1760619499; cv=none; b=Trn+PG6kn0FdgyKw9wzkhSEcZxEGUQ0bI7fb8A/mBi1mEhDRdDlBRCnqrEOAiTGILmUJxX/nugIAi+mGzWCFUx49mPB5atC13C1W4PP30ON+WM8P4SOM2bFluLdWwE8GX0KEpHx797j4rlXDjsXcqgoTypmyBPA/bFyHDC6KAO0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760619499; c=relaxed/simple; bh=GZxezoIkNwtwUcjJV0zafwxh2Mgp77M2WJpzEUZyXTw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Z+GSifhZXfD+NFKDU3Hes9rC3jr2Ugo0kvkEdlvoeKZclc/A08xdzPBEPXUZSpT19/NENxYA9FOuFOmh88+Ihzs2okOl1pIN3+x7i7ESgIaKD8Jh1+G1UHW/ZexTMWxHsLheJPg7eFyxN/1GjnNPtaVDPrraMp/osOjsrS1kKcM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=XT8SVxg+; 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="XT8SVxg+" Received: by smtp.kernel.org (Postfix) with ESMTPS id 87800C4CEFE; Thu, 16 Oct 2025 12:58:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760619499; bh=GZxezoIkNwtwUcjJV0zafwxh2Mgp77M2WJpzEUZyXTw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=XT8SVxg+3t9Vr8NQeEy1aZw3F2kmXp3iYsCJCgWMRB9ozBnPKoq6x/gY0Ya6126RS oUPFyBHRtn5rBPGTYmQqtUzyQR3Mp1TzHHl+aY/iSX/w1fwy6JdUuR97ckKaIFRQPc TlczOC5+9o5m+ipG1I4XfiTK/tT3bb49+C+h/H+Uz1TPeb5sR643bNhOyAicM9jnPo buwtATpKszeXZxwbLbOMS7OxcoBher8D0TrtdWzdQQu5zLjhIYj/ebhDh6J4mxVn2E AHV6JeWifrQriOdoMSBpdcIfS29pkTyzMo4/9mqcHQVQaNqDh3+lnziddFWbN1m58t CCV0xhyaQm8kQ== 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 79AB8CCD19A; Thu, 16 Oct 2025 12:58:19 +0000 (UTC) From: Joel Granados Date: Thu, 16 Oct 2025 14:57:52 +0200 Subject: [PATCH v2 06/11] 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: <20251016-jag-sysctl_conv-v2-6-a2f16529acc4@kernel.org> References: <20251016-jag-sysctl_conv-v2-0-a2f16529acc4@kernel.org> In-Reply-To: <20251016-jag-sysctl_conv-v2-0-a2f16529acc4@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Kees Cook , Joel Granados Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org 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+kA0DAAoBupfNUreWQU8ByyZiAGjw6+U2gAH5Q4bjSsqY0prw3ON75hJYy2/sr oqMiRbdnjYdN4kBswQAAQoAHRYhBK5HCVcl5jElzssnkLqXzVK3lkFPBQJo8OvlAAoJELqXzVK3 lkFPSVYMAJZ0vrWt5wqVg2OvhDt9jd0kyPIqHy/JufEx98PcxUyK2Gujpyoat5UPewHp47zp7LF 8d/jyPAdovdFIH/54231gBqfKXH8FhJHPjcEoDdOLP9yQrcyGOUC1EjCQi7Jzbsx25GOydcSzI/ 4CT0y7L0lmTqX6QMaP3ZSoTacR938id6YbM79ljHeiaW+cr3rWNARjKPMyYJNrdXqFO9qx3qQoy 8ptZPgL0jj+50L62tCFuXBZS2lnMQpN4um6DhlNKxvCU3k6K16pgF8ankfQHuMnXC5FKTXEaUSF f9S4edjy1uLAy0zKPkkQMx9TVJ2jLSvMDBQ1x57IPJm6yI9wuBIBvG2CNB0xrvfakY8Lq2Adezl JteR7/3hMmhknwJvRLylNYec0rnpu7l5tzU2jpbx3qq0MNl2CB6kwzxXa4tBRJQ1wlmvjO3i125 sFgM4NbHNajyB3q1uMlLa3700jAk1/4EmfROvtCWnfBBBvone2F4OGBX1AA0K0AM4GOIhHoq0Y6 iU= 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 Sun Feb 8 00:55:14 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 D115D335BB1; Thu, 16 Oct 2025 12:58:19 +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=1760619499; cv=none; b=IlS3MljXiLx7onF1IEKUZ9WpavZSrANkXPyHudN2s5fdis4AeJWq5mpxaX1/rj/EcsjEF7ZmFulZ6g4cVkNOQRCmdLmSCcLYVUemfLtdLy/d5C7omzT8ckZxVHWFnL98gGwhbtVnjNW8RUwHKXvS4RltboNN0d03wDDoW9XlAYc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760619499; c=relaxed/simple; bh=KD+2NkFaHlPghXWKYGaZ79Eguljp8JHhe47tIb8ZfcQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=EDDoizY8x6ghlEOWTqz/rsZFV9WzT3Bl4gjE634mUMj8Bf0dhR2NrDPNwttne5kdcnjc6Jz3Lms6P4q6cGTzCE3LCU67QZesVrfRm8Q69HPQmW/okhaSzUvXbHC9jWFIxXd2q8FEvvvWxsiNQYFd63hQkZ8ZfbRLe4h7fqjAwBw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=k9+frvlV; 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="k9+frvlV" Received: by smtp.kernel.org (Postfix) with ESMTPS id 9412CC4AF0B; Thu, 16 Oct 2025 12:58:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760619499; bh=KD+2NkFaHlPghXWKYGaZ79Eguljp8JHhe47tIb8ZfcQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=k9+frvlVlbq4z6I1Ddd9LIci0XhOAY/RsohBH+JrHhOmcJImgkW3Vr9CuXaz4e1nj +Ixf3U9cZqW2lVHmW8r76LrmC3uMqosGxuZmhlHQu6GHyqqTfMEfE7vJlbsP608Enr 3cTa6MnZwmm8mvIyOj8qUcXfl+7nAK5A8YWE04Wa8x7vYSoLVA7xyH2c77wqwJbmfA K+CgoLY1n12TpF6iewlaVYNqAXUa+tDNRh5KkWVtAzowYCR7/VshOkkPDbWmjCklT6 zOxUpx2jf3attQ2TYCLFrkOE8j3nTqSt0pRYeyZIDljo9SHgV2t7iclb6ko40z3te3 YsLt7dTVA7Teg== 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 879FACCD183; Thu, 16 Oct 2025 12:58:19 +0000 (UTC) From: Joel Granados Date: Thu, 16 Oct 2025 14:57:53 +0200 Subject: [PATCH v2 07/11] 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: <20251016-jag-sysctl_conv-v2-7-a2f16529acc4@kernel.org> References: <20251016-jag-sysctl_conv-v2-0-a2f16529acc4@kernel.org> In-Reply-To: <20251016-jag-sysctl_conv-v2-0-a2f16529acc4@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Kees Cook , Joel Granados Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org 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+kA0DAAoBupfNUreWQU8ByyZiAGjw6+Y2Ed26Q6lscjWsOC3opmYd4U/URhoyW HWQZlvWQLJPqYkBswQAAQoAHRYhBK5HCVcl5jElzssnkLqXzVK3lkFPBQJo8OvmAAoJELqXzVK3 lkFPsqUL/3sTrTN7+xIsoOWEvA+Xzy1vgBK2MTqx7rd98HL2U26kXul6QCrKv6Fq6wmZhvio4ZQ jJ/3Iyg5ZrkS5HdvApzPiu5JmNlkeREfNVLe2gvxxFNUVwKmuDq/uepEABEgpYZJ0EHPpUKXhiL BsE6xSqbZAn2RUbHmwF525d+IfeWo1BRfGY88O41glcqRGOhE3KGw2jTTVP+oeBRDmte07Rx0GS xQBTHSrIdMvzQkhe7/UwWqiotCw2sFppeU2wQCv4/1dAZtDUK0WDrk3RAp60wYaCsCMND93y2KB hkhUpfW3STj5NZrlIfghQHMdbSqSOBrOfC2J/CtBecXcGePRkynVXU/ggGXZaZUbNanqvw1iFBN MVQv/l7NmvLsJWVfXUVyCVzubrQfDB6tDVmMlWysjujD5v7R2L1EzfSBpTcNrZpV/8UX14m1tcZ +WPV/c/egiQQH0bIKvqZylg1fhpms1foZZ1s0uqw/4bWUmgelac+Ddb19PpfC9v9QGtjZZmU5o5 FI= 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 Sun Feb 8 00:55:14 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 E2C4B335BB9; Thu, 16 Oct 2025 12:58:19 +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=1760619500; cv=none; b=gm0xqDm+CyfsLQgKRHqEm5RlvbdizxFf2ewjH3pdfz2VKbk+trI8iX3m/Mx2c/iuvIL0GI3ZwkMI47rLzqyh2WQBVkhCwhS2kK34dkRdIPD/G+RME7rkwUak+3Tr4+PF42xAYAPhuJrX/vUOEmvVwO4X20zUCKO3dprcwweOGQ8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760619500; c=relaxed/simple; bh=WFmYwNqRtEEV71HErtXjnELu0hh+bKYykNpfWVGpcO8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Q0Z2qw8sRc8hXzfLNML8X0HnBawbtxefZHx5TnVi63lJLeuKVqM4SKVElSts2Nf/idHyp1SBsk/IbIkreQrMzFZgke9u/ddN4tmnGCBI02o2loLwv/qNlfDbXqS0oBBkDkhkQuvwKM/VIc11P+P0mDopFf7fOVz/TCaE6a5PLiU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=bzPG9Zfs; 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="bzPG9Zfs" Received: by smtp.kernel.org (Postfix) with ESMTPS id A35DAC19423; Thu, 16 Oct 2025 12:58:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760619499; bh=WFmYwNqRtEEV71HErtXjnELu0hh+bKYykNpfWVGpcO8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=bzPG9ZfsqA4o8+aMTZA4l07OvczF1DHxkajqbDA1uhRxTFFtqCIsACYCjDp61R7le 1z/yMmd34Ty+hX38asvVTCnXsihc0JePXVMTF2Xk0WMW6NF0wuqkvnFeJtr8qCKBZb fpg2uOfFz9Xr8Cw9QcgjqI9/a+tsLK3VGK+8xrsnncwcEYW7YLEj7spdm/udVMy2zM L6L3jR+D6jkmRAFC9httB7qQSwtG0Xs2v3G2CNVXQRdtz//qE5bxMe+WHzA9IujY// 49jtR8o52S2LXnfT5tENEm6YrC5JEjZISl4MUH9fchR79e/AN3kvwcffcdBV83PAZ2 uzcrAqNjehJzA== 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 95CBBCCD19F; Thu, 16 Oct 2025 12:58:19 +0000 (UTC) From: Joel Granados Date: Thu, 16 Oct 2025 14:57:54 +0200 Subject: [PATCH v2 08/11] 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: <20251016-jag-sysctl_conv-v2-8-a2f16529acc4@kernel.org> References: <20251016-jag-sysctl_conv-v2-0-a2f16529acc4@kernel.org> In-Reply-To: <20251016-jag-sysctl_conv-v2-0-a2f16529acc4@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Kees Cook , Joel Granados Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org 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+kA0DAAoBupfNUreWQU8ByyZiAGjw6+apDIedVblwlaTEI8ojelRgkHAc7asxX 2RAFfsLi3oEVIkBswQAAQoAHRYhBK5HCVcl5jElzssnkLqXzVK3lkFPBQJo8OvmAAoJELqXzVK3 lkFP3hIL/1YA6bZ6sWEABAzd0w8iR1j0DI8ChPn3AQydkeJUsBi9Y7ET9pfipymKMNZ4ny59/bm 0uwEAnjWsqNq6y1zz0cMMpBTCcB8+0QHHd+pqjKPe4gl1X4LZfF+dlFi9bcBKzUv2FiNplHdiGt LpqdJNI/Ty/IC9IpaRX0nAV/qRM86NjeOlmMxcgRwl/De3MSdMGbVO/ixveeAq8zkaJ5ClRsGg5 AEfBQFF3H4R3MSTe5oOPE42kbNKjZHDkeaTfnpK+8v4RjMCuh1RFFGPA//9lCrVh4cpvac5KrVt QTd35zuMPpPUBX8h9UzBGBZo/SeANr1Yp9RtX5zhtYlW8oSAlOUjb2epxlHTVALHjbzbbCBVixa Y5VvQRQo1Hi9j6jCqAif/1F5PDgf1cn0AgZRoWhMS/F41oxZ6Pq97/WT4cBrBZ7eLC9BkY599rE 8hMjO8IlToBaCj0I0MUmtGdc1hn8mKMzTVKgZ1xngX8D422cMIjD2rf7Mp74hBHMomko6Hiz5F5 PU= 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 From nobody Sun Feb 8 00:55:14 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 D17E3335BB4; Thu, 16 Oct 2025 12:58:19 +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=1760619499; cv=none; b=KJmpEN+Pq6JQev3EnMNtZIvkpbKtMHz7T++ct1d82ERiFP0iEibs+4cyLaMwYe5yjZwG9kJCf0HJbwBM7ddJ6e3XtUI3Tm8OBBFHdNMf8TRcGZ6kRn46xHf0TBm2xIDZTstqRrl60ricR+2zRNm/nZxVsz4Md06zRPjrjPiHYVQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760619499; c=relaxed/simple; bh=bFforyaMLZ60YaWnxL6G/HX0VwXmPBjbbd+0+NWBvM4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=CASrWFCgBTD4Vrrvc6NBEVNCN0R0HEiNpw3WxpJb3WACjGll75gGP4OFWN7pw+2RN+BTIPlgmxzCdHjUpbtJEsRaQco/+MjYlBDWIkzJP9m69DoqXjv208D8kDWyWEuYq4x4HWCtJdmL7zwIX+DyBxXBj8c5xfsOd6vPFAQH2sA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=cZsVtwWk; 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="cZsVtwWk" Received: by smtp.kernel.org (Postfix) with ESMTPS id AE746C19424; Thu, 16 Oct 2025 12:58:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760619499; bh=bFforyaMLZ60YaWnxL6G/HX0VwXmPBjbbd+0+NWBvM4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=cZsVtwWkl4C/fbux0giecztiL9gMB/jl9Bomv5sDc1yQ2m7aUHdL3Ta/K/80HuWd/ SovwbGvZ6Tx8HQiJ83q2KFbUx4cdRk1gwfbsLXBOxAIHtJDxeu/2GvJ/5IY9gDJQYz iN0iUujm3wUICdyFBi2QqAhH6LKxUjOgl+Xs9JcVcpg9q9e0u50I6bOi3F9aqtAp3A +ovf+3P2+vKl/V0zyaxkz0K1gplJiFLBbEISesQwtyqE+WtSlG+nusXqQPDjT+3L2M QAlQiaYq3uD1Q5vXjB3Qe6dO5NBKr5fkcD+rLz+3YzuhqwBm+h/WH9KMkjP2+uUOfc khW0ortl2yqAA== 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 A2FCFCCD199; Thu, 16 Oct 2025 12:58:19 +0000 (UTC) From: Joel Granados Date: Thu, 16 Oct 2025 14:57:55 +0200 Subject: [PATCH v2 09/11] sysctl: Create unsigned int converter using new 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: <20251016-jag-sysctl_conv-v2-9-a2f16529acc4@kernel.org> References: <20251016-jag-sysctl_conv-v2-0-a2f16529acc4@kernel.org> In-Reply-To: <20251016-jag-sysctl_conv-v2-0-a2f16529acc4@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Kees Cook , Joel Granados Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=3248; i=joel.granados@kernel.org; h=from:subject:message-id; bh=bFforyaMLZ60YaWnxL6G/HX0VwXmPBjbbd+0+NWBvM4=; b=owJ4nAHtARL+kA0DAAoBupfNUreWQU8ByyZiAGjw6+eyf6O1KoCOlnPYcVu+O6SYEqzjwoQcu QvBNyhWJIHxlYkBswQAAQoAHRYhBK5HCVcl5jElzssnkLqXzVK3lkFPBQJo8OvnAAoJELqXzVK3 lkFPhVkMAJEs0X7xu7EaiWHJtEJPStbnKXiHmlkjBNMsCRcBDn7UZqKfRK7YPBxwcUkH++u3cti zt+TwAjIMjia4IxCmXOQh/CNm/Ys9TP1nXtnkyZ6FJfucQC+LnIEgDs9Y8KgB3BwS6lY+T9zz1k xvBnXBufDofsFT4QAQZH9qZqpbrgCMevOin26wRpMunfK/xHviTk3YwCtPXrWAetIb1z+GP+73L gfq1g0wApX7/eNjB9VYs5pUgq/vyzKGz8CAn/1YllIo4WEuEx3pK2ABKlFcO9Oo5KwvAVOIJ6RM tRBTyII1N+zYccMrwY36xXnd/v5mQeeZSe7doyAKo03vKR2GS9kdmbHbeSO7kb2ezQXtfPIOAA0 u+nGb0/TJVcXvDn+zIQXwINUW9Oeht7V8JpQOwQFTjHOLFGxtlXggmztkuR5f/2TPzUM0Lola9S I3W8ZZ+Nb3WrRlTWIW+MgMcc0iQlBXZ6kQcUXAoYjSDjXXBuBuW3oAZJFMCHp7Pff/AXkkLgBr6 wA= 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 Pass sysctl_{user_to_kern,kern_to_user}_uint_conv (unsigned integer uni-directional converters) to the new SYSCTL_UINT_CONV_CUSTOM macro to create do_proc_douintvec_conv's replacement (do_proc_uint_conv). This is a preparation commit to use the unsigned integer converter from outside sysctl. No functional change is intended. Signed-off-by: Joel Granados --- kernel/sysctl.c | 43 ++++++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 60f7618083516a24530f46f6eabccd108e90c74f..ca657d1bb958060ba72118aa156= a43f8a64607eb 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -462,24 +462,37 @@ 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, - const struct ctl_table *table) +#define SYSCTL_UINT_CONV_CUSTOM(name, user_to_kern, kern_to_user) \ +int do_proc_uint_conv##name(unsigned long *u_ptr, unsigned int *k_ptr, \ + int dir, const struct ctl_table *tbl) \ +{ \ + if (SYSCTL_USER_TO_KERN(dir)) \ + return user_to_kern(u_ptr, k_ptr); \ + return kern_to_user(u_ptr, k_ptr); \ +} + +static int sysctl_user_to_kern_uint_conv(const unsigned long *u_ptr, + unsigned int *k_ptr) +{ + if (*u_ptr > UINT_MAX) + return -EINVAL; + WRITE_ONCE(*k_ptr, *u_ptr); + return 0; +} + +static int sysctl_kern_to_user_uint_conv(unsigned long *u_ptr, + const unsigned int *k_ptr) { - if (SYSCTL_USER_TO_KERN(dir)) { - if (*u_ptr > UINT_MAX) - return -EINVAL; - WRITE_ONCE(*k_ptr, *u_ptr); - } else { - unsigned int val =3D READ_ONCE(*k_ptr); - *u_ptr =3D (unsigned long)val; - } + unsigned int val =3D READ_ONCE(*k_ptr); + *u_ptr =3D (unsigned long)val; return 0; } =20 +static SYSCTL_UINT_CONV_CUSTOM(, sysctl_user_to_kern_uint_conv, + sysctl_kern_to_user_uint_conv) + 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 *u_ptr, int *k_ptr, @@ -660,7 +673,7 @@ int do_proc_douintvec(const struct ctl_table *table, in= t dir, void *buffer, } =20 if (!conv) - conv =3D do_proc_douintvec_conv; + conv =3D do_proc_uint_conv; =20 if (SYSCTL_USER_TO_KERN(dir)) return do_proc_douintvec_w(table, buffer, lenp, ppos, conv); @@ -743,7 +756,7 @@ int proc_douintvec(const struct ctl_table *table, int d= ir, void *buffer, size_t *lenp, loff_t *ppos) { return do_proc_douintvec(table, dir, buffer, lenp, ppos, - do_proc_douintvec_conv); + do_proc_uint_conv); } =20 /** @@ -779,7 +792,7 @@ static int do_proc_douintvec_minmax_conv(unsigned long = *u_ptr, /* When writing to the kernel use a temp local uint for bounds-checking */ unsigned int *up =3D SYSCTL_USER_TO_KERN(dir) ? &tmp : k_ptr; =20 - ret =3D do_proc_douintvec_conv(u_ptr, up, dir, table); + ret =3D do_proc_uint_conv(u_ptr, up, dir, table); if (ret) return ret; =20 --=20 2.50.1 From nobody Sun Feb 8 00:55:14 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 260E0335BD0; Thu, 16 Oct 2025 12:58:19 +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=1760619500; cv=none; b=bs2U2IdrZaHz6lj1csoKmxmYmygcqZZoYYrYLbeMV6uIrrbrFpAEdBYx+8yU+g07vLgsvh/FWyueCrbk2vKvHSGRm6V/VMyHc6IMa+LysBx/+ZFxLnV3PDpaT16/l5UBc/SUo7lBAVksCP8KvgVx7KW+/dQ1CP4Gb2Obce2xZxk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760619500; c=relaxed/simple; bh=807u6LnyL+s222km/1YbC0VDQY1tikVb8paVLNFnzfk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=MjOfVbGH6V/ZNOK7vUW+7g/YpNN/BfaFbptDIWOMO60n20Zxf0R+jEnDe9gMVtCiGBRy2RORIuod15yTSVay12q5fpi2fcSIAPKSxuvYtc90q0NfEJ0iT1vwX0k6pCRmoWT7nbOAlWKQGVih7/VNGzfF69gxkJ26UI97Ft74o94= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=PsbxhnL/; 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="PsbxhnL/" Received: by smtp.kernel.org (Postfix) with ESMTPS id B8D73C116B1; Thu, 16 Oct 2025 12:58:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760619499; bh=807u6LnyL+s222km/1YbC0VDQY1tikVb8paVLNFnzfk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=PsbxhnL/3s6Vi1YB3ERAMoFq86Ym0LXpiL2zGMpk6a9EP5V93PEQrNKjhjgO98REw N7VAQbJqyXu+Hvq4+eOdv09s1asjFA5zymqC5XmDj9D+n8qJagF6I4C4A/n1ENeTLo nXBcHA7qlwpkKEkyaqV5w2l9rkeWcfJn4dd1kGOuY93lAXADAdOq/P/Ga0T9UFAA1f SrzSrg9d07FDqlsqtYg3ExGxLmntPznTu6OAxYYPxKvL0cYQI5nJHzWbbslzVmQmN0 nsf8lwiWi1zBx0ozK5ZhC1DPtaybLwF3MXf8Ic3JruEEmyWswvsg7PFbBb3+CuRLCZ Vheee534lUtig== 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 B0CF6CCD1A1; Thu, 16 Oct 2025 12:58:19 +0000 (UTC) From: Joel Granados Date: Thu, 16 Oct 2025 14:57:56 +0200 Subject: [PATCH v2 10/11] sysctl: Add optional range checking to SYSCTL_UINT_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: <20251016-jag-sysctl_conv-v2-10-a2f16529acc4@kernel.org> References: <20251016-jag-sysctl_conv-v2-0-a2f16529acc4@kernel.org> In-Reply-To: <20251016-jag-sysctl_conv-v2-0-a2f16529acc4@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Kees Cook , Joel Granados Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=4062; i=joel.granados@kernel.org; h=from:subject:message-id; bh=807u6LnyL+s222km/1YbC0VDQY1tikVb8paVLNFnzfk=; b=owJ4nAHtARL+kA0DAAoBupfNUreWQU8ByyZiAGjw6+eTUKQbCUSkbHbRE0+Az7i9xGiVeVcvA xeWh+qnCwwyDIkBswQAAQoAHRYhBK5HCVcl5jElzssnkLqXzVK3lkFPBQJo8OvnAAoJELqXzVK3 lkFPt8cL/0vpcOq2QdjRCUe3WFO8q06gLl5OJNA4GA0+5wIv7V2aS0dzFzirbX8X0vwjFQYu2F6 FYyyQV9X28WS9x+ItZM/D3p1x/w62ifyPUq2jxyGnFFh6d8qUNoogicIawSw23kSYO8cwf3scJV NnQq25tVDcJMyCzxfh0/+rcbGHw+bY6PiZKIoyKDrg+woCUnDfIcyc8rAGL5frqW4g9vXXhNYXW QpwvM7cnSB1N9gOW7CTHr9pgVogBKV/CDCHHjn5zgpTT5ZobEoM5bo3ipzdK2IvgGpLAlLuUygc UP4w63ZhG5oX/+CZKXbaxIqobNaVNHXHzx8n1534oiBQ7UNf5AmK5awTVqocJs5TCzfuO6Q2w8m iqvaCvAxIEVBdMre3YeC1T4yQbtjIU/7hh9/4mtiO4kkwshDBZXzAMD/HtSiO6Ni2ltka/LEbl9 kZpqgScvZSVcylVKqMYXa3Oa2SCND7/YzTvPpZoLJMDnZkHMaIKP432jjLfHp5/ouyvgUirNPD7 l4= 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 Add k_ptr_range_check parameter to SYSCTL_UINT_CONV_CUSTOM macro to enable range validation using table->extra1/extra2. Replace do_proc_douintvec_minmax_conv with do_proc_uint_conv_minmax generated by the updated macro. Signed-off-by: Joel Granados --- kernel/sysctl.c | 69 ++++++++++++++++++++++++++---------------------------= ---- 1 file changed, 32 insertions(+), 37 deletions(-) diff --git a/kernel/sysctl.c b/kernel/sysctl.c index ca657d1bb958060ba72118aa156a43f8a64607eb..750c94313c1fd23551e03f45558= 5d2dd94f3c758 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -462,15 +462,6 @@ static SYSCTL_INT_CONV_CUSTOM(_ms_jiffies_minmax, sysctl_user_to_kern_int_conv_ms, sysctl_kern_to_user_int_conv_ms, true) =20 -#define SYSCTL_UINT_CONV_CUSTOM(name, user_to_kern, kern_to_user) \ -int do_proc_uint_conv##name(unsigned long *u_ptr, unsigned int *k_ptr, \ - int dir, const struct ctl_table *tbl) \ -{ \ - if (SYSCTL_USER_TO_KERN(dir)) \ - return user_to_kern(u_ptr, k_ptr); \ - return kern_to_user(u_ptr, k_ptr); \ -} - static int sysctl_user_to_kern_uint_conv(const unsigned long *u_ptr, unsigned int *k_ptr) { @@ -488,8 +479,37 @@ static int sysctl_kern_to_user_uint_conv(unsigned long= *u_ptr, return 0; } =20 +#define SYSCTL_UINT_CONV_CUSTOM(name, user_to_kern, kern_to_user, \ + k_ptr_range_check) \ +int do_proc_uint_conv##name(unsigned long *u_ptr, unsigned int *k_ptr, \ + int dir, const struct ctl_table *tbl) \ +{ \ + if (SYSCTL_KERN_TO_USER(dir)) \ + return kern_to_user(u_ptr, k_ptr); \ + \ + if (k_ptr_range_check) { \ + unsigned int tmp_k; \ + int ret; \ + if (!tbl) \ + return -EINVAL; \ + ret =3D user_to_kern(u_ptr, &tmp_k); \ + if (ret) \ + return ret; \ + if ((tbl->extra1 && \ + *(unsigned int *)tbl->extra1 > tmp_k) || \ + (tbl->extra2 && \ + *(unsigned int *)tbl->extra2 < tmp_k)) \ + return -ERANGE; \ + WRITE_ONCE(*k_ptr, tmp_k); \ + } else \ + return user_to_kern(u_ptr, k_ptr); \ + return 0; \ +} + static SYSCTL_UINT_CONV_CUSTOM(, sysctl_user_to_kern_uint_conv, - sysctl_kern_to_user_uint_conv) + sysctl_kern_to_user_uint_conv, false) +static SYSCTL_UINT_CONV_CUSTOM(_minmax, sysctl_user_to_kern_uint_conv, + sysctl_kern_to_user_uint_conv, true) =20 static const char proc_wspace_sep[] =3D { ' ', '\t', '\n' }; =20 @@ -783,31 +803,6 @@ int proc_dointvec_minmax(const struct ctl_table *table= , int dir, do_proc_int_conv_minmax); } =20 -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 : k_ptr; - - ret =3D do_proc_uint_conv(u_ptr, up, dir, table); - if (ret) - return ret; - - 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)) - return -ERANGE; - - WRITE_ONCE(*k_ptr, tmp); - } - - return 0; -} - /** * proc_douintvec_minmax - read a vector of unsigned ints with min/max val= ues * @table: the sysctl table @@ -832,7 +827,7 @@ int proc_douintvec_minmax(const struct ctl_table *table= , int dir, void *buffer, size_t *lenp, loff_t *ppos) { return do_proc_douintvec(table, dir, buffer, lenp, ppos, - do_proc_douintvec_minmax_conv); + do_proc_uint_conv_minmax); } =20 /** @@ -876,7 +871,7 @@ int proc_dou8vec_minmax(const struct ctl_table *table, = int dir, =20 val =3D READ_ONCE(*data); res =3D do_proc_douintvec(&tmp, dir, buffer, lenp, ppos, - do_proc_douintvec_minmax_conv); + do_proc_uint_conv_minmax); if (res) return res; if (SYSCTL_USER_TO_KERN(dir)) --=20 2.50.1 From nobody Sun Feb 8 00:55:14 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 5E24A3375A2; Thu, 16 Oct 2025 12:58:19 +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=1760619500; cv=none; b=Az3TVds08b7FPA28mJTtVuxDrSsmQrC2U+SafRoZTeBbxito3M/cMy3ijXQQ4cqEh+e5ecE8qbBC+6/OK0rLuPmy8RmCZbklpv7KfapYPZ5W2WUT0KfdtSGvN3WwecCPPOuO9vqYx12iHFzHDisytMULb3Q2tzVlvybY/9L7WXg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760619500; c=relaxed/simple; bh=xP7pIUDrYB9KQ96n73WKDlnF/Xja1RjBW7d+EpQMu6M=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=HiVYLkm4n5w6eqNJR9irphiCQfoIGYT0PWjUh26IVjCFEgwNrary7t02eO15E+38UYBYPWzEn4WWQomBWg10L/xvkkilPvTBLHPOeQpjp198ocAQPrOWnI2VtKEijFI7VtVdw0MX8ymNvOwuRhV63hfb/Xu5E4qArFStjU9dVyc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=rAvygFza; 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="rAvygFza" Received: by smtp.kernel.org (Postfix) with ESMTPS id C6186C113D0; Thu, 16 Oct 2025 12:58:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760619499; bh=xP7pIUDrYB9KQ96n73WKDlnF/Xja1RjBW7d+EpQMu6M=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=rAvygFzarRinD4LwRTf47yq/cPKw0bTbsKRZiLjn4Fx31xSSqlyfi3hpstYOfMlyL uHONtz7p4u1l4EsCYIGu04Z7ETt2o0SNzS3XOKlzx5Fu5ewRgNlsZhlzjrHPo4I9pP gaYcUu3XoIoS1V94IQqSfDp7raHA0ObWKOOj+uDOLbC61h62cAyCbVqbG4kcPCmMWl V3lpJ0AM/2VLZPe2FhmbbKfypStR5QYouqpxGNUpTKYYdLqatmsTFhSYeqCuVIZHDr NlqnxhKn0Iop3IlgX5mqgeVZ3yZKzYjs9Ydc/PHKd1mfGTW/d6K3PIItcWuZovrl8/ qqdWIRFXKMoVQ== 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 BE73ACCD19A; Thu, 16 Oct 2025 12:58:19 +0000 (UTC) From: Joel Granados Date: Thu, 16 Oct 2025 14:57:57 +0200 Subject: [PATCH v2 11/11] sysctl: Create macro for user-to-kernel uint converter 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: <20251016-jag-sysctl_conv-v2-11-a2f16529acc4@kernel.org> References: <20251016-jag-sysctl_conv-v2-0-a2f16529acc4@kernel.org> In-Reply-To: <20251016-jag-sysctl_conv-v2-0-a2f16529acc4@kernel.org> To: Alexander Viro , Christian Brauner , Jan Kara , Kees Cook , Joel Granados Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=1590; i=joel.granados@kernel.org; h=from:subject:message-id; bh=xP7pIUDrYB9KQ96n73WKDlnF/Xja1RjBW7d+EpQMu6M=; b=owJ4nAHtARL+kA0DAAoBupfNUreWQU8ByyZiAGjw6+har3JgRhpb7X+yT2YZZPpLBCCBReffZ 4u3JcnC1qd+QYkBswQAAQoAHRYhBK5HCVcl5jElzssnkLqXzVK3lkFPBQJo8OvoAAoJELqXzVK3 lkFPC0wL/2nGgxIGHWL6XlsbrXL1jKFc+w1KHAEWTglDc1POPTTpP0zMycx8vI8WergoKcGZm0a 8aT2lbab9gWuYsWRK4OQKgIZtfFNKmVNza80mg6bwPVMvOe8UFUWasZDXxWkhUqND35JfHebMET HxjVwILebsi/RFWCkyjpqRdcWUESrGwWQ7jxUj4087BkUmtZ2LXt8FUGTyIUxVktZltIUtHwtm0 cXQIrDUtT7Dt646yB/2LioExvw64/q68vWZGXmCMoz6r1lHFBRLwaL2DrrezclwqRPjNcAYZVeA HjiI9bG5e2y7mOOYP0ZLpbvkobJzMVBDVjNJuPXv6rLy8wTBjXE52k7Uj/uXf/j+IuLB57uANrG Wxk66e3TUicvF0V3XVEwHeGrY4oTDt4TQeP6jhhwvfBQ5Uh2cjq+EhxJeVvlgrwmTNLejWIc5Ac c3oyCTpJpMF2SGQW3W+ClMH2oAwoKENliAh1ow2rgFEGsdBDPUKSuepPQ6ShlEGg0UnHEDjBiw5 qI= 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 sysctl_user_to_kern_uint_conv function with SYSCTL_USER_TO_KERN_UINT_CONV macro that accepts u_ptr_op parameter for value transformation. Replacing sysctl_kern_to_user_uint_conv is not needed as it will only be used from within sysctl.c. This is a preparation commit for creating a custom converter in fs/pipe.c. No Functional changes are intended. Signed-off-by: Joel Granados --- kernel/sysctl.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 750c94313c1fd23551e03f455585d2dd94f3c758..9b08573bbacdfa0ec036a804356= 1253c21300c9a 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -462,15 +462,19 @@ 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 sysctl_user_to_kern_uint_conv(const unsigned long *u_ptr, - unsigned int *k_ptr) -{ - if (*u_ptr > UINT_MAX) - return -EINVAL; - WRITE_ONCE(*k_ptr, *u_ptr); - return 0; +#define SYSCTL_USER_TO_KERN_UINT_CONV(name, u_ptr_op) \ +int sysctl_user_to_kern_uint_conv##name(const unsigned long *u_ptr,\ + unsigned int *k_ptr) \ +{ \ + unsigned long u =3D u_ptr_op(*u_ptr); \ + if (u > UINT_MAX) \ + return -EINVAL; \ + WRITE_ONCE(*k_ptr, u); \ + return 0; \ } =20 +static SYSCTL_USER_TO_KERN_UINT_CONV(, SYSCTL_CONV_IDENTITY) + static int sysctl_kern_to_user_uint_conv(unsigned long *u_ptr, const unsigned int *k_ptr) { --=20 2.50.1