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 <[email protected]>
---
 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



Reply via email to