[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAK8P3a20SEoYCrp3jOK32oZc9OkiPv+1KTjNZ2GxLbHpY4WexQ@mail.gmail.com>
Date: Thu, 30 Jul 2020 10:11:07 +0200
From: Arnd Bergmann <arnd@...db.de>
To: Denis Efremov <efremov@...ux.com>
Cc: Dan Carpenter <dan.carpenter@...cle.com>,
Peilin Ye <yepeilin.cs@...il.com>,
Jens Axboe <axboe@...nel.dk>,
"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>,
linux-block <linux-block@...r.kernel.org>,
linux-kernel-mentees@...ts.linuxfoundation.org,
Kees Cook <keescook@...omium.org>
Subject: Re: [Linux-kernel-mentees] [PATCH v2] block/floppy: Prevent
kernel-infoleak in raw_cmd_copyout()
> On Wed, Jul 29, 2020 at 3:22 PM Denis Efremov <efremov@...ux.com> wrote:
> And checked for leaks on x86_64 with the script test.sh
> $ cat test.sh
> #!/bin/bash
>
> for i in 4.8 5 6 7 8 9 10
> do
> ./run_container.sh gcc-$i $(pwd)/src $(pwd)/out bash -c 'gcc test.c; ./a.out'
> ./run_container.sh gcc-$i $(pwd)/src $(pwd)/out bash -c 'gcc -O2 test.c; ./a.out'
> ./run_container.sh gcc-$i $(pwd)/src $(pwd)/out bash -c 'gcc -O3 test.c; ./a.out'
> done
>
> No leaks reported. Is it really possible this this kind of init, i.e. cmd = *ptr?
The problem is that the behavior is dependent not just on the compiler
version but
also optimization flags, target architecture and specific structure
layouts. Most
of the time, both gcc and clang will initialize the whole structure
rather than just
the individual members, but you still can't be sure that this is true
for all configurations
that this code runs on, except by using CONFIG_GCC_PLUGIN_STRUCTLEAK.
Kees pointed me to the lib/test_stackinit.c file in the kernel in which he has
collected a number of combinations that are known to trigger the problem.
What I see there though are only cases of struct initializers like
struct test_big_hole var = { .one = arg->one, .two=arg->two, .three
= arg->three, .four = arg->four };
but not the syntax used in the floppy driver:
struct test_big_hole var = *arg;
or the a constructor like
struct test_big_hole var;
var = (struct test_big_hole){ .one = arg->one, .two=arg->two, .three
= arg->three, .four = arg->four };
Kees, do you know whether those two would behave differently?
Would it make sense to also check for those, or am I perhaps
misreading your code and it already gets checked?
Arnd
Powered by blists - more mailing lists