Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1422288 > unrolled thread

Re: [PATCH 1/1] kernel/sysctl.c: avoid overflow

Started byAndrew Morton <akpm@linux-foundation.org>
First post2016-06-14 22:20 +0200
Last post2016-06-14 23:10 +0200
Articles 6 — 4 participants

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: [PATCH 1/1] kernel/sysctl.c: avoid overflow Andrew Morton <akpm@linux-foundation.org> - 2016-06-14 22:20 +0200
    Re: [PATCH 1/1] kernel/sysctl.c: avoid overflow Willy Tarreau <w@1wt.eu> - 2016-06-14 22:50 +0200
      Re: [PATCH 1/1] kernel/sysctl.c: avoid overflow Dave Young <dyoung@redhat.com> - 2016-06-15 10:40 +0200
        Re: [PATCH 1/1] kernel/sysctl.c: avoid overflow Willy Tarreau <w@1wt.eu> - 2016-06-15 10:50 +0200
          Re: [PATCH 1/1] kernel/sysctl.c: avoid overflow Dave Young <dyoung@redhat.com> - 2016-06-15 11:00 +0200
    Re: [PATCH 1/1] kernel/sysctl.c: avoid overflow Kees Cook <keescook@chromium.org> - 2016-06-14 23:10 +0200

#1422288 — Re: [PATCH 1/1] kernel/sysctl.c: avoid overflow

FromAndrew Morton <akpm@linux-foundation.org>
Date2016-06-14 22:20 +0200
SubjectRe: [PATCH 1/1] kernel/sysctl.c: avoid overflow
Message-ID<rK2Yy-1dW-3@gated-at.bofh.it>
On Sat, 11 Jun 2016 03:33:08 +0200 Heinrich Schuchardt <xypron.glpk@gmx.de> wrote:

> An undetected overflow may occur in do_proc_dointvec_minmax_conv_param.
> 
> ...
>
> --- a/kernel/sysctl.c
> +++ b/kernel/sysctl.c
> @@ -2313,7 +2313,17 @@ 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;
> +		int val;
> +
> +		if (*negp) {
> +			if (*lvalp > (unsigned long) INT_MAX + 1)
> +				return -EINVAL;
> +			val = -*lvalp;
> +		} else {
> +			if (*lvalp > (unsigned long) INT_MAX)
> +				return -EINVAL;
> +			val = *lvalp;
> +		}
>  		if ((param->min && *param->min > val) ||
>  		    (param->max && *param->max < val))
>  			return -EINVAL;

hm.

What happens if someone does

	echo -1 > /proc/foo

expecting to get 0xffffffff?  That's a reasonable shorthand, and if we
change that to spit out EINVAL then people's stuff may break.

[toc] | [next] | [standalone]


#1422316

FromWilly Tarreau <w@1wt.eu>
Date2016-06-14 22:50 +0200
Message-ID<rK3rz-1nX-7@gated-at.bofh.it>
In reply to#1422288
On Tue, Jun 14, 2016 at 01:19:06PM -0700, Andrew Morton wrote:
> On Sat, 11 Jun 2016 03:33:08 +0200 Heinrich Schuchardt <xypron.glpk@gmx.de> wrote:
> 
> > An undetected overflow may occur in do_proc_dointvec_minmax_conv_param.
> > 
> > ...
> >
> > --- a/kernel/sysctl.c
> > +++ b/kernel/sysctl.c
> > @@ -2313,7 +2313,17 @@ 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;
> > +		int val;
> > +
> > +		if (*negp) {
> > +			if (*lvalp > (unsigned long) INT_MAX + 1)
> > +				return -EINVAL;
> > +			val = -*lvalp;
> > +		} else {
> > +			if (*lvalp > (unsigned long) INT_MAX)
> > +				return -EINVAL;
> > +			val = *lvalp;
> > +		}
> >  		if ((param->min && *param->min > val) ||
> >  		    (param->max && *param->max < val))
> >  			return -EINVAL;
> 
> hm.
> 
> What happens if someone does
> 
> 	echo -1 > /proc/foo
> 
> expecting to get 0xffffffff?  That's a reasonable shorthand, and if we
> change that to spit out EINVAL then people's stuff may break.

I'd go even further, I don't see anymore how it becomes possible
to actually *write* 0xffffffff at all! This function is used by
proc_dointvec_minmax() which is used with extra1=&zero and extra2
not set with some unsigned ints to allow the full range to be
configured (eg: dirty_expire_interval is the first I found by a
quick random look).

So for me this change is bogus.

Willy

[toc] | [prev] | [next] | [standalone]


#1422781

FromDave Young <dyoung@redhat.com>
Date2016-06-15 10:40 +0200
Message-ID<rKewG-a9-31@gated-at.bofh.it>
In reply to#1422316
On 06/14/16 at 10:41pm, Willy Tarreau wrote:
> On Tue, Jun 14, 2016 at 01:19:06PM -0700, Andrew Morton wrote:
> > On Sat, 11 Jun 2016 03:33:08 +0200 Heinrich Schuchardt <xypron.glpk@gmx.de> wrote:
> > 
> > > An undetected overflow may occur in do_proc_dointvec_minmax_conv_param.
> > > 
> > > ...
> > >
> > > --- a/kernel/sysctl.c
> > > +++ b/kernel/sysctl.c
> > > @@ -2313,7 +2313,17 @@ 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;
> > > +		int val;
> > > +
> > > +		if (*negp) {
> > > +			if (*lvalp > (unsigned long) INT_MAX + 1)
> > > +				return -EINVAL;
> > > +			val = -*lvalp;
> > > +		} else {
> > > +			if (*lvalp > (unsigned long) INT_MAX)
> > > +				return -EINVAL;
> > > +			val = *lvalp;
> > > +		}
> > >  		if ((param->min && *param->min > val) ||
> > >  		    (param->max && *param->max < val))
> > >  			return -EINVAL;
> > 
> > hm.
> > 
> > What happens if someone does
> > 
> > 	echo -1 > /proc/foo
> > 
> > expecting to get 0xffffffff?  That's a reasonable shorthand, and if we
> > change that to spit out EINVAL then people's stuff may break.
> 
> I'd go even further, I don't see anymore how it becomes possible
> to actually *write* 0xffffffff at all! This function is used by
> proc_dointvec_minmax() which is used with extra1=&zero and extra2
> not set with some unsigned ints to allow the full range to be
> configured (eg: dirty_expire_interval is the first I found by a
> quick random look).

sysctl_writes_strict use extra1 = -1 and extra2 = 1

But I do not get why -1 does not work, 1 < (unsigned long) INT_MAX + 1
so val = -1, it is still right?

> 
> So for me this change is bogus.
> 
> Willy
> 

Thanks
Dave

[toc] | [prev] | [next] | [standalone]


#1422790

FromWilly Tarreau <w@1wt.eu>
Date2016-06-15 10:50 +0200
Message-ID<rKeGm-ez-3@gated-at.bofh.it>
In reply to#1422781
On Wed, Jun 15, 2016 at 04:33:32PM +0800, Dave Young wrote:
> On 06/14/16 at 10:41pm, Willy Tarreau wrote:
> > On Tue, Jun 14, 2016 at 01:19:06PM -0700, Andrew Morton wrote:
> > > On Sat, 11 Jun 2016 03:33:08 +0200 Heinrich Schuchardt <xypron.glpk@gmx.de> wrote:
> > > 
> > > > An undetected overflow may occur in do_proc_dointvec_minmax_conv_param.
> > > > 
> > > > ...
> > > >
> > > > --- a/kernel/sysctl.c
> > > > +++ b/kernel/sysctl.c
> > > > @@ -2313,7 +2313,17 @@ 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;
> > > > +		int val;
> > > > +
> > > > +		if (*negp) {
> > > > +			if (*lvalp > (unsigned long) INT_MAX + 1)
> > > > +				return -EINVAL;
> > > > +			val = -*lvalp;
> > > > +		} else {
> > > > +			if (*lvalp > (unsigned long) INT_MAX)
> > > > +				return -EINVAL;
> > > > +			val = *lvalp;
> > > > +		}
> > > >  		if ((param->min && *param->min > val) ||
> > > >  		    (param->max && *param->max < val))
> > > >  			return -EINVAL;
> > > 
> > > hm.
> > > 
> > > What happens if someone does
> > > 
> > > 	echo -1 > /proc/foo
> > > 
> > > expecting to get 0xffffffff?  That's a reasonable shorthand, and if we
> > > change that to spit out EINVAL then people's stuff may break.
> > 
> > I'd go even further, I don't see anymore how it becomes possible
> > to actually *write* 0xffffffff at all! This function is used by
> > proc_dointvec_minmax() which is used with extra1=&zero and extra2
> > not set with some unsigned ints to allow the full range to be
> > configured (eg: dirty_expire_interval is the first I found by a
> > quick random look).
> 
> sysctl_writes_strict use extra1 = -1 and extra2 = 1
> 
> But I do not get why -1 does not work, 1 < (unsigned long) INT_MAX + 1
> so val = -1, it is still right?

-1 should indeed work but 0xffffffff will definitely not.

Willy

[toc] | [prev] | [next] | [standalone]


#1422800

FromDave Young <dyoung@redhat.com>
Date2016-06-15 11:00 +0200
Message-ID<rKeQ2-iF-15@gated-at.bofh.it>
In reply to#1422790
On 06/15/16 at 10:40am, Willy Tarreau wrote:
> On Wed, Jun 15, 2016 at 04:33:32PM +0800, Dave Young wrote:
> > On 06/14/16 at 10:41pm, Willy Tarreau wrote:
> > > On Tue, Jun 14, 2016 at 01:19:06PM -0700, Andrew Morton wrote:
> > > > On Sat, 11 Jun 2016 03:33:08 +0200 Heinrich Schuchardt <xypron.glpk@gmx.de> wrote:
> > > > 
> > > > > An undetected overflow may occur in do_proc_dointvec_minmax_conv_param.
> > > > > 
> > > > > ...
> > > > >
> > > > > --- a/kernel/sysctl.c
> > > > > +++ b/kernel/sysctl.c
> > > > > @@ -2313,7 +2313,17 @@ 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;
> > > > > +		int val;
> > > > > +
> > > > > +		if (*negp) {
> > > > > +			if (*lvalp > (unsigned long) INT_MAX + 1)
> > > > > +				return -EINVAL;
> > > > > +			val = -*lvalp;
> > > > > +		} else {
> > > > > +			if (*lvalp > (unsigned long) INT_MAX)
> > > > > +				return -EINVAL;
> > > > > +			val = *lvalp;
> > > > > +		}
> > > > >  		if ((param->min && *param->min > val) ||
> > > > >  		    (param->max && *param->max < val))
> > > > >  			return -EINVAL;
> > > > 
> > > > hm.
> > > > 
> > > > What happens if someone does
> > > > 
> > > > 	echo -1 > /proc/foo
> > > > 
> > > > expecting to get 0xffffffff?  That's a reasonable shorthand, and if we
> > > > change that to spit out EINVAL then people's stuff may break.
> > > 
> > > I'd go even further, I don't see anymore how it becomes possible
> > > to actually *write* 0xffffffff at all! This function is used by
> > > proc_dointvec_minmax() which is used with extra1=&zero and extra2
> > > not set with some unsigned ints to allow the full range to be
> > > configured (eg: dirty_expire_interval is the first I found by a
> > > quick random look).
> > 
> > sysctl_writes_strict use extra1 = -1 and extra2 = 1
> > 
> > But I do not get why -1 does not work, 1 < (unsigned long) INT_MAX + 1
> > so val = -1, it is still right?
> 
> -1 should indeed work but 0xffffffff will definitely not.

Hmm, right, indeed.

Below echo works originally:
echo 0xffffffff > /proc/sys/kernel/sysctl_writes_strict

> 
> Willy

Thanks
Dave

[toc] | [prev] | [next] | [standalone]


#1422338

FromKees Cook <keescook@chromium.org>
Date2016-06-14 23:10 +0200
Message-ID<rK3KW-1Jw-21@gated-at.bofh.it>
In reply to#1422288
On Tue, Jun 14, 2016 at 1:19 PM, Andrew Morton
<akpm@linux-foundation.org> wrote:
> On Sat, 11 Jun 2016 03:33:08 +0200 Heinrich Schuchardt <xypron.glpk@gmx.de> wrote:
>
>> An undetected overflow may occur in do_proc_dointvec_minmax_conv_param.
>>
>> ...
>>
>> --- a/kernel/sysctl.c
>> +++ b/kernel/sysctl.c
>> @@ -2313,7 +2313,17 @@ 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;
>> +             int val;
>> +
>> +             if (*negp) {
>> +                     if (*lvalp > (unsigned long) INT_MAX + 1)
>> +                             return -EINVAL;
>> +                     val = -*lvalp;
>> +             } else {
>> +                     if (*lvalp > (unsigned long) INT_MAX)
>> +                             return -EINVAL;
>> +                     val = *lvalp;
>> +             }
>>               if ((param->min && *param->min > val) ||
>>                   (param->max && *param->max < val))
>>                       return -EINVAL;
>
> hm.
>
> What happens if someone does
>
>         echo -1 > /proc/foo
>
> expecting to get 0xffffffff?  That's a reasonable shorthand, and if we
> change that to spit out EINVAL then people's stuff may break.

If we expect the interface to allow overflows, we should at least add
comments to do_proc_dointvec_minmax_conv_param()...

-Kees

-- 
Kees Cook
Chrome OS & Brillo Security

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web