[PATCH v2 2/4] sysctl: Reject uint arrays before calling the general proc_vec

From: Joel Granados

Date: Fri Aug 14 2026 - 06:42:34 EST


Move the UINT vector size check to proc_douintvec_conv; the function
that routes UINT types only. Route all the UINT calls (including
proc_dou8vec_minmax) through proc_douintvec_conv.

UINT proc handlers that incorrectly define maxlen will now return
-EINVAL instead of 0 in the cases where data is missing, lenp is 0 or
ppos is 0. Note that maxlen == 0 is not considered as miss-defined.

Signed-off-by: Joel Granados <joel.granados@xxxxxxxxxx>
---
kernel/sysctl.c | 17 +++++++----------
1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 47a92cbbcb69cd361a18dba6606ae6ae8f86b5e2..7e9024899be6d5971752dd5639ab4b806a899081 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -748,10 +748,6 @@ static int proc_vec(const struct ctl_table *table, int dir, void *buffer,
return 0;
}

- /* uint arrays are not supported, *Do not* add support for them. */
- if (type == PROC_VEC_UINT && (table->maxlen / data_size) != 1)
- return -EINVAL;
-
if (SYSCTL_USER_TO_KERN(dir)) {
if (proc_first_pos_non_zero_ignore(ppos, table))
goto out;
@@ -797,6 +793,9 @@ int proc_douintvec_conv(const struct ctl_table *table, int dir, void *buffer,
int (*conv)(bool *negp, ulong *u_ptr, uint *k_ptr,
int dir, const struct ctl_table *table))
{
+ /* uint arrays are not supported, *Do not* add support for them. */
+ if (table->maxlen && (table->maxlen / sizeof(uint)) != 1)
+ return -EINVAL;

if (!conv)
conv = do_proc_uint_conv;
@@ -881,8 +880,7 @@ int proc_dointvec(const struct ctl_table *table, int dir, void *buffer,
int proc_douintvec(const struct ctl_table *table, int dir, void *buffer,
size_t *lenp, loff_t *ppos)
{
- return proc_vec(table, dir, buffer, lenp, ppos, PROC_VEC_UINT,
- (union proc_vec_conv){ .uint_conv = do_proc_uint_conv });
+ return proc_douintvec_conv(table, dir, buffer, lenp, ppos, do_proc_uint_conv);
}

/**
@@ -932,8 +930,8 @@ int proc_dointvec_minmax(const struct ctl_table *table, int dir,
int proc_douintvec_minmax(const struct ctl_table *table, int dir,
void *buffer, size_t *lenp, loff_t *ppos)
{
- return proc_vec(table, dir, buffer, lenp, ppos, PROC_VEC_UINT,
- (union proc_vec_conv){ .uint_conv = do_proc_uint_conv_minmax });
+ return proc_douintvec_conv(table, dir, buffer, lenp, ppos,
+ do_proc_uint_conv_minmax);
}

/**
@@ -976,8 +974,7 @@ int proc_dou8vec_minmax(const struct ctl_table *table, int dir,
tmp.extra2 = (unsigned int *) &max;

val = READ_ONCE(*data);
- res = proc_vec(&tmp, dir, buffer, lenp, ppos, PROC_VEC_UINT,
- (union proc_vec_conv){ .uint_conv = do_proc_uint_conv_minmax });
+ res = proc_douintvec_minmax(&tmp, dir, buffer, lenp, ppos);
if (res)
return res;
if (SYSCTL_USER_TO_KERN(dir))

--
2.50.1