The patch titled Subject: kernel/sysctl.c: warn when a clamped sysctl parameter is set out of range has been added to the -mm tree. Its filename is sysctl-warn-when-a-clamped-sysctl-parameter-is-set-out-of-range.patch This patch should soon appear at http://ozlabs.org/~akpm/mmots/broken-out/sysctl-warn-when-a-clamped-sysctl-parameter-is-set-out-of-range.patch and later at http://ozlabs.org/~akpm/mmotm/broken-out/sysctl-warn-when-a-clamped-sysctl-parameter-is-set-out-of-range.patch Before you just go and hit "reply", please: a) Consider who else should be cc'ed b) Prefer to cc a suitable mailing list as well c) Ideally: find the original patch on the mailing list and do a reply-to-all to that, adding suitable additional cc's *** Remember to use Documentation/SubmitChecklist when testing your code *** The -mm tree is included into linux-next and is updated there every 3-4 working days ------------------------------------------------------ From: Waiman Long <longman@xxxxxxxxxx> Subject: kernel/sysctl.c: warn when a clamped sysctl parameter is set out of range Even with clamped sysctl parameters, it is still not that straightforward to figure out the exact range of those parameters. One may try to write extreme parameter values to see if they get clamped. To make it easier, a warning with the expected range will now be printed in the kernel ring buffer when a clamped sysctl parameter receives an out of range value. Link: http://lkml.kernel.org/r/1519926220-7453-5-git-send-email-longman@xxxxxxxxxx Signed-off-by: Waiman Long <longman@xxxxxxxxxx> Reviewed-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> Cc: Al Viro <viro@xxxxxxxxxxxxxxxxxx> Cc: Davidlohr Bueso <dave@xxxxxxxxxxxx> Cc: Kees Cook <keescook@xxxxxxxxxxxx> Cc: "Luis R. Rodriguez" <mcgrof@xxxxxxxxxx> Cc: Manfred Spraul <manfred@xxxxxxxxxxxxxxxx> Cc: Matthew Wilcox <willy@xxxxxxxxxxxxx> Cc: Randy Dunlap <rdunlap@xxxxxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- include/linux/sysctl.h | 3 ++ kernel/sysctl.c | 52 +++++++++++++++++++++++++++++++++------ 2 files changed, 47 insertions(+), 8 deletions(-) diff -puN include/linux/sysctl.h~sysctl-warn-when-a-clamped-sysctl-parameter-is-set-out-of-range include/linux/sysctl.h --- a/include/linux/sysctl.h~sysctl-warn-when-a-clamped-sysctl-parameter-is-set-out-of-range +++ a/include/linux/sysctl.h @@ -130,11 +130,14 @@ struct ctl_table * @CTL_FLAGS_CLAMP_RANGE: Set to indicate that the entry should be * flexibly clamped to min/max range in case the user provided * an incorrect value. + * @CTL_FLAGS_OOR_WARNED: Set to indicate that an out of range warning + * had been issued for that entry. * * At most 16 different flags will be allowed. */ enum ctl_table_flags { CTL_FLAGS_CLAMP_RANGE = BIT(0), + CTL_FLAGS_OOR_WARNED = BIT(1), }; struct ctl_node { diff -puN kernel/sysctl.c~sysctl-warn-when-a-clamped-sysctl-parameter-is-set-out-of-range kernel/sysctl.c --- a/kernel/sysctl.c~sysctl-warn-when-a-clamped-sysctl-parameter-is-set-out-of-range +++ a/kernel/sysctl.c @@ -2505,6 +2505,7 @@ static int proc_dointvec_minmax_sysadmin * @min: pointer to minimum allowable value * @max: pointer to maximum allowable value * @flags: pointer to flags + * @name: sysctl parameter name * * The do_proc_dointvec_minmax_conv_param structure provides the * minimum and maximum values for doing range checking for those sysctl @@ -2514,31 +2515,50 @@ struct do_proc_dointvec_minmax_conv_para int *min; int *max; uint16_t *flags; + const char *name; }; +/* Out of range warning message */ +#define proc_ctl_warn(type, ...) \ + pr_warn("Kernel parameter \"%s\" was set out of range [%" \ + #type ", %" #type "], clamped to %" #type ".\n", __VA_ARGS__) + static int do_proc_dointvec_minmax_conv(bool *negp, unsigned long *lvalp, int *valp, int write, void *data) { struct do_proc_dointvec_minmax_conv_param *param = data; + if (write) { int val = *negp ? -*lvalp : *lvalp; + bool clamped = false; bool clamp = param->flags && (*param->flags & CTL_FLAGS_CLAMP_RANGE); if (param->min && *param->min > val) { - if (clamp) + if (clamp) { val = *param->min; - else + clamped = true; + } else { return -EINVAL; + } } if (param->max && *param->max < val) { - if (clamp) + if (clamp) { val = *param->max; - else + clamped = true; + } else { return -EINVAL; + } } *valp = val; + if (clamped && param->name && + !(*param->flags & CTL_FLAGS_OOR_WARNED)) { + proc_ctl_warn(d, param->name, + param->min ? *param->min : -INT_MAX, + param->max ? *param->max : INT_MAX, val); + *param->flags |= CTL_FLAGS_OOR_WARNED; + } } else { int val = *valp; if (val < 0) { @@ -2576,6 +2596,7 @@ int proc_dointvec_minmax(struct ctl_tabl .min = (int *) table->extra1, .max = (int *) table->extra2, .flags = &table->flags, + .name = table->procname, }; return do_proc_dointvec(table, write, buffer, lenp, ppos, do_proc_dointvec_minmax_conv, ¶m); @@ -2586,6 +2607,7 @@ int proc_dointvec_minmax(struct ctl_tabl * @min: pointer to minimum allowable value * @max: pointer to maximum allowable value * @flags: pointer to flags + * @name: sysctl parameter name * * The do_proc_douintvec_minmax_conv_param structure provides the * minimum and maximum values for doing range checking for those sysctl @@ -2595,6 +2617,7 @@ struct do_proc_douintvec_minmax_conv_par unsigned int *min; unsigned int *max; uint16_t *flags; + const char *name; }; static int do_proc_douintvec_minmax_conv(unsigned long *lvalp, @@ -2605,6 +2628,7 @@ static int do_proc_douintvec_minmax_conv if (write) { unsigned int val = *lvalp; + bool clamped = false; bool clamp = param->flags && (*param->flags & CTL_FLAGS_CLAMP_RANGE); @@ -2612,18 +2636,29 @@ static int do_proc_douintvec_minmax_conv return -EINVAL; if (param->min && *param->min > val) { - if (clamp) + if (clamp) { val = *param->min; - else + clamped = true; + } else { return -ERANGE; + } } if (param->max && *param->max < val) { - if (clamp) + if (clamp) { val = *param->max; - else + clamped = true; + } else { return -ERANGE; + } } *valp = val; + if (clamped && param->name && + !(*param->flags & CTL_FLAGS_OOR_WARNED)) { + proc_ctl_warn(u, param->name, + param->min ? *param->min : 0, + param->max ? *param->max : UINT_MAX, val); + *param->flags |= CTL_FLAGS_OOR_WARNED; + } } else { unsigned int val = *valp; *lvalp = (unsigned long) val; @@ -2659,6 +2694,7 @@ int proc_douintvec_minmax(struct ctl_tab .min = (unsigned int *) table->extra1, .max = (unsigned int *) table->extra2, .flags = &table->flags, + .name = table->procname, }; return do_proc_douintvec(table, write, buffer, lenp, ppos, do_proc_douintvec_minmax_conv, ¶m); _ Patches currently in -mm which might be from longman@xxxxxxxxxx are list_lru-prefetch-neighboring-list-entries-before-acquiring-lock.patch proc-sysctl-fix-typo-in-sysctl_check_table_array.patch sysctl-add-kdoc-comments-to-do_proc_douintvec_minmax_conv_param.patch sysctl-add-flags-to-support-min-max-range-clamping.patch sysctl-warn-when-a-clamped-sysctl-parameter-is-set-out-of-range.patch ipc-clamp-msgmni-and-shmmni-to-the-real-ipcmni-limit.patch ipc-clamp-semmni-to-the-real-ipcmni-limit.patch -- To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html