Re: [PATCH v6 3/8] sysctl: Warn when a clamped sysctl parameter is set out of range

2018-05-01 Thread Waiman Long
On 04/30/2018 06:40 PM, Kees Cook wrote:
> I like this series overall, thanks! No objections from me. One thing I
> noted, though:
>
> On Fri, Apr 27, 2018 at 2:00 PM, Waiman Long  wrote:
>> if (param->min && *param->min > val) {
>> if (clamp) {
>> val = *param->min;
>> +   clamped = true;
>> } else {
>> return -EINVAL;
>> }
> This appears as a common bit of logic in many places in the series. It
> seems like it'd make sense to make this a helper of some kind?
>
> -Kees
>
We can't have an inline helper function because the types are different.
We may be able to use a helper macro, but helper macro like that may be
not well accepted by the kernel community.

Cheers,
Longman

--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v6 3/8] sysctl: Warn when a clamped sysctl parameter is set out of range

2018-04-30 Thread Kees Cook
I like this series overall, thanks! No objections from me. One thing I
noted, though:

On Fri, Apr 27, 2018 at 2:00 PM, Waiman Long  wrote:
> if (param->min && *param->min > val) {
> if (clamp) {
> val = *param->min;
> +   clamped = true;
> } else {
> return -EINVAL;
> }

This appears as a common bit of logic in many places in the series. It
seems like it'd make sense to make this a helper of some kind?

-Kees

-- 
Kees Cook
Pixel Security
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v6 3/8] sysctl: Warn when a clamped sysctl parameter is set out of range

2018-04-27 Thread Waiman Long
Even with clamped sysctl parameters, it is still not that straight
forward 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 into the kernel ring buffer when a clamped sysctl parameter
receives an out of range value.

The pr_warn_ratelimited() macro is used to limit the number of warning
messages that can be printed within a given period of time.

Signed-off-by: Waiman Long 
---
 kernel/sysctl.c | 30 ++
 1 file changed, 30 insertions(+)

diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 5b84c1d..76b2f1b 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -17,6 +17,7 @@
  * The list_for_each() macro wasn't appropriate for the sysctl loop.
  *  Removed it and replaced it with older style, 03/23/00, Bill Wendling
  */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include 
 #include 
@@ -2516,6 +2517,7 @@ static int proc_dointvec_minmax_sysadmin(struct ctl_table 
*table, int write,
  * @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
@@ -2525,6 +2527,7 @@ struct do_proc_dointvec_minmax_conv_param {
int *min;
int *max;
uint16_t *flags;
+   const char *name;
 };
 
 static int do_proc_dointvec_minmax_conv(bool *negp, unsigned long *lvalp,
@@ -2534,12 +2537,14 @@ static int do_proc_dointvec_minmax_conv(bool *negp, 
unsigned long *lvalp,
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_SIGNED_RANGE);
 
if (param->min && *param->min > val) {
if (clamp) {
val = *param->min;
+   clamped = true;
} else {
return -EINVAL;
}
@@ -2547,11 +2552,17 @@ static int do_proc_dointvec_minmax_conv(bool *negp, 
unsigned long *lvalp,
if (param->max && *param->max < val) {
if (clamp) {
val = *param->max;
+   clamped = true;
} else {
return -EINVAL;
}
}
*valp = val;
+   if (clamped && param->name)
+   pr_warn_ratelimited("\"%s\" was set out of range [%d, 
%d], clamped to %d.\n",
+   param->name,
+   param->min ? *param->min : -INT_MAX,
+   param->max ? *param->max :  INT_MAX, val);
} else {
int val = *valp;
if (val < 0) {
@@ -2589,6 +2600,7 @@ int proc_dointvec_minmax(struct ctl_table *table, int 
write,
.min = (int *) table->extra1,
.max = (int *) table->extra2,
.flags = >flags,
+   .name  = table->procname,
};
return do_proc_dointvec(table, write, buffer, lenp, ppos,
do_proc_dointvec_minmax_conv, );
@@ -2599,6 +2611,7 @@ int proc_dointvec_minmax(struct ctl_table *table, int 
write,
  * @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
@@ -2608,6 +2621,7 @@ struct do_proc_douintvec_minmax_conv_param {
unsigned int *min;
unsigned int *max;
uint16_t *flags;
+   const char *name;
 };
 
 static int do_proc_douintvec_minmax_conv(unsigned long *lvalp,
@@ -2618,6 +2632,7 @@ static int do_proc_douintvec_minmax_conv(unsigned long 
*lvalp,
 
if (write) {
unsigned int val = *lvalp;
+   bool clamped = false;
bool clamp = param->flags &&
   (*param->flags & CTL_FLAGS_CLAMP_UNSIGNED_RANGE);
 
@@ -2627,6 +2642,7 @@ static int do_proc_douintvec_minmax_conv(unsigned long 
*lvalp,
if (param->min && *param->min > val) {
if (clamp) {
val = *param->min;
+   clamped = true;
} else {
return -ERANGE;
}
@@ -2634,11 +2650,17 @@ static int do_proc_douintvec_minmax_conv(unsigned long 
*lvalp,