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 --- kernel/sysctl.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/kernel/sysctl.c b/kernel/sysctl.c index ed0e5101949c2fa56e33d543c65175d0ab579fc7..c5fa916e626a336c004d596f4c74f829b1cdc5e1 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -739,10 +739,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; @@ -788,6 +784,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; @@ -872,8 +871,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); } /** @@ -923,8 +921,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); } /** @@ -967,8 +965,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