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


Groups > linux.kernel > #1551709 > unrolled thread

Re: [PATCH 1/1] x86: sanitize argument of clearcpuid command-line option

Started byIngo Molnar <mingo@kernel.org>
First post2017-01-05 09:00 +0100
Last post2017-01-16 20:00 +0100
Articles 2 — 2 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] x86: sanitize argument of clearcpuid command-line  option Ingo Molnar <mingo@kernel.org> - 2017-01-05 09:00 +0100
    RE: [PATCH 1/1] x86: sanitize argument of clearcpuid command-line  option "Odzioba, Lukasz" <lukasz.odzioba@intel.com> - 2017-01-16 20:00 +0100

#1551709 — Re: [PATCH 1/1] x86: sanitize argument of clearcpuid command-line option

FromIngo Molnar <mingo@kernel.org>
Date2017-01-05 09:00 +0100
SubjectRe: [PATCH 1/1] x86: sanitize argument of clearcpuid command-line option
Message-ID<sWb7Q-8fR-27@gated-at.bofh.it>
* Borislav Petkov <bp@alien8.de> wrote:

> On Wed, Dec 28, 2016 at 02:55:40PM +0100, Lukasz Odzioba wrote:
> > A negative number can be specified in the cmdline which will be used as
> > setup_clear_cpu_cap() argument. With that we can clear/set some bit in
> > memory predceeding boot_cpu_data/cpu_caps_cleared which may cause kernel
> > to misbehave. This patch adds lower bound check to setup_disablecpuid().
> > 
> > Fixes: ac72e7888a61 ("x86: add generic clearcpuid=... option")
> > 
> > Signed-off-by: Lukasz Odzioba <lukasz.odzioba@intel.com>
> > ---
> > As an example let's change definition of one_hundred variable:
> > ffffffff81c4eeec d one_hundred
> > ffffffff81d69720 D boot_cpu_data (0x14 is x86_capability offset)
> > 
> > 8*(0xffffffff81d69734-0xffffffff81c4eeec) => 9257536 -2 because we
> > want to clear the second bit. With clearcpuid=-9257534 we change the
> > definition of one_hundread to 96 which is used among other things
> > as sysfs' max value for swappiness, so we can check the effect like so:
> > # echo 96 >  /proc/sys/vm/swappiness
> > # echo 97 >  /proc/sys/vm/swappiness
> > -bash: echo: write error: Invalid argument
> > ---
> >  arch/x86/kernel/cpu/common.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
> > index dc1697c..9bab7a8 100644
> > --- a/arch/x86/kernel/cpu/common.c
> > +++ b/arch/x86/kernel/cpu/common.c
> > @@ -1221,7 +1221,7 @@ static __init int setup_disablecpuid(char *arg)
> >  {
> >  	int bit;
> >  
> > -	if (get_option(&arg, &bit) && bit < NCAPINTS*32)
> > +	if (get_option(&arg, &bit) && bit >= 0 && bit < NCAPINTS * 32)
> >  		setup_clear_cpu_cap(bit);
> >  	else
> >  		return 0;
> > -- 
> 
> Yap, that's a good catch!
> 
> Acked-by: Borislav Petkov <bp@suse.de>
> 
> I even got a splat while experimenting with this:
> 
> 
> [    1.234575] BUG: unable to handle kernel paging request at ffffffff858bd540
> [    1.236535] IP: memcpy_erms+0x6/0x10

Good one, queued it up.

Btw., another (separate) fix would be to keep the kernel's option filtering code 
from being passive aggressive:

        if (get_option(&arg, &bit) && bit >= 0 && bit < NCAPINTS * 32)
                setup_clear_cpu_cap(bit);
        else
                return 0;

When we don't accept the value we should at least inform the user (via a printk 
that includes the 'clearcpuid' token in its message) that we totally ignored 
whatever he wanted. Something like:

	pr_warn("x86/cpu: Ignoring invalid "clearcpuid=%s' option!\n", arg)

Which would save quite a bit of head scratching and frustration when someone has a 
bad enough day to add silly typos to the kernel cmdline.

Thanks,

	Ingo

[toc] | [next] | [standalone]


#1559987

From"Odzioba, Lukasz" <lukasz.odzioba@intel.com>
Date2017-01-16 20:00 +0100
Message-ID<t0kFz-4uU-7@gated-at.bofh.it>
In reply to#1551709
On Thursday, January 5, 2017 8:56 AM, Ingo Molnar wrote:
>
> Good one, queued it up.

Hi Ingo, thanks for picking up the patch.

> When we don't accept the value we should at least inform the user (via a printk 
> that includes the 'clearcpuid' token in its message) that we totally ignored 
> whatever he wanted. Something like:
> 
>	pr_warn("x86/cpu: Ignoring invalid "clearcpuid=%s' option!\n", arg)
>
> Which would save quite a bit of head scratching and frustration when someone has a 
> bad enough day to add silly typos to the kernel cmdline.

Is there any particular reason why we have such warnings only for early params?
early_param handlers return non-zero values on success:
	linux/init.h: " * Emits warning if fn returns non-zero."
__setup handlers in most cases seem to return 1 on success, is the expected
behaviour documented somewhere?

After looking at some of the ~500 usages of __setup macro it seems that handler's ret
code doesn't matter so much, because it is treated differently in various parts
of the kernel. If we make it consistent possibly it could be solved similarly to 
early params by something like this: 

diff --git a/init/main.c b/init/main.c
index b0c9d6f..261178e 100644
--- a/init/main.c
+++ b/init/main.c
@@ -182,8 +182,12 @@ static bool __init obsolete_checksetup(char *line)
                                pr_warn("Parameter %s is obsolete, ignored\n",
                                        p->str);
                                return true;
-                       } else if (p->setup_func(line + n))
-                               return true;
+                       } else {
+                               if (p->setup_func(line + n))
+                                       return true;
+                               else
+                                       pr_warn("Malformed option '%s'\n", line);
+                       }

Thanks,
Lukas

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web