Discussion:
signed kernel modules?
David Howells
2004-10-11 15:11:22 UTC
Permalink
> Sign the whole thing. Use a signature format which doesn't suck (ASN1
> parsing in the kernel? Hmm...). Have your build system spit out two
> RPMs, one with full debug modules, and one without. This is not rocket
> science.

You make it sound so simple...

I've adapted my patches to sign the whole thing 'cos I know you're just going
to fight it otherwise[*]:-)

However, I'm having trouble getting it working... I didn't realise just how
many strips get applied to the module before it gets loaded into the kernel
(when making initrd's for instance):-/

The old way of just signing the stuff that is required is definitely more
robust against all the valid things people want to be able to do to modules,
especially those involving strip for the purposes of producing initrds and
stuff. Some of this is done upon or after installation where it isn't possible
to get hold of the private key[**].

I could make the signature section non-ALLOC, but that would just mean that
any stripped module is unsigned.

Since much of ELF is an arch-independent format, I think my latest "signing
only the requisite bits" method _is_ sufficient. You say that you can see a
gaping security hole - please elaborate... it may not be what you think.

David

[*] You're still wrong, of course, but that's your prerogative:-)

[**] Before anyone suggests it, no, I'm not going to ship the private key just
so that the module can be re-signed after stripping.
David Woodhouse
2004-10-11 15:15:55 UTC
Permalink
On Mon, 2004-10-11 at 16:11 +0100, David Howells wrote:
> > Sign the whole thing. Use a signature format which doesn't suck (ASN1
> > parsing in the kernel? Hmm...). Have your build system spit out two
> > RPMs, one with full debug modules, and one without. This is not rocket
> > science.
>
> You make it sound so simple...
>
> I've adapted my patches to sign the whole thing

Why on earth would you want to sign the whole thing? As you've observed,
that means the signature gets broken when the debug info is stripped,
etc. Sign just what the kernel actually _looks_ at, nothing more.

Signing the whole thing is just silly. If you're going to include random
extra irrelevant stuff like comment sections and debug info, then you
might as well include the inode number and device on which the .ko file
is stored too -- so it breaks when you 'cp' it.

> 'cos I know you're just going to fight it otherwise[*]:-)

<...>

> [*] You're still wrong, of course, but that's your prerogative:-)

That doesn't mean you have to pander to him.

--
dwmw2
Rusty Russell (IBM)
2004-10-11 22:34:50 UTC
Permalink
On Tue, 2004-10-12 at 01:15, David Woodhouse wrote:
> On Mon, 2004-10-11 at 16:11 +0100, David Howells wrote:
> > > Sign the whole thing. Use a signature format which doesn't suck (ASN1
> > > parsing in the kernel? Hmm...). Have your build system spit out two
> > > RPMs, one with full debug modules, and one without. This is not rocket
> > > science.
> >
> > You make it sound so simple...
> >
> > I've adapted my patches to sign the whole thing
>
> Why on earth would you want to sign the whole thing? As you've observed,
> that means the signature gets broken when the debug info is stripped,
> etc. Sign just what the kernel actually _looks_ at, nothing more.

Welcome to the debate David. I agree that you only need to sign the
things that the kernel looks at, unfortunately, there's not a nice clear
line: for example the headers change when you strip the module, and they
need to be signed.

Trying to work around it just gets you into more and more complexity:
you can't trust the module until you've checked the signature, and when
you don't trust the module you have to write paranoid code, which is
very ugly and causes bloat. David Howells just sidestepped this and
trusted the module headers, and so I refused his patch.

> > [*] You're still wrong, of course, but that's your prerogative:-)
>
> That doesn't mean you have to pander to him.

Nor do I have to re-iterate the points from the discussion for someone
who hasn't bothered reading it. But I did.

Rusty.
David Woodhouse
2004-10-12 08:35:59 UTC
Permalink
On Tue, 2004-10-12 at 08:34 +1000, Rusty Russell (IBM) wrote:
> Welcome to the debate David. I agree that you only need to sign the
> things that the kernel looks at, unfortunately, there's not a nice clear
> line: for example the headers change when you strip the module, and they
> need to be signed.

First you agree that we only need to sign the things the kernel looks
at, but then you seem to be saying we need to sign _all_ of the headers.
That isn't consistent, surely?

Think of it as canonicalising the module before we sign it.
Conceptually, we strip the module and make a signature on the bits which
are actually _relevant_, not on the fluff. It's just that we want to do
what while being able to leave the debug information and all the
irrelevant symbols etc. in place in the object file.

We know _precisely_ what the kernel looks at -- we wrote its linker. It
really isn't that hard.

> Trying to work around it just gets you into more and more complexity:
> you can't trust the module until you've checked the signature, and when
> you don't trust the module you have to write paranoid code, which is
> very ugly and causes bloat. David Howells just sidestepped this and
> trusted the module headers, and so I refused his patch.

If there's something specific which he wasn't checking which could
actually make a _real_ difference to the module once it's loaded and
linked, please point it out.

Trusting _just_ the headers doesn't seem to make sense, I agree --
surely you actually want to include the contents of the text and data
sections in your signature? Are you saying David didn't do that? That
would want fixing, obviously. But it doesn't mean that we should be
signing the _whole_ of the object file, irrelevant parts and all.

> Nor do I have to re-iterate the points from the discussion for someone
> who hasn't bothered reading it. But I did.

Sorry, I didn't think the discussion had been in public. While I'm sure
I _could_ read mail in David's inbox, I feel it would be somewhat
impolite. It's not that I "haven't bothered". :)

--
dwmw2
Greg KH
2004-10-12 19:08:26 UTC
Permalink
On Tue, Oct 12, 2004 at 09:35:59AM +0100, David Woodhouse wrote:
>
> We know _precisely_ what the kernel looks at -- we wrote its linker. It
> really isn't that hard.

I agree. We have to be able to detect improper header information for
unsigned modules today, nothing new there. So by only signing the
information that the kernel looks at, we should be fine.

Or am I missing some big flaw in the above argument?

thanks,

greg k-h
Rusty Russell (IBM)
2004-10-13 00:20:35 UTC
Permalink
On Wed, 2004-10-13 at 05:08, Greg KH wrote:
> On Tue, Oct 12, 2004 at 09:35:59AM +0100, David Woodhouse wrote:
> >
> > We know _precisely_ what the kernel looks at -- we wrote its linker. It
> > really isn't that hard.
>
> I agree. We have to be able to detect improper header information for
> unsigned modules today, nothing new there.

No, we *don't*. We check that it's the right arch, and ELF, and not
truncated. Then we trust the contents.

I realize that ignorance is bliss, but if you want to debate this, I
recommend reading some code...

Rusty.
David Woodhouse
2004-10-13 08:24:13 UTC
Permalink
On Wed, 2004-10-13 at 10:20 +1000, Rusty Russell (IBM) wrote:
> On Wed, 2004-10-13 at 05:08, Greg KH wrote:
> > On Tue, Oct 12, 2004 at 09:35:59AM +0100, David Woodhouse wrote:
> > >
> > > We know _precisely_ what the kernel looks at -- we wrote its linker. It
> > > really isn't that hard.
> >
> > I agree. We have to be able to detect improper header information for
> > unsigned modules today, nothing new there.
>
> No, we *don't*. We check that it's the right arch, and ELF, and not
> truncated. Then we trust the contents.

"We have to" != "We actually do". He's right. You're right. We _have_ to
do this already, but we suck and actually we don't. David's working on
that, I believe.

--
dwmw2
David Howells
2004-10-12 19:16:08 UTC
Permalink
>
> I agree. We have to be able to detect improper header information for
> unsigned modules today, nothing new there. So by only signing the
> information that the kernel looks at, we should be fine.

I'm writing an ELF checker to go with my module signature checker. I'll put it
up for approval, flames, etc.. in a bit. As soon as I can persuade gdb that,
yes, it _does_ want to debug 64-bit code...

David
David Howells
2004-10-12 20:43:04 UTC
Permalink
> I agree. We have to be able to detect improper header information for
> unsigned modules today, nothing new there. So by only signing the
> information that the kernel looks at, we should be fine.

Take a look at:

http://people.redhat.com/~dhowells/modsign/modsign-bits.tar.bz2

I've extracted the module signing and module verification stuff into a
userspace test harness for easier development.

Note that this module verifier will only work on PPC64 (well, it might work on
other big-endian ELF64 archs too) without messing around in the included
header files.

The module signer should work on anything, and should be able sign any sort of
ELF, no matter whether it's the same endianness or wordsize as the host CPU.

I've added an ELF verification function in checksig/module-verify.c that does
a reasonably comprehensive check of the ELF that might cause the kernel to
crash if it loads a module.

Run "make test" to build everything, check the unsigned module, sign the
module and check the signed module.

David
Rusty Russell (IBM)
2004-10-13 00:11:36 UTC
Permalink
On Tue, 2004-10-12 at 18:35, David Woodhouse wrote:
> We know _precisely_ what the kernel looks at -- we wrote its linker. It
> really isn't that hard.

Write the code. Then come back and tell me it "isn't that hard".

Let me make this clear: I refuse to include any solution which doesn't
protect against accidental, as well as deliberate, corruption. This
means your "canonicalization" code has to be very, very paranoid about
not trusting the data until the signature is verified. The current code
does very simple checks then completely trusts the module contents,
especially the section headers: to make signatures worth anything, your
code must not do this.

Here's the level of paranoia required for the simplest case, that of
signing the entire module. The last Howells patches I saw didn't even
do any of *this*, let alone checking the rest of the module:

+static int in_range(Elf_Ehdr *hdr,
+ unsigned long len,
+ unsigned long offset,
+ unsigned long elemsize,
+ unsigned long num)
+{
+ /* We're careful with wrap here. */
+ if (offset > len)
+ return 0;
+ if (elemsize * num / num != elemsize)
+ return 0;
+ if (elemsize * num > len - offset)
+ return 0;
+ return 1;
+}
+
+/* Lots of checking: we don't trust anything until signature matched. */
+static int check_modsig(Elf_Ehdr *hdr, unsigned long len)
+{
+ Elf_Shdr *sechdrs;
+ unsigned long i, stroff;
+
+ /* Section headers must all be in range. */
+ if (!in_range(hdr, len, hdr->e_shoff, sizeof(Elf_Shdr), hdr->e_shnum))
+ return -EINVAL;
+
+ /* Index of section which contains headers must be good. */
+ if (hdr->e_shstrndx >= hdr->e_shnum)
+ return -EINVAL;
+
+ sechdrs = (void *)hdr + hdr->e_shoff;
+ stroff = sechdrs[hdr->e_shstrndx].sh_offset;
+
+ for (i = 1; i < hdr->e_shnum; i++) {
+ if (!in_range(hdr, len, stroff+sechdrs[i].sh_name, 1,
+ sizeof("module_sig")))
+ continue;
+ if (strcmp((char *)hdr + stroff+sechdrs[i].sh_name,
+ "module_sig") != 0)
+ continue;
+ if (!in_range(hdr, len, sechdrs[i].sh_offset,
+ sechdrs[i].sh_size, 1))
+ return -EINVAL;
+ return calc_signature(hdr, len, sechdrs[i].sh_offset,
+ sechdrs[i].sh_size);
+ }
+ tainted |= TAINT_FORCED_MODULE;
+ return 0;
+}
+#else
+static int check_modsig(Elf_Ehdr *hdr, unsigned int len)
+{
+ return 0;
+}
+#endif /* CONFIG_MODULE_SIG */
+
#ifdef CONFIG_SMP
/* Number of blocks used and allocated. */
static unsigned int pcpu_num_used, pcpu_num_allocated;
@@ -1522,6 +1614,9 @@ static struct module *load_module(void _
if (len < hdr->e_shoff + hdr->e_shnum * sizeof(Elf_Shdr))
goto truncated;

+ if ((err = check_modsig(hdr, len)) != 0)
+ goto free_hdr;
+
/* Convenience variables */
sechdrs = (void *)hdr + hdr->e_shoff;
secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;

> > Nor do I have to re-iterate the points from the discussion for someone
> > who hasn't bothered reading it. But I did.
>
> Sorry, I didn't think the discussion had been in public. While I'm sure
> I _could_ read mail in David's inbox, I feel it would be somewhat
> impolite. It's not that I "haven't bothered". :)

Sorry, thought you were CC'd the whole time. My mistake.

Rusty.
David Woodhouse
2004-10-13 09:16:33 UTC
Permalink
On Wed, 2004-10-13 at 10:11 +1000, Rusty Russell (IBM) wrote:
> Here's the level of paranoia required for the simplest case, that of
> signing the entire module. The last Howells patches I saw didn't even
> do any of *this*, let alone checking the rest of the module:

It's work in progress, and from my limited and third-hand understanding
of what went on before this thread became public, you seemed to be
railing against the _concept_ not against the implementation.

We agree that the checks you cite are required. In fact we should have
been doing a lot of these checks even _before_ we thought about signing
modules.

That said, I think it was perfectly reasonable for David to leave the
implementation of this level of paranoia till last, after working out
the details of how the signatures actually work.

After all, until the precise signature scheme is agreed upon we don't
really know how much of the ELF we should be paranoid about, and how
much we can trust because it's signed.

In David's original scheme, the signature covered only the relevant
parts of the module, so it survives the removal of debug info, and it
survives the further 'strip' it gets on being put into an initrd -- but
the signature _doesn't_ survive anything which would actually change
what happens when the module is loaded.

If your objection to that is purely on the perfectly reasonable grounds
that we're overly trusting of what could be invalid ELF, and could kill
us before we actually get to checking the signature, we can just wait
for him to complete what he's working on at the moment and all will
presumably be well.

I had the impression you were rabidly against any scheme which didn't
sign the _whole_ module, irrelevant parts and all.

--
dwmw2
Alan Cox
2004-10-13 10:42:19 UTC
Permalink
On Mer, 2004-10-13 at 01:11, Rusty Russell (IBM) wrote:
> + unsigned long len,
> + unsigned long offset,
> + unsigned long elemsize,
> + unsigned long num)
> +{
> + /* We're careful with wrap here. */
> + if (offset > len)
> + return 0;
> + if (elemsize * num / num != elemsize)

Whoops bang "num 0 elements". That check set isn't safe standalone
Rusty Russell (IBM)
2004-10-13 21:21:16 UTC
Permalink
On Wed, 2004-10-13 at 19:16, David Woodhouse wrote:
> On Wed, 2004-10-13 at 10:11 +1000, Rusty Russell (IBM) wrote:
> > Here's the level of paranoia required for the simplest case, that of
> > signing the entire module. The last Howells patches I saw didn't even
> > do any of *this*, let alone checking the rest of the module:
>
> We agree that the checks you cite are required. In fact we should have
> been doing a lot of these checks even _before_ we thought about signing
> modules.

No. What a complete and utter waste of time and code! At the moment,
we do minimum checks; this is because we don't even try to keep out
malicious code. At the moment, flip and random bit in a module and
you'll get weird behaviour. We don't check for that because we can't:
it's most likely in data or text anyway.

Now. if you're adding a signature, I insist that it should do detect all
relevant changes. Calling David's a "work in progress" and that "I'm
sure these problems will be fixed" doesn't ignore the fact that he has
resisted fixing them so far. He just doesn't seem to understand: could
you explain it to him please?

You are arguing that he should add elaborate checks, with care for those
arch-specific hooks and the requisite paranoia. I'm arguing that he
should just sum the whole module and be done. My method is far simpler,
with the cost that stripping the module requires a signature update.

If you really insist that the complexity is worth it, I want to see the
code. ALL the code. Because at the moment you're cheating.

Rusty.
Rusty Russell (IBM)
2004-10-13 22:40:39 UTC
Permalink
On Wed, 2004-10-13 at 20:42, Alan Cox wrote:
> On Mer, 2004-10-13 at 01:11, Rusty Russell (IBM) wrote:
> > + unsigned long len,
> > + unsigned long offset,
> > + unsigned long elemsize,
> > + unsigned long num)
> > +{
> > + /* We're careful with wrap here. */
> > + if (offset > len)
> > + return 0;
> > + if (elemsize * num / num != elemsize)
>
> Whoops bang "num 0 elements". That check set isn't safe standalone

Thanks, Alan.

I'd appreciate your opinion on the issue at hand. Is it worth 600 lines
of ELF verification and canonicalization code so we can strip modules
without altering the signature?

Rusty.
Alan Cox
2004-10-14 23:44:41 UTC
Permalink
On Mer, 2004-10-13 at 23:40, Rusty Russell (IBM) wrote:
> > Whoops bang "num 0 elements". That check set isn't safe standalone
>
> Thanks, Alan.
>
> I'd appreciate your opinion on the issue at hand. Is it worth 600 lines
> of ELF verification and canonicalization code so we can strip modules
> without altering the signature?

I'm unconvinced at the moment, it seems it would be easier to write the
neccessary code to do this in userspace, and then sign the canonicalised
module so that the kernel interface is small and clean.
Rusty Russell (IBM)
2004-10-15 01:00:27 UTC
Permalink
On Fri, 2004-10-15 at 09:44, Alan Cox wrote:
> On Mer, 2004-10-13 at 23:40, Rusty Russell (IBM) wrote:
> > > Whoops bang "num 0 elements". That check set isn't safe standalone
> >
> > Thanks, Alan.
> >
> > I'd appreciate your opinion on the issue at hand. Is it worth 600 lines
> > of ELF verification and canonicalization code so we can strip modules
> > without altering the signature?
>
> I'm unconvinced at the moment, it seems it would be easier to write the
> neccessary code to do this in userspace, and then sign the canonicalised
> module so that the kernel interface is small and clean.

Well, my original implementation carefully found the signature section,
copied it out and zeroed it, then checked the whole module. The two
objections David Howells had was (1) stripping the module after build
breaks this, and (2) his scheme uses straight GPG signatures and they
are of variable length: some wrapper would be needed to handle trailing
zeroes in the signature.

The advantage was the simplicity of the scheme: very short path the
module verification, and no canonicalization step.

Rusty.
Richard B. Johnson
2004-10-15 12:10:35 UTC
Permalink
On Fri, 15 Oct 2004, Roman Zippel wrote:

> Hi,
>
> On Thu, 14 Oct 2004, David Howells wrote:
>
>> I've uploaded an updated module signing patch with Rusty's suggested
>> additions:
>
> Can someone please put this patch into some context, where it's not
> completely pointless? As is it does not make anything more secure.
> Why is the kernel more trustable than a kernel module?
> If someone could show me how I can trust the running kernel, it should be
> rather easy to extend the same measures to modules without the need for
> this patch.
>
> bye, Roman
> -

This is just the first step, which I think must be quashed
immediately. The ultimate goal is to control what you put
into your computer. Eventually, some central licensing
authority will certify any modules that are allowed to
be run in your computer. Doesn't anybody else see this?

Freedom isn't lost in one big step when the storm-troopers
show up at your door. It is lost in little pieces, each
so small that they tend to be ignored.

We need to stop this nonsense now. Certainly persons who
lived, or still live, under highly regulated governmental
control, know that we must prevent some select group of
self-appointed authorities from controlling what we put
into our computers. In particular, when the five to
ten-thousand who contributed to the kernel, thought that
they were performing a service for the common good, not
to be taken from them and hidden behind some license.

I developed one of the first SCSI controllers for Linux,
back when Linus was in Helsinki. I did this because I
bought a new SCSI disk and controller. It worked under
DOS, but not Linux. Nobody, in those days, thought
anything about modules and licenses, etc. We just wanted
to make Linux better. Then, when I was working on some
other drivers, I needed to be able to change code without
having to re-boot. I made the first primitive 'module' to
do this. The old driver was not actually removed nor
even overwritten. I just made a program to perform
fix-ups in user-mode, and a built-in driver to allocate
memory, load the fixed-up code, and change pointers
to point to new code. This allowed me to write drivers
and install them without having to re-boot. Eventually,
the system would run out of memory and I'd have to
reboot, but in the meantime, I could continue
development. This was all the precursor of the more
modern 'modules' by Laarhoven and Tombs.

Now, I've watched through the years where every bit
of code that the original contributors wrote, was
overwritten. It was not necessarily better, only
different. Even the names of contributors have been
removed. The name-removers still haven't removed the
last vestige of my contributions although they probably
will now, but I'll make it difficult to find them...

Script started on Fri 15 Oct 2004 07:51:34 AM EDT
# for x in `find . -name "*.c"` ; do grep rjohnson@ $x ; done
***@analogic.com : Changed init order so an interrupt will only
***@analogic.com : Fix up PIO interface for efficient operation.
# exit
Script done on Fri 15 Oct 2004 07:52:45 AM EDT

Then, a certain Richard Stallman, tried to claim Linux as
his own as "GNU/Linux". Guess what? Most everybody fell into
that trap.

Why would anybody remove contributor names from even
`man` pages? Look at the new `man insmod`. Yes, the
original is in `insmod.old`. How long will that last?

Each of these little pieces of freedom are being chipped
away, bit-by-bit.

Wake up everybody. Get the POLICY out of the kernel.

Cheers,
Dick Johnson
Penguin : Linux version 2.6.8 on an i686 machine (5537.79 Gimps).
Note 96.31% of all statistics are fiction.
Gene Heskett
2004-10-15 15:51:04 UTC
Permalink
On Friday 15 October 2004 08:10, Richard B. Johnson wrote:
>On Fri, 15 Oct 2004, Roman Zippel wrote:
>> Hi,
>>
>> On Thu, 14 Oct 2004, David Howells wrote:
>>> I've uploaded an updated module signing patch with Rusty's
>>> suggested additions:
>>
>> Can someone please put this patch into some context, where it's
>> not completely pointless? As is it does not make anything more
>> secure. Why is the kernel more trustable than a kernel module?
>> If someone could show me how I can trust the running kernel, it
>> should be rather easy to extend the same measures to modules
>> without the need for this patch.
>>
>> bye, Roman
>> -

If you please, allow me to second the below gentlemans point of view.
Its an extremely valid objection in this persons aged opinion. A road
down which we should not even glance, let alone travel. Do I hear a
full chorus of voices here? I certainly hope so. This patch is best
dropped in the shredder.

>This is just the first step, which I think must be quashed
>immediately. The ultimate goal is to control what you put
>into your computer. Eventually, some central licensing
>authority will certify any modules that are allowed to
>be run in your computer. Doesn't anybody else see this?
>
>Freedom isn't lost in one big step when the storm-troopers
>show up at your door. It is lost in little pieces, each
>so small that they tend to be ignored.
>
>We need to stop this nonsense now. Certainly persons who
>lived, or still live, under highly regulated governmental
>control, know that we must prevent some select group of
>self-appointed authorities from controlling what we put
>into our computers. In particular, when the five to
>ten-thousand who contributed to the kernel, thought that
>they were performing a service for the common good, not
>to be taken from them and hidden behind some license.
>
>I developed one of the first SCSI controllers for Linux,
>back when Linus was in Helsinki. I did this because I
>bought a new SCSI disk and controller. It worked under
>DOS, but not Linux. Nobody, in those days, thought
>anything about modules and licenses, etc. We just wanted
>to make Linux better. Then, when I was working on some
>other drivers, I needed to be able to change code without
>having to re-boot. I made the first primitive 'module' to
>do this. The old driver was not actually removed nor
>even overwritten. I just made a program to perform
>fix-ups in user-mode, and a built-in driver to allocate
>memory, load the fixed-up code, and change pointers
>to point to new code. This allowed me to write drivers
>and install them without having to re-boot. Eventually,
>the system would run out of memory and I'd have to
>reboot, but in the meantime, I could continue
>development. This was all the precursor of the more
>modern 'modules' by Laarhoven and Tombs.
>
>Now, I've watched through the years where every bit
>of code that the original contributors wrote, was
>overwritten. It was not necessarily better, only
>different. Even the names of contributors have been
>removed. The name-removers still haven't removed the
>last vestige of my contributions although they probably
>will now, but I'll make it difficult to find them...
>
>Script started on Fri 15 Oct 2004 07:51:34 AM EDT
># for x in `find . -name "*.c"` ; do grep rjohnson@ $x ; done
> ***@analogic.com : Changed init order so an interrupt will
> only ***@analogic.com : Fix up PIO interface for efficient
> operation. # exit
>Script done on Fri 15 Oct 2004 07:52:45 AM EDT
>
>Then, a certain Richard Stallman, tried to claim Linux as
>his own as "GNU/Linux". Guess what? Most everybody fell into
>that trap.
>
>Why would anybody remove contributor names from even
>`man` pages? Look at the new `man insmod`. Yes, the
>original is in `insmod.old`. How long will that last?
>
>Each of these little pieces of freedom are being chipped
>away, bit-by-bit.
>
>Wake up everybody. Get the POLICY out of the kernel.
>
>Cheers,
>Dick Johnson
>Penguin : Linux version 2.6.8 on an i686 machine (5537.79 Gimps).
> Note 96.31% of all statistics are fiction.
>
--
Cheers, Gene
"There are four boxes to be used in defense of liberty:
soap, ballot, jury, and ammo. Please use in that order."
-Ed Howdershelt (Author)
99.27% setiathome rank, not too shabby for a WV hillbilly
Yahoo.com attorneys please note, additions to this message
by Gene Heskett are:
Copyright 2004 by Maurice Eugene Heskett, all rights reserved.
David Howells
2004-10-13 09:24:46 UTC
Permalink
> Let me make this clear: I refuse to include any solution which doesn't
> protect against accidental, as well as deliberate, corruption. This
> means your "canonicalization" code has to be very, very paranoid about
> not trusting the data until the signature is verified. The current code
> does very simple checks then completely trusts the module contents,
> especially the section headers: to make signatures worth anything, your
> code must not do this.

I agree that checks should be made on ELF before signature checking is
performed, but I was trying to develop it one step at a time. However, since
you asked so nicely, I've added the attached to my implementation.

David

---

struct module_verify_data {
struct crypto_tfm *sha1_tfm;
const void *buffer;
const Elf_Ehdr *hdr;
const Elf_Shdr *sections;
const Elf_Sym *symbols;
const char *secstrings;
const char *strings;
size_t *secsizes;
size_t size;
size_t nsects;
size_t nsyms;
size_t nstrings;
size_t signed_size;
int *canonlist;
int *canonmap;
int sig_index;
uint8_t csum;
};

/*****************************************************************************/
/*
* verify the ELF structure of a module
*/
static int module_verify_elf(struct module_verify_data *mvdata)
{
const Elf_Ehdr *hdr = mvdata->hdr;
const Elf_Shdr *section, *section2, *secstop;
const Elf_Rela *relas, *rela, *relastop;
const Elf_Rel *rels, *rel, *relstop;
const Elf_Sym *symbol, *symstop;
size_t size, sssize, *secsize, tmp, tmp2;
int line;

size = mvdata->size;
mvdata->nsects = hdr->e_shnum;

#define elfcheck(X) \
do { if (unlikely(!(X))) { line = __LINE__; goto elfcheck_error; } } while(0)

#define seccheck(X) \
do { if (unlikely(!(X))) { line = __LINE__; goto seccheck_error; } } while(0)

#define symcheck(X) \
do { if (unlikely(!(X))) { line = __LINE__; goto symcheck_error; } } while(0)

#define relcheck(X) \
do { if (unlikely(!(X))) { line = __LINE__; goto relcheck_error; } } while(0)

#define relacheck(X) \
do { if (unlikely(!(X))) { line = __LINE__; goto relacheck_error; } } while(0)

/* validate the ELF header */
elfcheck(hdr->e_ehsize < size);
elfcheck(hdr->e_entry == 0);
elfcheck(hdr->e_phoff == 0);
elfcheck(hdr->e_phnum == 0);

elfcheck(hdr->e_shoff < size);
elfcheck(hdr->e_shoff >= hdr->e_ehsize);
elfcheck((hdr->e_shoff & (sizeof(long) - 1)) == 0);
elfcheck(hdr->e_shstrndx > 0);
elfcheck(hdr->e_shstrndx < hdr->e_shnum);

tmp = (size_t) hdr->e_shentsize * (size_t) hdr->e_shnum;
elfcheck(tmp < size - hdr->e_shoff);

/* allocate a table to hold in-file section sizes */
mvdata->secsizes = kmalloc(hdr->e_shnum * sizeof(size_t), GFP_KERNEL);
if (!mvdata->secsizes)
return -ENOMEM;

memset(mvdata->secsizes, 0, hdr->e_shnum * sizeof(size_t));

/* validate the ELF section headers */
mvdata->sections = mvdata->buffer + hdr->e_shoff;
secstop = mvdata->sections + mvdata->nsects;

sssize = mvdata->sections[hdr->e_shstrndx].sh_size;
elfcheck(sssize > 0);

section = mvdata->sections;
seccheck(section->sh_type == SHT_NULL);
seccheck(section->sh_size == 0);
seccheck(section->sh_offset == 0);

secsize = mvdata->secsizes + 1;
for (section++; section < secstop; secsize++, section++) {
seccheck(section->sh_name < sssize);
seccheck(section->sh_addr == 0);
seccheck(section->sh_link < hdr->e_shnum);

if (section->sh_entsize > 0)
seccheck(section->sh_size % section->sh_entsize == 0);

seccheck(section->sh_offset >= hdr->e_ehsize);
seccheck(section->sh_offset < size);

/* determine the section's in-file size */
tmp = size - section->sh_offset;
if (section->sh_offset < hdr->e_shoff)
tmp = hdr->e_shoff - section->sh_offset;

for (section2 = mvdata->sections + 1; section2 < secstop; section2++) {
if (section->sh_offset < section2->sh_offset) {
tmp2 = section2->sh_offset - section->sh_offset;
if (tmp2 < tmp)
tmp = tmp2;
}
}
*secsize = tmp;

_debug("Section %ld: %zx bytes at %lx\n",
section - mvdata->sections,
*secsize,
section->sh_offset);

/* perform section type specific checks */
switch (section->sh_type) {
case SHT_NOBITS:
break;

case SHT_REL:
case SHT_RELA:
seccheck(section->sh_info > 0);
seccheck(section->sh_info < hdr->e_shnum);
/* fall through */

default:
/* most types of section must be contained entirely
* within the file */
seccheck(section->sh_size <= *secsize);
break;
}
}

/* validate the ELF section names */
section = &mvdata->sections[hdr->e_shstrndx];

seccheck(section->sh_offset != hdr->e_shoff);

mvdata->secstrings = mvdata->buffer + section->sh_offset;

for (section = mvdata->sections + 1; section < secstop; section++) {
const char *secname;
tmp = sssize - section->sh_name;
secname = mvdata->secstrings + section->sh_name;
seccheck(secname[0] != 0);
seccheck(memchr(secname, 0, tmp) != NULL);
}

/* look for various sections in the module */
for (section = mvdata->sections + 1; section < secstop; section++) {
switch (section->sh_type) {
case SHT_SYMTAB:
if (strcmp(mvdata->secstrings + section->sh_name,
".symtab") == 0
) {
seccheck(mvdata->symbols == NULL);
mvdata->symbols =
mvdata->buffer + section->sh_offset;
mvdata->nsyms =
section->sh_size / sizeof(Elf_Sym);
seccheck(section->sh_size > 0);
}
break;

case SHT_STRTAB:
if (strcmp(mvdata->secstrings + section->sh_name,
".strtab") == 0
) {
seccheck(mvdata->strings == NULL);
mvdata->strings =
mvdata->buffer + section->sh_offset;
sssize = mvdata->nstrings = section->sh_size;
seccheck(section->sh_size > 0);
}
break;
}
}

if (!mvdata->symbols) {
printk("Couldn't locate module symbol table\n");
goto format_error;
}

if (!mvdata->strings) {
printk("Couldn't locate module strings table\n");
goto format_error;
}

/* validate the symbol table */
symstop = mvdata->symbols + mvdata->nsyms;

symbol = mvdata->symbols;
symcheck(ELF_ST_TYPE(symbol[0].st_info) == STT_NOTYPE);
symcheck(symbol[0].st_shndx == SHN_UNDEF);
symcheck(symbol[0].st_value == 0);
symcheck(symbol[0].st_size == 0);

for (symbol++; symbol < symstop; symbol++) {
symcheck(symbol->st_name < sssize);
symcheck(symbol->st_shndx < mvdata->nsects ||
symbol->st_shndx >= SHN_LORESERVE);
}

/* validate each relocation table as best we can */
for (section = mvdata->sections + 1; section < secstop; section++) {
section2 = mvdata->sections + section->sh_info;

switch (section->sh_type) {
case SHT_REL:
rels = mvdata->buffer + section->sh_offset;
relstop = mvdata->buffer + section->sh_offset + section->sh_size;

for (rel = rels; rel < relstop; rel++) {
relcheck(rel->r_offset < section2->sh_size);
relcheck(ELF_R_SYM(rel->r_info) < mvdata->nsyms);
}

break;

case SHT_RELA:
relas = mvdata->buffer + section->sh_offset;
relastop = mvdata->buffer + section->sh_offset + section->sh_size;

for (rela = relas; rela < relastop; rela++) {
relacheck(rela->r_offset < section2->sh_size);
relacheck(ELF_R_SYM(rela->r_info) < mvdata->nsyms);
}

break;

default:
break;
}
}


_debug("ELF okay\n");
return 0;

elfcheck_error:
printk("Verify ELF error (assertion %d)\n", line);
goto format_error;

seccheck_error:
printk("Verify ELF error [sec %ld] (assertion %d)\n",
section - mvdata->sections, line);
goto format_error;

symcheck_error:
printk("Verify ELF error [sym %ld] (assertion %d)\n",
symbol - mvdata->symbols, line);
goto format_error;

relcheck_error:
printk("Verify ELF error [sec %ld rel %ld] (assertion %d)\n",
section - mvdata->sections, rel - rels, line);
goto format_error;

relacheck_error:
printk("Verify ELF error [sec %ld rela %ld] (assertion %d)\n",
section - mvdata->sections, rela - relas, line);
goto format_error;

format_error:
return -ELIBBAD;

} /* end module_verify_elf() */
David Howells
2004-10-13 21:18:38 UTC
Permalink
> Write the code. Then come back and tell me it "isn't that hard".

It isn't that hard.

> Let me make this clear: I refuse to include any solution which doesn't
> protect against accidental, as well as deliberate, corruption. This
> means your "canonicalization" code has to be very, very paranoid about
> not trusting the data until the signature is verified. The current code
> does very simple checks then completely trusts the module contents,
> especially the section headers: to make signatures worth anything, your
> code must not do this.

I've made a patch available to permit module signing in the kernel.

http://people.redhat.com/~dhowells/modsign/modsign-269rc4mm1.diff.bz2

I've also put up some example keys:

http://people.redhat.com/~dhowells/modsign/kernel.pub
http://people.redhat.com/~dhowells/modsign/kernel.sec
http://people.redhat.com/~dhowells/modsign/key.h

The first two need to go into your kernel root dir; the third needs to go into
crypto/signature/.

key.h can be generated by something like:

gpg --homedir /tmp --export --keyring ./kernel.pub Red |
scripts/bin2c ksign_def_public_key __initdata >crypto/signature/key.h

You'll need to build the module extractor manually:

make -C scripts/modsign mod-extract

And sign modules manually:

scripts/modsign/modsign.sh net/rxrpc/rxrpc.ko

I'd like to automate this in the kernel build process, but it's not
immediately obvious how to do this with the kernel's current Makefile
stuff.

There's also the problem of how to get the keys in the first place. In the
Fedora RPMs the spec file generates a single new key pair for every build and
discards it later after generating key.h, but that may not be appropriate in
all cases (you can have multiple keys, and you may want to get them from a GPG
keyring somewhere).

David
Richard B. Johnson
2004-10-14 13:08:27 UTC
Permalink
On Thu, 14 Oct 2004, David Howells wrote:

>
> > I'm trying to understand the reason to stuff this into kernel. Why can't
> > this check be done before loading the module into the kernel? If you don't
> > trust insmod, how can you trust the build system?
>
> (1) insmod isn't the only way to load a module.
>
> (2) This helps limit what an intruder can do; particularly if you combine it
> with other measures.
>
> (3) Who says the kernel RPM is built on the same machine as the one you
> really want to deploy this on for the added protection?
>
> David

I think I smell something. We had a perfectly-good way of loading
modules. About 99 percent of the code was in user-space. Now, 99 percent
of the code is in the kernel. Why? I think this is to "prove" that
kernel modules are "kernel" things that require kernel licensing.

So, some misguided persons that think they are lawyers and/or are
being led by misguided persons that are lawyers??? And, for this
we get lawyer-bloat in the kernel.

The new build system sucks. The new kernel module loading scheme
sucks, pure and simple. In fact, Linux is degenerating into
a trash bin of "me-too" hacks.

I am now back to Linux-2.4.26 after trying to run a new standard
distribution of "Red Hat Fedora" on a completely separate
hard-disk. I had to rebuild everything for the third time
(reinstall all software) and I'm thoroughly pissed. The
Linux-2.6.whatever that comes with that garbage trashes my
SCSI disks if I mount them, making them unusable and
requiring a complete reinstall of everything.

So, keep it up. In a few years Linux will be remembered
as a joke. Somebody may fork off something near Linux-2.4.x
and make a professional operating system out of it, but
right now it's taken a rapid down-turn into the toilet.

I strongly suggest that you stop corrupting the kernel
and kernel modules and go back to the tried and true
Linux-2.4.n methods. Sure there are some bugs (races)
that may need to be fixed in the older module loading
scheme, but its been workable for many years.

The new kernel build environment is also corrupt. On
this system, it takes 45 seconds to perform:

make clean
make bzImage

With the new build system, same disk, same kernel
configuration, it takes 14 minutes. And, you can't
even see what the compiler doesn't like.

The build system generates separate command-files,
hidden from `ls` by having them start with ".", for
every source-file and link action, plus it even
makes hidden subdirectories. The modules build
even generates its own 'C' source-file for some
junk that the new `insmod` needs. It's crap, pure
and simple. Damn crap. All of it.

This is the best example of technological degeneration
I've seen in my 40+ years of professional involvement
in engineering. Somebody may write a book and the
only fame that will remain will be visual impact
of a smoking hole that was once a viable operating
system borne on the ideas of thousands world-wide.

I qoute; "Have you no shame?"

Cheers,
Dick Johnson
Penguin : Linux version 2.4.26 on an i686 machine (5570.56 BogoMips).
Note 96.31% of all statistics are fiction.
Richard B. Johnson
2004-10-14 14:25:52 UTC
Permalink
On Thu, 14 Oct 2004, Geert Uytterhoeven wrote:

> On Thu, 14 Oct 2004, Richard B. Johnson wrote:
> > The new kernel build environment is also corrupt. On
> > this system, it takes 45 seconds to perform:
> >
> > make clean
> > make bzImage
>
> And how long does `make oldconfig' take?
>

Don't know.

> > With the new build system, same disk, same kernel
> > configuration, it takes 14 minutes. And, you can't
>
> BTW, how do you choose the old/new build system with the same kernel?
>

You can't. I needed to do a `make oldconfig` as a seperate
operation which wasn't timed. The configuration uses only
12 modules (SCSI disk stuff plus ethernet).

> > even see what the compiler doesn't like.
>
> make V=1?


Try it while making modules!

>
> Gr{oetje,eeting}s,
>
> Geert


Cheers,
Dick Johnson
Penguin : Linux version 2.4.26 on an i686 machine (5570.56 BogoMips).
Note 96.31% of all statistics are fiction.
Richard B. Johnson
2004-10-14 15:40:54 UTC
Permalink
On Thu, 14 Oct 2004, Richard B. Johnson wrote:

> On Thu, 14 Oct 2004, Geert Uytterhoeven wrote:
>
> > On Thu, 14 Oct 2004, Richard B. Johnson wrote:
> > > The new kernel build environment is also corrupt. On
> > > this system, it takes 45 seconds to perform:
> > >
> > > make clean
> > > make bzImage
> >
> > And how long does `make oldconfig' take?
> >
>
> Don't know.
>
> > > With the new build system, same disk, same kernel
> > > configuration, it takes 14 minutes. And, you can't
> >
> > BTW, how do you choose the old/new build system with the same kernel?
> >
>
> You can't. I needed to do a `make oldconfig` as a seperate
> operation which wasn't timed. The configuration uses only
> 12 modules (SCSI disk stuff plus ethernet).
>
> > > even see what the compiler doesn't like.
> >
> > make V=1?
>
>
> Try it while making modules!
>
> >
> > Gr{oetje,eeting}s,
> >
> > Geert
>

Here is the tail end of a kernel build of 2.4.26 while
running the 2.4.26 kernel.

==> BUILD-2.4.26 <==
gcc -D__ASSEMBLY__ -D__KERNEL__ -I/usr/src/linux-2.4.26/include -traditional -c head.S
gcc -D__KERNEL__ -I/usr/src/linux-2.4.26/include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common -fomit-frame-pointer -pipe -march=i686 -DKBUILD_BASENAME=misc -c misc.c
ld -m elf_i386 -Ttext 0x100000 -e startup_32 -o bvmlinux head.o misc.o piggy.o
make[2]: Leaving directory `/usr/src/linux-2.4.26/arch/i386/boot/compressed'
gcc -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -o tools/build tools/build.c -I/usr/src/linux-2.4.26/include
objcopy -O binary -R .note -R .comment -S compressed/bvmlinux compressed/bvmlinux.out
tools/build -b bbootsect bsetup compressed/bvmlinux.out CURRENT > bzImage
Root device is (8, 17)
Boot sector 512 bytes.
Setup is 4653 bytes.
System is 801 kB
make[1]: Leaving directory `/usr/src/linux-2.4.26/arch/i386/boot'
49.72user 6.45system 54.67elapsed 92%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+0minor)pagefaults 0swaps
# uname -r
2.4.26
# pwd
/usr/src/linux-2.4.26
# exit
Script done on Thu Oct 14 11:25:54 2004

The elapsed time was 54.67 seconds.

Here is the same configuration, built on the linux-2.6.8 machine.

==> BUILD-2.6.8 <==
OBJCOPY arch/i386/boot/vmlinux.bin
HOSTCC arch/i386/boot/tools/build
BUILD arch/i386/boot/bzImage
Root device is (3, 1)
Boot sector 512 bytes.
Setup is 4847 bytes.
System is 1401 kB
Kernel: arch/i386/boot/bzImage is ready

real 16m58.119s
user 10m59.700s
sys 4m33.340s
You have new mail in /var/spool/mail/root
# uname -a
Linux chaos.analogic.com 2.6.8 #1 SMP Wed Oct 13 19:03:35 EDT 2004 i686 i686 i386 GNU/Linux
# pwd
/usr/src/linux-2.6.8
# exit

Script done on Thu 14 Oct 2004 11:18:10 AM EDT

It took 16:58 to build the kernel (no modules, they take the
better part of an hour).


Cheers,
Dick Johnson
Penguin : Linux version 2.4.26 on an i686 machine (5570.56 BogoMips).
Note 96.31% of all statistics are fiction.
Dave Jones
2004-10-14 15:50:31 UTC
Permalink
On Thu, Oct 14, 2004 at 11:40:54AM -0400, Richard B. Johnson wrote:

> Here is the same configuration, built on the linux-2.6.8 machine.

.config's from both please ?

Dave
Dave Jones
2004-10-14 18:20:52 UTC
Permalink
On Thu, Oct 14, 2004 at 01:57:50PM -0400, Richard B. Johnson wrote:
>
> Attached. This difference in size might make one think that
> there's more in the 2.6.8 basic compile, but most stuff is
> strings that say "BLAW is not set", which us longer than
> "BLAW=y" or "BLAW=m". In fact, about twice as long....

A cursory examination show that the two aren't even remotely
similar in a lot of cases. Take the misc filesystems section
for example.. (edited for brevity)

2.4
# Miscellaneous filesystems
#
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
# CONFIG_HFSPLUS_FS is not set
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
CONFIG_EFS_FS=m
CONFIG_HPFS_FS=m
CONFIG_SYSV_FS=m
CONFIG_UFS_FS=m

2.6

# Miscellaneous filesystems
#
CONFIG_AFFS_FS=m
CONFIG_HFS_FS=m
CONFIG_HFSPLUS_FS=m
CONFIG_BEFS_FS=m
CONFIG_BFS_FS=m
CONFIG_EFS_FS=m
CONFIG_JFFS2_FS=m
CONFIG_JFFS2_FS_NAND=y
CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
CONFIG_CRAMFS=m
CONFIG_VXFS_FS=m
CONFIG_QNX4FS_FS=m
CONFIG_SYSV_FS=m
CONFIG_UFS_FS=m

And you wonder why 2.6 is taking longer ?
There are many more cases like this in your configs..

Unless you're comparing apples to apples, this is
just nonsense.

Dave
Richard B. Johnson
2004-10-14 18:30:08 UTC
Permalink
On Thu, 14 Oct 2004, Dave Jones wrote:

> On Thu, Oct 14, 2004 at 01:57:50PM -0400, Richard B. Johnson wrote:
> >
> > Attached. This difference in size might make one think that
> > there's more in the 2.6.8 basic compile, but most stuff is
> > strings that say "BLAW is not set", which us longer than
> > "BLAW=y" or "BLAW=m". In fact, about twice as long....
>
> A cursory examination show that the two aren't even remotely
> similar in a lot of cases. Take the misc filesystems section
> for example.. (edited for brevity)
>
> 2.4
> # Miscellaneous filesystems
> #
> # CONFIG_ADFS_FS is not set
> # CONFIG_AFFS_FS is not set
> # CONFIG_HFS_FS is not set
> # CONFIG_HFSPLUS_FS is not set
> # CONFIG_BEFS_FS is not set
> # CONFIG_BFS_FS is not set
> CONFIG_EFS_FS=m
> CONFIG_HPFS_FS=m
> CONFIG_SYSV_FS=m
> CONFIG_UFS_FS=m
>
> 2.6
>
> # Miscellaneous filesystems
> #
> CONFIG_AFFS_FS=m
> CONFIG_HFS_FS=m
> CONFIG_HFSPLUS_FS=m
> CONFIG_BEFS_FS=m
> CONFIG_BFS_FS=m
> CONFIG_EFS_FS=m
> CONFIG_JFFS2_FS=m
> CONFIG_JFFS2_FS_NAND=y
> CONFIG_JFFS2_ZLIB=y
> CONFIG_JFFS2_RTIME=y
> CONFIG_CRAMFS=m
> CONFIG_VXFS_FS=m
> CONFIG_QNX4FS_FS=m
> CONFIG_SYSV_FS=m
> CONFIG_UFS_FS=m
>
> And you wonder why 2.6 is taking longer ?
> There are many more cases like this in your configs..
>
> Unless you're comparing apples to apples, this is
> just nonsense.
>
> Dave
>

No. I didn't time `make modules`, only `make bzImage`.
`make modules` takes too long to time (really) I don't
want to use any CPU resources which will screw up the
timing and I need to use the computer.

A wall-clock guess is that `make modules` takes about
an hour on the new system while it takes about 4 minutes
on the old. The new kernel build procedure is truly
horrible for the wall-clock time that is used.

For oranges vs oranges, if I compile Version 2.4.26
on a version 2.6.8 OS computer, the compile-time
is within tens of seconds. I'm not complaining about
the resulting kernel code performance, only the
abortion^M^M^M^M^M^Mjunk used to create a new kernel.
It 'make' won't do it, we have a problem and make
needs to be fixed.

Cheers,
Dick Johnson
Penguin : Linux version 2.6.8 on an i686 machine (5537.79 BogoMips).
Note 96.31% of all statistics are fiction.
Richard B. Johnson
2004-10-14 19:03:51 UTC
Permalink
On Thu, 14 Oct 2004, Dave Jones wrote:

> On Thu, Oct 14, 2004 at 02:30:08PM -0400, Richard B. Johnson wrote:
>
> > No. I didn't time `make modules`, only `make bzImage`.
> > `make modules` takes too long to time (really) I don't
> > want to use any CPU resources which will screw up the
> > timing and I need to use the computer.
>
> You still have to calculate dependancies and such for
> anything built modular. Also a bunch of code built into
> the bzImage changes if things are built modular.
>
> the two comparisons aren't equal. Additionally,
> you haven't factored in the fact that 'make dep'
> is no longer needed. This accounts for a big chunk
> of time on 2.4 kernel builds.
>
> > A wall-clock guess is that `make modules` takes about
> > an hour on the new system while it takes about 4 minutes
> > on the old. The new kernel build procedure is truly
> > horrible for the wall-clock time that is used.
> >
> > For oranges vs oranges, if I compile Version 2.4.26
> > on a version 2.6.8 OS computer, the compile-time
> > is within tens of seconds. I'm not complaining about
> > the resulting kernel code performance, only the
> > abortion^M^M^M^M^M^Mjunk used to create a new kernel.
> > It 'make' won't do it, we have a problem and make
> > needs to be fixed.
>
> oranges to oranges means _exactly_ the same options
> (where they haven't changed from 2.4 -> 2.6) are
> set/unset. Anything else is totally bogus.
>
> If you find things are still taking phenomenally
> long times to build, then something is wrong somewhere.
> Don't you find it strange you're the only person
> to have complained about this ? If it was as big
> a problem as you're suggesting, those of us who
> do nothing but build kernels all day would be up in arms.
>
> Dave
>

I think you guys probably got used to it. Also, you
seldom build the whole thing, anymore, because the
dependencies are handled differently. I was used to
building stuff on 2.4.x. When I went to build stuff using
the new build procedure I was shocked. It was like the
old days with 66MHz '486s (fast) and 33MHz i386's. Of
course there weren't modules, then so 2hrs,30min
was normal. Now, with a CPU that's 80 times faster and
a front-side bus that's 12 time faster, and SCSI
disks that are 40 times faster, there just has to
be something wrong when a complete build of the kernel
takes an hour.

Cheers,
Dick Johnson
Penguin : Linux version 2.6.8 on an i686 machine (5537.79 BogoMips).
Note 96.31% of all statistics are fiction.
Geert Uytterhoeven
2004-10-14 19:41:21 UTC
Permalink
On Thu, 14 Oct 2004, Richard B. Johnson wrote:
> On Thu, 14 Oct 2004, Dave Jones wrote:
> > If you find things are still taking phenomenally
> > long times to build, then something is wrong somewhere.
> > Don't you find it strange you're the only person
> > to have complained about this ? If it was as big
> > a problem as you're suggesting, those of us who
> > do nothing but build kernels all day would be up in arms.
>
> I think you guys probably got used to it. Also, you
> seldom build the whole thing, anymore, because the
> dependencies are handled differently. I was used to
> building stuff on 2.4.x. When I went to build stuff using
> the new build procedure I was shocked. It was like the
> old days with 66MHz '486s (fast) and 33MHz i386's. Of
> course there weren't modules, then so 2hrs,30min
> was normal. Now, with a CPU that's 80 times faster and
> a front-side bus that's 12 time faster, and SCSI
> disks that are 40 times faster, there just has to
> be something wrong when a complete build of the kernel
> takes an hour.

I have the impression 2.6 builds are more convenient, if not faster (sorry, no
hard data around due to ccache).

Perhaps you need to start using ccache (but that's true for building 2.4.x,
too)?

BTW, _if_ the build system got much slower, people who use ccache a lot would
notice, since the relative impact of the build system on the build time is
higher when using ccache.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ***@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
Dave Jones
2004-10-14 21:13:38 UTC
Permalink
On Thu, Oct 14, 2004 at 03:03:51PM -0400, Richard B. Johnson wrote:

> I think you guys probably got used to it. Also, you
> seldom build the whole thing, anymore, because the
> dependencies are handled differently.

I build the whole thing, daily. from scratch, without
ccache, with something that isn't too far from a
make allmodconfig, on a half dozen different architectures
(with multiple builds for each sometimes - 586/686,
various ppc flavours etc).

Our build system spits out 2.6 kernel RPMs not noticably
slower their 2.4 counterparts, which were also pretty
close to a make allmodconfig.

If the builds took _twice_ as long, I would've been
shouting from the rooftops long ago.
The factors you mention make it sound like something is
very very wrong somewhere, but there's no clear sign why
this is affecting you so badly. Maybe you should try
profiling things and find out where the additional time
is being spent.

> building stuff on 2.4.x. When I went to build stuff using
> the new build procedure I was shocked. It was like the
> old days with 66MHz '486s (fast) and 33MHz i386's. Of
> course there weren't modules, then so 2hrs,30min
> was normal. Now, with a CPU that's 80 times faster and
> a front-side bus that's 12 time faster, and SCSI
> disks that are 40 times faster, there just has to
> be something wrong when a complete build of the kernel
> takes an hour.

How much RAM do you have ? And are you using the same
version of gcc for both 2.4 and 2.6 builds ?

Dave
Dave Jones
2004-10-14 18:46:35 UTC
Permalink
On Thu, Oct 14, 2004 at 02:30:08PM -0400, Richard B. Johnson wrote:

> No. I didn't time `make modules`, only `make bzImage`.
> `make modules` takes too long to time (really) I don't
> want to use any CPU resources which will screw up the
> timing and I need to use the computer.

You still have to calculate dependancies and such for
anything built modular. Also a bunch of code built into
the bzImage changes if things are built modular.

the two comparisons aren't equal. Additionally,
you haven't factored in the fact that 'make dep'
is no longer needed. This accounts for a big chunk
of time on 2.4 kernel builds.

> A wall-clock guess is that `make modules` takes about
> an hour on the new system while it takes about 4 minutes
> on the old. The new kernel build procedure is truly
> horrible for the wall-clock time that is used.
>
> For oranges vs oranges, if I compile Version 2.4.26
> on a version 2.6.8 OS computer, the compile-time
> is within tens of seconds. I'm not complaining about
> the resulting kernel code performance, only the
> abortion^M^M^M^M^M^Mjunk used to create a new kernel.
> It 'make' won't do it, we have a problem and make
> needs to be fixed.

oranges to oranges means _exactly_ the same options
(where they haven't changed from 2.4 -> 2.6) are
set/unset. Anything else is totally bogus.

If you find things are still taking phenomenally
long times to build, then something is wrong somewhere.
Don't you find it strange you're the only person
to have complained about this ? If it was as big
a problem as you're suggesting, those of us who
do nothing but build kernels all day would be up in arms.

Dave
Jon Masters
2004-10-18 01:56:09 UTC
Permalink
On Thu, 14 Oct 2004 09:08:27 -0400 (EDT), Richard B. Johnson
<***@chaos.analogic.com> wrote:
> On Thu, 14 Oct 2004, David Howells wrote:
>
> >
> > > I'm trying to understand the reason to stuff this into kernel. Why can't
> > > this check be done before loading the module into the kernel? If you don't
> > > trust insmod, how can you trust the build system?
> >
> > (1) insmod isn't the only way to load a module.
> >
> > (2) This helps limit what an intruder can do; particularly if you combine it
> > with other measures.
> >
> > (3) Who says the kernel RPM is built on the same machine as the one you
> > really want to deploy this on for the added protection?

> I think I smell something. We had a perfectly-good way of loading
> modules. About 99 percent of the code was in user-space. Now, 99 percent
> of the code is in the kernel. Why? I think this is to "prove" that
> kernel modules are "kernel" things that require kernel licensing.

The only extent to which I'll agree you have half a point - is in the
fact that the kernel does have to worry more about licensing issues
these days. I think it's plain crazy and delusional to suggest that
there is a secret lawyer driven motive behind the 2.6 implementation
however. That said, I've not taken my anti-brain rays tablet yet today
so that might just be what they want me to think.

> The new build system sucks. The new kernel module loading scheme
> sucks, pure and simple. In fact, Linux is degenerating into
> a trash bin of "me-too" hacks.

What sucks about it? That you didn't bother to read about how to use
it, or that it's fundamentally got some problem you can offer a
solution to?

> I am now back to Linux-2.4.26 after trying to run a new standard
> distribution of "Red Hat Fedora" on a completely separate
> hard-disk. I had to rebuild everything for the third time
> (reinstall all software) and I'm thoroughly pissed. The
> Linux-2.6.whatever that comes with that garbage trashes my
> SCSI disks if I mount them, making them unusable and
> requiring a complete reinstall of everything.

This isn't a Fedora discussion list. Several folks here work for
RedHat but that's not an excuse for having a Fedora rant here. If you
dislike what you downloaded - go buy a supported product and call tech
support.

> The new kernel build environment is also corrupt. On
> this system, it takes 45 seconds to perform:
>
> make clean
> make bzImage
>
> With the new build system, same disk, same kernel
> configuration, it takes 14 minutes. And, you can't
> even see what the compiler doesn't like.

Geert suggested a quick fix for displaying the compilation process. I
admit that I didn't like not seeing the compiler output on first use,
but then you grow used to the newer build process and come to like it
- and can always read through the Makefiles to trivially figure out
how to display the compiler output. The 14 minute claim reeks with
some feeling of an alternative reason - perhaps you're doing this on a
box with some weird symlink to a dying nfs server or goodness knows
what, some more information would help debugging.

> The build system generates separate command-files,
> hidden from `ls` by having them start with ".", for
> every source-file and link action, plus it even
> makes hidden subdirectories.

Oh no! We'd better call the Microsoft police in to fix this and make
it all ok again. How will we all cope having to give additional flags
to ls? Can't you remember all 26 flags off the top of your head
anyway? ;-)

> The modules build
> even generates its own 'C' source-file for some
> junk that the new `insmod` needs. It's crap, pure
> and simple. Damn crap. All of it.

Right. We'll need to be throwing away the dummy.o stages and a lot of
other kernel code too then. Looks like it's all crap according to you
so no big loss - meanwhile, in the real world, the kernel build
process has used cunning hacks for years. As long as they're more
cunning than a cunning fox, it's all ok.

> This is the best example of technological degeneration
> I've seen in my 40+ years of professional involvement
> in engineering. Somebody may write a book and the
> only fame that will remain will be visual impact
> of a smoking hole that was once a viable operating
> system borne on the ideas of thousands world-wide.

Let's get this right: you get fed up with Fedora didn't you? So you
decided that all the kernel hackers must be part of a secret lawyer
driver conspiracy to create an evil build system that's out to get
you? Cool.

> I qoute; "Have you no shame?"

I have enough to take the flamebait all the way. Sorry folks.

> Penguin : Linux version 2.4.26 on an i686 machine (5570.56 BogoMips).
> Note 96.31% of all statistics are fiction.

Still, not bothered and bitter enough to not have the above tagline.
Look at me! I've got a big processor!

Jon.
Geert Uytterhoeven
2004-10-14 14:18:59 UTC
Permalink
On Thu, 14 Oct 2004, Richard B. Johnson wrote:
> The new kernel build environment is also corrupt. On
> this system, it takes 45 seconds to perform:
>
> make clean
> make bzImage

And how long does `make oldconfig' take?

> With the new build system, same disk, same kernel
> configuration, it takes 14 minutes. And, you can't

BTW, how do you choose the old/new build system with the same kernel?

> even see what the compiler doesn't like.

make V=1?

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ***@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
Roman Zippel
2004-10-13 21:51:10 UTC
Permalink
Hi,

On Wed, 13 Oct 2004, David Howells wrote:

> I've made a patch available to permit module signing in the kernel.
>
> http://people.redhat.com/~dhowells/modsign/modsign-269rc4mm1.diff.bz2

How do you make sure that the module you sign is exactly the module that
you want to get signed?

bye, Roman
Rusty Russell
2004-10-13 23:01:21 UTC
Permalink
On Thu, 2004-10-14 at 07:18, David Howells wrote:
> > Write the code. Then come back and tell me it "isn't that hard".
>
> It isn't that hard.

I see. Well, the good news is that I think your canonicalization step
now covers all the exploits I can think of.

@@ -1536,8 +1538,59 @@ static struct module *load_module(void _
goto free_hdr;
}

- if (len < hdr->e_shoff + hdr->e_shnum * sizeof(Elf_Shdr))
- goto truncated;
+ /* verify the module (validates ELF and checks signature) */
+ gpgsig_ok = 0;
+ err = module_verify(hdr, len);
+ if (err < 0)
+ goto free_hdr;
+ if (err == 1)
+ gpgsig_ok = 1;

/* Convenience variables */
sechdrs = (void *)hdr + hdr->e_shoff;

I'd prefer to see:
err = module_verify(hdr, len, &gpgsig_ok);
if (err)
goto free_hdr;

And then have module_verify for the !CONFIG_MODULE_SIG case (in
module-verify.h) simply be:

if (len < hdr->e_shoff + hdr->e_shnum * sizeof(Elf_Shdr))
return -EINVAL;
*gpgsig_ok = 1;

+/*****************************************************************************/
+/*
+ * verify the ELF structure of a module
+ */
+static int module_verify_elf(struct module_verify_data *mvdata)
+{
+ const Elf_Ehdr *hdr = mvdata->hdr;
+ const Elf_Shdr *section, *section2, *secstop;
+ const Elf_Rela *relas, *rela, *relastop;
+ const Elf_Rel *rels, *rel, *relstop;
+ const Elf_Sym *symbol, *symstop;
+ size_t size, sssize, *secsize, tmp, tmp2;
+ int line;
+
+ size = mvdata->size;
+ mvdata->nsects = hdr->e_shnum;
+
+#define elfcheck(X) \
+do { if (unlikely(!(X))) { line = __LINE__; goto elfcheck_error; } } while(0)
+
+#define seccheck(X) \
+do { if (unlikely(!(X))) { line = __LINE__; goto seccheck_error; } } while(0)
+
+#define symcheck(X) \
+do { if (unlikely(!(X))) { line = __LINE__; goto symcheck_error; } } while(0)
+
+#define relcheck(X) \
+do { if (unlikely(!(X))) { line = __LINE__; goto relcheck_error; } } while(0)
+
+#define relacheck(X) \
+do { if (unlikely(!(X))) { line = __LINE__; goto relacheck_error; } } while(0)
+
+ /* validate the ELF header */
+ elfcheck(hdr->e_ehsize < size);
+ elfcheck(hdr->e_entry == 0);
+ elfcheck(hdr->e_phoff == 0);
+ elfcheck(hdr->e_phnum == 0);
+
+ elfcheck(hdr->e_shoff < size);
+ elfcheck(hdr->e_shoff >= hdr->e_ehsize);
+ elfcheck((hdr->e_shoff & (sizeof(long) - 1)) == 0);
+ elfcheck(hdr->e_shstrndx > 0);
+ elfcheck(hdr->e_shstrndx < hdr->e_shnum);
+
+ tmp = (size_t) hdr->e_shentsize * (size_t) hdr->e_shnum;
+ elfcheck(tmp < size - hdr->e_shoff);

Multiplicative overflow. Also check that hdr->e_shentsize is
sizeof(Elf_Shdr) since you assume that below.

+ /* allocate a table to hold in-file section sizes */
+ mvdata->secsizes = kmalloc(hdr->e_shnum * sizeof(size_t), GFP_KERNEL);
+ if (!mvdata->secsizes)
+ return -ENOMEM;
+ memset(mvdata->secsizes, 0, hdr->e_shnum * sizeof(size_t));

Multiplicative overflow again: we could kmalloc 0 bytes and overflow below.

+ /* validate the ELF section headers */
+ mvdata->sections = mvdata->buffer + hdr->e_shoff;
+ secstop = mvdata->sections + mvdata->nsects;

Subtler multiplicative overflow.

+ sssize = mvdata->sections[hdr->e_shstrndx].sh_size;
+ elfcheck(sssize > 0);
+
+ section = mvdata->sections;
+ seccheck(section->sh_type == SHT_NULL);
+ seccheck(section->sh_size == 0);
+ seccheck(section->sh_offset == 0);
+
+ secsize = mvdata->secsizes + 1;
+ for (section++; section < secstop; secsize++, section++) {
+ seccheck(section->sh_name < sssize);
+ seccheck(section->sh_addr == 0);
+ seccheck(section->sh_link < hdr->e_shnum);
+
+ if (section->sh_entsize > 0)
+ seccheck(section->sh_size % section->sh_entsize == 0);

Divide by zero (thanks Alan!).

+ seccheck(section->sh_offset >= hdr->e_ehsize);
+ seccheck(section->sh_offset < size);
+
+ /* determine the section's in-file size */
+ tmp = size - section->sh_offset;
+ if (section->sh_offset < hdr->e_shoff)
+ tmp = hdr->e_shoff - section->sh_offset;
+
+ for (section2 = mvdata->sections + 1; section2 < secstop; section2++) {
+ if (section->sh_offset < section2->sh_offset) {
+ tmp2 = section2->sh_offset - section->sh_offset;
+ if (tmp2 < tmp)
+ tmp = tmp2;
+ }
+ }
+ *secsize = tmp;
+
+ _debug("Section %ld: %zx bytes at %lx\n",
+ section - mvdata->sections,
+ *secsize,
+ section->sh_offset);
+
+ /* perform section type specific checks */
+ switch (section->sh_type) {
+ case SHT_NOBITS:
+ break;
+
+ case SHT_REL:
+ case SHT_RELA:
+ seccheck(section->sh_info > 0);
+ seccheck(section->sh_info < hdr->e_shnum);
+ /* fall through */
+
+ default:
+ /* most types of section must be contained entirely
+ * within the file */
+ seccheck(section->sh_size <= *secsize);
+ break;
+ }
+ }
+
+ /* validate the ELF section names */
+ section = &mvdata->sections[hdr->e_shstrndx];
+
+ seccheck(section->sh_offset != hdr->e_shoff);
+
+ mvdata->secstrings = mvdata->buffer + section->sh_offset;
+
+ for (section = mvdata->sections + 1; section < secstop; section++) {
+ const char *secname;
+ tmp = sssize - section->sh_name;
+ secname = mvdata->secstrings + section->sh_name;
+ seccheck(secname[0] != 0);
+ seccheck(memchr(secname, 0, tmp) != NULL);
+ }
+
+ /* look for various sections in the module */
+ for (section = mvdata->sections + 1; section < secstop; section++) {
+ switch (section->sh_type) {
+ case SHT_SYMTAB:
+ if (strcmp(mvdata->secstrings + section->sh_name,
+ ".symtab") == 0
+ ) {
+ seccheck(mvdata->symbols == NULL);
+ mvdata->symbols =
+ mvdata->buffer + section->sh_offset;
+ mvdata->nsyms =
+ section->sh_size / sizeof(Elf_Sym);
+ seccheck(section->sh_size > 0);
+ }
+ break;
+
+ case SHT_STRTAB:
+ if (strcmp(mvdata->secstrings + section->sh_name,
+ ".strtab") == 0
+ ) {
+ seccheck(mvdata->strings == NULL);
+ mvdata->strings =
+ mvdata->buffer + section->sh_offset;
+ sssize = mvdata->nstrings = section->sh_size;
+ seccheck(section->sh_size > 0);
+ }
+ break;
+ }
+ }
+
+ if (!mvdata->symbols) {
+ printk("Couldn't locate module symbol table\n");
+ goto format_error;
+ }
+
+ if (!mvdata->strings) {
+ printk("Couldn't locate module strings table\n");
+ goto format_error;
+ }
+
+ /* validate the symbol table */
+ symstop = mvdata->symbols + mvdata->nsyms;
+
+ symbol = mvdata->symbols;
+ symcheck(ELF_ST_TYPE(symbol[0].st_info) == STT_NOTYPE);
+ symcheck(symbol[0].st_shndx == SHN_UNDEF);
+ symcheck(symbol[0].st_value == 0);
+ symcheck(symbol[0].st_size == 0);
+
+ for (symbol++; symbol < symstop; symbol++) {
+ symcheck(symbol->st_name < sssize);

I think you have to check (as above) that st_name is nul terminated
within size.

+ symcheck(symbol->st_shndx < mvdata->nsects ||
+ symbol->st_shndx >= SHN_LORESERVE);
+ }
+
+ /* validate each relocation table as best we can */
+ for (section = mvdata->sections + 1; section < secstop; section++) {
+ section2 = mvdata->sections + section->sh_info;
+
+ switch (section->sh_type) {
+ case SHT_REL:
+ rels = mvdata->buffer + section->sh_offset;
+ relstop = mvdata->buffer + section->sh_offset + section->sh_size;
+
+ for (rel = rels; rel < relstop; rel++) {
+ relcheck(rel->r_offset < section2->sh_size);
+ relcheck(ELF_R_SYM(rel->r_info) > 0);
+ relcheck(ELF_R_SYM(rel->r_info) < mvdata->nsyms);

I think you can overflow here. For REL and RELA sections, you don't
check that sh_size is <= *secsize.

That's all I found,
Rusty.
--
Anyone who quotes me in their signature is an idiot -- Rusty Russell
David Howells
2004-10-14 10:17:46 UTC
Permalink
> I'd appreciate your opinion on the issue at hand. Is it worth 600 lines
> of ELF verification and canonicalization code so we can strip modules
> without altering the signature?

You have to some of the ELF verification anyway, otherwise your suggested way
is just as pointless. You had included somde code in your example, but what
that did wasn't sufficient either - it can trivially be broken.

I think we should verify the ELF anyway upon module load; it doesn't take very
long, and the data cache works in our favour. This then means we can drop some
checks later on in the module loading because we can trust the ELF to a known
extent.

David
David Howells
2004-10-14 11:02:52 UTC
Permalink
> I'd prefer to see:
> err = module_verify(hdr, len, &gpgsig_ok);
> if (err)
> goto free_hdr;

I've been moaned at for doing this before. Other people have told me they
prefer to see the value returned through the return value since there's enough
scope.

> And then have module_verify for the !CONFIG_MODULE_SIG case (in
> module-verify.h) simply be:

I think it should still check the ELF, even if we're not going to check a
signature. This permits us to drop a few checks later in the module loading
process.

> + tmp = (size_t) hdr->e_shentsize * (size_t) hdr->e_shnum;
> + elfcheck(tmp < size - hdr->e_shoff);
>
> Multiplicative overflow.

Not so in this ELF incarnation. The multiply parameters are both 16-bit values
which I cast to 32-bit values before multiplying. I could, I suppose, put
checks on this.

I've added a check to make sure hdr->e_shnum is less than SHN_LORESERVE.

> Also check that hdr->e_shentsize is sizeof(Elf_Shdr) since you assume that
> below.

Added.

> + mvdata->secsizes = kmalloc(hdr->e_shnum * sizeof(size_t), GFP_KERNEL);
> + memset(mvdata->secsizes, 0, hdr->e_shnum * sizeof(size_t));
>
> Multiplicative overflow again: we could kmalloc 0 bytes and overflow below.

A 16-bit value multiplied by a 32/64-bit value which 4 or 8. Where's the
overflow?

Try compiling and running:

#include <stdio.h>
int main() { printf("%zu\n", sizeof(sizeof(char))); return 0; }

> + secstop = mvdata->sections + mvdata->nsects;
>
> Subtler multiplicative overflow.

There's already a check in to make sure it won't overflow, given the
additional checks to limit e_shnum (which is unsigned 16 bits) and that
e_shentsize is correct.

> + if (section->sh_entsize > 0)
> + seccheck(section->sh_size % section->sh_entsize == 0);
>
> Divide by zero (thanks Alan!).

Not so. Look more closely, particularly at the if-statement.

> I think you have to check (as above) that st_name is nul terminated
> within size.

Added.

> I think you can overflow here. For REL and RELA sections, you don't
> check that sh_size is <= *secsize.

I've added checks that the sh_entsize is what I'm expecting. There's already a
check that the section size divides exactly by the ent-size (you claimed it
had a div-by-0 error above).

> That's all I found,

Thanks.

David
David Howells
2004-10-14 11:12:29 UTC
Permalink
>
> How do you make sure that the module you sign is exactly the module that
> you want to get signed?

Currently you have to sign them manually (as I said in that email). The Fedora
kernel spec file signs everything and its dog when you build the RPM.

David
Roman Zippel
2004-10-14 12:01:46 UTC
Permalink
Hi,

On Thu, 14 Oct 2004, David Howells wrote:

> > How do you make sure that the module you sign is exactly the module that
> > you want to get signed?
>
> Currently you have to sign them manually (as I said in that email). The Fedora
> kernel spec file signs everything and its dog when you build the RPM.

I'm trying to understand the reason to stuff this into kernel. Why can't
this check be done before loading the module into the kernel? If you don't
trust insmod, how can you trust the build system?

bye, Roman
David Woodhouse
2004-10-14 12:11:31 UTC
Permalink
On Thu, 2004-10-14 at 14:01 +0200, Roman Zippel wrote:
> If you don't trust insmod, how can you trust the build system?

How are they related? If you don't trust the _build_ system on which the
kernel and modules were compiled and signed, the whole game is lost
anyway.

Insmod is running on the live system, and has nothing to do with the
build system.

--
dwmw2
Roman Zippel
2004-10-14 14:22:42 UTC
Permalink
Hi,

On Thu, 14 Oct 2004, David Woodhouse wrote:

> How are they related? If you don't trust the _build_ system on which the
> kernel and modules were compiled and signed, the whole game is lost
> anyway.

Well, how do you want to win the whole game? Modules are just one part of
it, what about the rest? If I'd be that much concerned about modules, I
would disable module loading completely.

> Insmod is running on the live system, and has nothing to do with the
> build system.

Only a minority of people do cross compile kernels, most people compile
kernel and modules on the same machine, so that there enough points left
to attack the system. Even if the kernel is compiled on a different
machine, how can you trust the kernel you're going to boot next time?
I'm missing how this does fit into the big picture, throwing lots of
code onto modules doesn't make it more safe. In the meantime there are
simpler measures to get the system more secure.

bye, Roman
David Woodhouse
2004-10-14 14:30:51 UTC
Permalink
On Thu, 2004-10-14 at 16:22 +0200, Roman Zippel wrote:
> Only a minority of people do cross compile kernels, most people compile
> kernel and modules on the same machine,

Do they? I spend half my life building kernels, and still only a tiny
minority of my boxen are actually running kernels which were built
locally.

--
dwmw2
Roman Zippel
2004-10-14 21:36:42 UTC
Permalink
Hi,

On Thu, 14 Oct 2004, David Woodhouse wrote:

> If you _really_ need an answer then yes, I accept that module signing
> won't achieve world peace all by itself. There, are you happy now? :)

No. I still don't know, why the kernel has to do this? You avoided to
answer this question already before.

by, Roman
Roman Zippel
2004-10-14 22:38:21 UTC
Permalink
Hi,

On Thu, 14 Oct 2004, David Howells wrote:

> Where do you do it in userspace? glibc? uclibc? insmod is too early and is not
> the only way modules are loaded.

What can the kernel that insmod can't do? How else do you want to load
modules?

bye, Roman
Roman Zippel
2004-10-14 22:15:00 UTC
Permalink
Hi,

On Thu, 14 Oct 2004, David Woodhouse wrote:

> Partly to protect against accidentally-corrupted modules causing damage.
> Partly to allow a sysadmin (or more likely an IT department) to enforce
> a policy that only known and approved modules shall be loaded onto
> machines which they're expected to support. Partly to allow other
> support providers to do likewise, or at least to _detect_ the fact that
> unsupported modules are loaded.

This really doesn't answer why it has to be done in the kernel. As is it
doesn't protect against anything and doing it in user space is as
effective.

bye, Roman
David Woodhouse
2004-10-14 21:52:33 UTC
Permalink
On Thu, 2004-10-14 at 23:36 +0200, Roman Zippel wrote:
> No. I still don't know, why the kernel has to do this? You avoided to
> answer this question already before.

Partly to protect against accidentally-corrupted modules causing damage.
Partly to allow a sysadmin (or more likely an IT department) to enforce
a policy that only known and approved modules shall be loaded onto
machines which they're expected to support. Partly to allow other
support providers to do likewise, or at least to _detect_ the fact that
unsupported modules are loaded.

--
dwmw2
Roman Zippel
2004-10-14 21:03:58 UTC
Permalink
Hi,

On Thu, 14 Oct 2004, David Woodhouse wrote:

> On Thu, 2004-10-14 at 16:22 +0200, Roman Zippel wrote:
> > Only a minority of people do cross compile kernels, most people compile
> > kernel and modules on the same machine,
>
> Do they? I spend half my life building kernels, and still only a tiny
> minority of my boxen are actually running kernels which were built
> locally.

Nice how you conclude from your habits to habits of other people, but why
did you ignore the rest of my mail? The primary topic of this was module
signing not compile habits.

bye, Roman
David Woodhouse
2004-10-14 21:24:20 UTC
Permalink
On Thu, 2004-10-14 at 23:03 +0200, Roman Zippel wrote:
> Nice how you conclude from your habits to habits of other people,

I'm one of the people who I suspect is _most_ likely to compile their
own kernel, and yet _still_ the majority of my boxen are running distro
kernels. It seemed like a relevant enough observation to me, in response
to your bizarre claim that 'most people compile kernel and modules on
the same machine'.

> but why did you ignore the rest of my mail? The primary topic of this
> was module signing not compile habits.

Because it didn't seem relevant. You joined a thread about module
signing asking "how to you want to win the whole game?" and saying "I'm
missing how this does fit into the big picture". Since I was only
discussing the technical details of _how_ we sign modules, I wasn't
really interested in such questions.

If you _really_ need an answer then yes, I accept that module signing
won't achieve world peace all by itself. There, are you happy now? :)

--
dwmw2
David Howells
2004-10-14 22:32:32 UTC
Permalink
Roman Zippel <***@linux-m68k.org> wrote:
> This really doesn't answer why it has to be done in the kernel. As is it
> doesn't protect against anything and doing it in user space is as
> effective.

Where do you do it in userspace? glibc? uclibc? insmod is too early and is not
the only way modules are loaded.

David
David Howells
2004-10-14 12:14:16 UTC
Permalink
> I'm trying to understand the reason to stuff this into kernel. Why can't
> this check be done before loading the module into the kernel? If you don't
> trust insmod, how can you trust the build system?

(1) insmod isn't the only way to load a module.

(2) This helps limit what an intruder can do; particularly if you combine it
with other measures.

(3) Who says the kernel RPM is built on the same machine as the one you
really want to deploy this on for the added protection?

David
David Howells
2004-10-14 18:09:00 UTC
Permalink
I've uploaded an updated module signing patch with Rusty's suggested
additions:

http://people.redhat.com/~dhowells/modsign/modsign-269rc4mm1-2.diff.bz2

David
Roman Zippel
2004-10-15 12:48:21 UTC
Permalink
Hi,

On Fri, 15 Oct 2004, Richard B. Johnson wrote:

> Freedom isn't lost in one big step when the storm-troopers
> show up at your door. It is lost in little pieces, each
> so small that they tend to be ignored.

Unless you have a technical argument, could you please stop your
nonsensical rambling? Thanks.

bye, Roman
Rusty Russell (IBM)
2004-10-15 00:28:10 UTC
Permalink
On Thu, 2004-10-14 at 20:17, David Howells wrote:
> > I'd appreciate your opinion on the issue at hand. Is it worth 600 lines
> > of ELF verification and canonicalization code so we can strip modules
> > without altering the signature?
>
> You have to some of the ELF verification anyway, otherwise your suggested way
> is just as pointless. You had included somde code in your example, but what
> that did wasn't sufficient either - it can trivially be broken.

The current approach is working just fine. I'm not the one trying to
prevent root from inserting malicious modules. You are, so you need to
do the checks.

Rusty.
Roman Zippel
2004-10-15 11:12:07 UTC
Permalink
Hi,

On Thu, 14 Oct 2004, David Howells wrote:

> I've uploaded an updated module signing patch with Rusty's suggested
> additions:

Can someone please put this patch into some context, where it's not
completely pointless? As is it does not make anything more secure.
Why is the kernel more trustable than a kernel module?
If someone could show me how I can trust the running kernel, it should be
rather easy to extend the same measures to modules without the need for
this patch.

bye, Roman
Josh Boyer
2004-10-15 12:31:32 UTC
Permalink
On Fri, 2004-10-15 at 07:10, Richard B. Johnson wrote:
> On Fri, 15 Oct 2004, Roman Zippel wrote:
>
> > Hi,
> >
> > On Thu, 14 Oct 2004, David Howells wrote:
> >
> >> I've uploaded an updated module signing patch with Rusty's suggested
> >> additions:
> >
> > Can someone please put this patch into some context, where it's not
> > completely pointless? As is it does not make anything more secure.
> > Why is the kernel more trustable than a kernel module?
> > If someone could show me how I can trust the running kernel, it should be
> > rather easy to extend the same measures to modules without the need for
> > this patch.
> >
> > bye, Roman
> > -
>
> This is just the first step, which I think must be quashed
> immediately. The ultimate goal is to control what you put
> into your computer. Eventually, some central licensing
> authority will certify any modules that are allowed to
> be run in your computer. Doesn't anybody else see this?

cd linux-2.6;
patch -R -p1 < ../<modsign patch name>

josh
Gene Heskett
2004-10-15 15:53:08 UTC
Permalink
On Friday 15 October 2004 08:31, Josh Boyer wrote:
>On Fri, 2004-10-15 at 07:10, Richard B. Johnson wrote:
>> On Fri, 15 Oct 2004, Roman Zippel wrote:
>> > Hi,
>> >
>> > On Thu, 14 Oct 2004, David Howells wrote:
>> >> I've uploaded an updated module signing patch with Rusty's
>> >> suggested additions:
>> >
>> > Can someone please put this patch into some context, where it's
>> > not completely pointless? As is it does not make anything more
>> > secure. Why is the kernel more trustable than a kernel module?
>> > If someone could show me how I can trust the running kernel, it
>> > should be rather easy to extend the same measures to modules
>> > without the need for this patch.
>> >
>> > bye, Roman
>> > -
>>
>> This is just the first step, which I think must be quashed
>> immediately. The ultimate goal is to control what you put
>> into your computer. Eventually, some central licensing
>> authority will certify any modules that are allowed to
>> be run in your computer. Doesn't anybody else see this?
>
>cd linux-2.6;
>patch -R -p1 < ../<modsign patch name>
>
>josh
>
Yes, but what happens if it gets into the tarballs from kernel.org.

Stop this nonsense Linus, now.

--
Cheers, Gene
"There are four boxes to be used in defense of liberty:
soap, ballot, jury, and ammo. Please use in that order."
-Ed Howdershelt (Author)
99.27% setiathome rank, not too shabby for a WV hillbilly
Yahoo.com attorneys please note, additions to this message
by Gene Heskett are:
Copyright 2004 by Maurice Eugene Heskett, all rights reserved.
Josh Boyer
2004-10-15 16:17:29 UTC
Permalink
On Fri, 2004-10-15 at 10:53, Gene Heskett wrote:
> >
> >cd linux-2.6;
> >patch -R -p1 < ../<modsign patch name>
> >
> >josh
> >
> Yes, but what happens if it gets into the tarballs from kernel.org.
>
> Stop this nonsense Linus, now.

While my original post was more of a symbolic "I think you're being a
bit over-dramatic" response, it's still valid once it's in a tarball
too. A tarball is just source that has the patch applied...

I personally don't see anything wrong with concept of signed modules.
Make it a config option and call it good. I'd probably never run with
signed modules with a kernel I built myself, but that's my choice.
Others can choose differently.

Let's separate the technical details from the opinions about whether
such a feature will end the free world as we know it or not. (Which it
won't).

josh
Richard B. Johnson
2004-10-15 16:59:50 UTC
Permalink
On Fri, 15 Oct 2004, Josh Boyer wrote:

> On Fri, 2004-10-15 at 10:53, Gene Heskett wrote:
>>>
>>> cd linux-2.6;
>>> patch -R -p1 < ../<modsign patch name>
>>>
>>> josh
>>>
>> Yes, but what happens if it gets into the tarballs from kernel.org.
>>
>> Stop this nonsense Linus, now.
>
> While my original post was more of a symbolic "I think you're being a
> bit over-dramatic" response, it's still valid once it's in a tarball
> too. A tarball is just source that has the patch applied...
>
> I personally don't see anything wrong with concept of signed modules.
> Make it a config option and call it good. I'd probably never run with
> signed modules with a kernel I built myself, but that's my choice.
> Others can choose differently.
>
> Let's separate the technical details from the opinions about whether
> such a feature will end the free world as we know it or not. (Which it
> won't).
>
> josh
>

The technical details are that "signed", "sealed", "certified",
relate to policy. For years policy was not allowed to be included in
the kernel. In recent times, the kernel has become filthy with
policy.

For instance, a simple module that implements open/close has this

00000000 r __mod_license23
00000047 r __module_depends
00000020 r __mod_vermagic5
00000000 D __this_module
00000000 r ____versions

... used to enforce somebody's policy (whoever wrote the latest
module code), not your policy nor my policy, just someone's policy
which becomes the de-facto kernel "law". That's why there must
not be policy in the kernel because it's not possible to get
it right. What's right for you is wrong for another.

We let this start when there were problems with secret video
modules. Nobody wanted to debug a kernel that could be corrupted
by a module where nobody could read the source-code. So if there
isn't a MODULE_LICENSE("POLICY") then a 'tainted' mark goes
in any OOPS report. Well, they got away with that. It was
explained away as being "good" policy. Now they are making
more policy.

And, yes, the end-of-the-world-as-we-know-it, comes one interval
at a time.

Cheers,
Dick Johnson
Penguin : Linux version 2.6.8 on an i686 machine (5537.79 BogoMips).
Note 96.31% of all statistics are fiction.
David Woodhouse
2004-10-15 17:08:42 UTC
Permalink
On Fri, 2004-10-15 at 12:59 -0400, Richard B. Johnson wrote:
> We let this start when there were problems with secret video
> modules. Nobody wanted to debug a kernel that could be corrupted
> by a module where nobody could read the source-code. So if there
> isn't a MODULE_LICENSE("POLICY") then a 'tainted' mark goes
> in any OOPS report. Well, they got away with that. It was
> explained away as being "good" policy. Now they are making
> more policy.

Please quit being a fuckwit, Richard. You've escaped my killfile so far
despite being in so many other peoples, because it's often amusing to
find the deliberate mistake in your posts when they actually appear
plausible.

The above is not policy; it's a mechanism. It provides the information.
Developers _use_ that information to implement their own policy, and
refrain from helping those whose kernels are tainted.

Signing kernel modules is just the same.

--
dwmw2
Richard B. Johnson
2004-10-15 17:35:37 UTC
Permalink
On Fri, 15 Oct 2004, David Woodhouse wrote:

> On Fri, 2004-10-15 at 12:59 -0400, Richard B. Johnson wrote:
>> We let this start when there were problems with secret video
>> modules. Nobody wanted to debug a kernel that could be corrupted
>> by a module where nobody could read the source-code. So if there
>> isn't a MODULE_LICENSE("POLICY") then a 'tainted' mark goes
>> in any OOPS report. Well, they got away with that. It was
>> explained away as being "good" policy. Now they are making
>> more policy.
>
> Please quit being a fuckwit, Richard. You've escaped my killfile so far
> despite being in so many other peoples, because it's often amusing to
> find the deliberate mistake in your posts when they actually appear
> plausible.
>
> The above is not policy; it's a mechanism. It provides the information.
> Developers _use_ that information to implement their own policy, and
> refrain from helping those whose kernels are tainted.
>
> Signing kernel modules is just the same.

You just don't get it. This is policy.

Script started on Fri 15 Oct 2004 01:13:59 PM EDT
# insmod xxx.ko
xxx: module license 'BSD' taints kernel.
# exit
Script done on Fri 15 Oct 2004 01:14:26 PM EDT

How dare somebody decide that a BSD license that
makes source-code available, but doesn't give its
control to Stallman, somehow taints the kernel.

Wake up! This is policy and bad policy, too.
If it wasn't for UC Berkeley, there wouldn't even
be a Linux, it was deliberately designed to be
compatible so the Berkeley (read UNIX) utilities
would run. This was well before GNU did anything
but a 'C' compiler and eimacs.

BTW us.ibm.com has an interesting policy, the
name in the DNS expires in a few minutes and only
becomes available for a few minutes each day. That
means that anything sent to Josh Boyer <***@us.ibm.com>,
in the c.c. list, above, gets cached here until the
name resolves.

Cheers,
Dick Johnson
Penguin : Linux version 2.6.8 on an i686 machine (5537.79 BogoMips).
Note 96.31% of all statistics are fiction.
Lee Revell
2004-10-15 20:56:33 UTC
Permalink
On Fri, 2004-10-15 at 13:35, Richard B. Johnson wrote:
> You just don't get it. This is policy.
>
> Script started on Fri 15 Oct 2004 01:13:59 PM EDT
> # insmod xxx.ko
> xxx: module license 'BSD' taints kernel.
> # exit
> Script done on Fri 15 Oct 2004 01:14:26 PM EDT

OK, now _this_ is undeniably policy, I would go so far as to call it
bullshit. There is a fundamental technical reason to have closed source
modules taint the kernel, because you cannot debug a closed source
module. But come on, a BSD license tainting the kernel? That is
zealotry, pure and simple.

Lee
Greg KH
2004-10-15 21:18:09 UTC
Permalink
On Fri, Oct 15, 2004 at 04:56:33PM -0400, Lee Revell wrote:
> On Fri, 2004-10-15 at 13:35, Richard B. Johnson wrote:
> > You just don't get it. This is policy.
> >
> > Script started on Fri 15 Oct 2004 01:13:59 PM EDT
> > # insmod xxx.ko
> > xxx: module license 'BSD' taints kernel.
> > # exit
> > Script done on Fri 15 Oct 2004 01:14:26 PM EDT
>
> OK, now _this_ is undeniably policy, I would go so far as to call it
> bullshit. There is a fundamental technical reason to have closed source
> modules taint the kernel, because you cannot debug a closed source
> module.

If you have a BSD licensed module, you do not have to provide the source
code for it.

Dual BSD/GPL licensed modules do not change the taint flag.

greg k-h
Chris Friesen
2004-10-15 21:34:38 UTC
Permalink
Greg KH wrote:

> If you have a BSD licensed module, you do not have to provide the source
> code for it.

Maybe we need a "BSD with source" module string that doesn't taint? Or is that
getting too ridiculous?

Chris
Richard B. Johnson
2004-10-15 22:08:37 UTC
Permalink
On Fri, 15 Oct 2004, Chris Friesen wrote:

> Greg KH wrote:
>
>> If you have a BSD licensed module, you do not have to provide the source
>> code for it.
>
> Maybe we need a "BSD with source" module string that doesn't taint? Or is
> that getting too ridiculous?
>
> Chris
>

Like I said, once you put policy in the kernel it can't be right:

module: module license 'Public domain' taints kernel.

And, of course, one can always do:

echo "0" >/proc/sys/kernel/tainted

... to make everything "better" after you've loaded a module
from Hell.

Any time somebody puts some "deny" hooks in readable source-code
(the kernel) somebody can either remove them or make a corresponding
countermeasure, usually in user-mode. It is entirely counter-productive
to bloat the kernel with this kind of stuff.

The moving of module load/unload code from user-mode code to the
kernel is a prime example. Time would have been better spent
removing the races in the hot-swap and module-removal code.

One can make a 'certified' kernel with 'certified' modules
for some hush-hush project. Adding this kind of junk isn't
how it's done. You just take your favorite kernel with the
modules you require, you verify that it meets your security
requirements, then you CRC the kernel and its modules. You
keep the CRCs somewhere safe, available from a read-only
source like a CD/ROM or a network file-server. You automatically
check these CRCs occasionally using a read-only program on
read-only source like the network or a CD/ROM. If the checks
fail, you call the "super" and shut down the system.

It's done all the time and it works. Putting more strings
and other junk in the kernel with all the checking-code
just tries to hide from the real elements of security.

But, it's not __really__ security everybody's after. It's
sucking up to GNU. For 15 years, before there was a GNU, I
was the SYSOP of the "Program Exchange". I know what free
software really is. And, it has nothing to do with FSF and
Richard Stallman. That's where M$ got their first version
of Flight Simulator from. The source was in Turbo Pascal
and MASM assembly. I wrote the assembly. So I know how
these things go. Been there, done that.

Cheers,
Dick Johnson
Penguin : Linux version 2.6.8 on an i686 machine (5537.79 BogoMips).
Note 96.31% of all statistics are fiction.
Richard B. Johnson
2004-10-18 12:53:46 UTC
Permalink
> On Fri, 15 Oct 2004, Chris Friesen wrote:
>
>> Greg KH wrote:
>>
>>> If you have a BSD licensed module, you do not have to provide the source
>>> code for it.
>>
>> Maybe we need a "BSD with source" module string that doesn't taint? Or is
>> that getting too ridiculous?
>>
>> Chris

If the whole module license issue is truly one of being able
to review the source, then certainly nobody would fear the
inclusion of a "PUBLIC" license string. This would fit the
broad classification of publicly-available sources, not
necessarily just in the "Public domain". For instance, when
a company puts the sources for some driver on it's Web Page,
but doesn't want to have anything to do with Mr. Stallman.

Here is a patch. I also added an array containing, possibly
more in the future, acceptable strings.



--- linux-2.6.8/kernel/module.c.orig 2004-10-18 08:21:28.000000000 -0400
+++ linux-2.6.8/kernel/module.c 2004-10-18 08:37:19.000000000 -0400
@@ -48,6 +48,18 @@
#define ARCH_SHF_SMALL 0
#endif

+/*
+ * List of acceptable module-license strings.
+ */
+static const char *licok[]= {
+ "GPL",
+ "GPL v2",
+ "CPL and additional rights",
+ "Dual BSD/GPL",
+ "Dual MPL/GPL",
+ "PUBLIC" };
+
+
/* If this is set, the section belongs in the init part of the module */
#define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1))

@@ -1362,11 +1374,11 @@

static inline int license_is_gpl_compatible(const char *license)
{
- return (strcmp(license, "GPL") == 0
- || strcmp(license, "GPL v2") == 0
- || strcmp(license, "GPL and additional rights") == 0
- || strcmp(license, "Dual BSD/GPL") == 0
- || strcmp(license, "Dual MPL/GPL") == 0);
+ size_t i;
+ for(i=0; i < sizeof(licok) / sizeof(licok[0]); i++)
+ if(strcmp(license, licok[i]) == 0)
+ return 1;
+ return 0;
}

static void set_license(struct module *mod, const char *license)


Cheers,
Dick Johnson
Penguin : Linux version 2.6.8 on an i686 machine (5537.79 BogoMips).
Note 96.31% of all statistics are fiction.
Matthew Garrett
2004-10-18 13:53:21 UTC
Permalink
Richard B. Johnson <***@chaos.analogic.com> wrote:

> If the whole module license issue is truly one of being able
> to review the source, then certainly nobody would fear the
> inclusion of a "PUBLIC" license string. This would fit the
> broad classification of publicly-available sources, not
> necessarily just in the "Public domain". For instance, when
> a company puts the sources for some driver on it's Web Page,
> but doesn't want to have anything to do with Mr. Stallman.

This potentially leds to arguments about whether developers who have
seen your publically available code are then tainted. If you don't want
anything to do with Mr. Stallman, why not just use a BSD-style license?

--
Matthew Garrett | mjg59-chiark.mail.linux-***@srcf.ucam.org
Richard B. Johnson
2004-10-18 14:09:14 UTC
Permalink
On Mon, 18 Oct 2004, Matthew Garrett wrote:

> Richard B. Johnson <***@chaos.analogic.com> wrote:
>
>> If the whole module license issue is truly one of being able
>> to review the source, then certainly nobody would fear the
>> inclusion of a "PUBLIC" license string. This would fit the
>> broad classification of publicly-available sources, not
>> necessarily just in the "Public domain". For instance, when
>> a company puts the sources for some driver on it's Web Page,
>> but doesn't want to have anything to do with Mr. Stallman.
>
> This potentially leds to arguments about whether developers who have
> seen your publically available code are then tainted. If you don't want

Tainted??? Tainted to what. The stated reason for having module-
license strings in kernel modules was to save developers from
having to locate "bugs" that were caused by proprietary modules
for which there was no source-code available. Now, you say that
if somebody were to review publicly-available source-code, they
become tainted? This is unmitigated political bullshit.

> anything to do with Mr. Stallman, why not just use a BSD-style license?
>
> --
> Matthew Garrett | mjg59-chiark.mail.linux-***@srcf.ucam.org
>

Because it doesn't allow "BSD"! Also, even my mailer doesn't
like the patch!!! Here it is again....


--- linux-2.6.8/kernel/module.c.orig 2004-10-18 08:21:28.000000000 -0400
+++ linux-2.6.8/kernel/module.c 2004-10-18 08:37:19.000000000 -0400
@@ -48,6 +48,18 @@
#define ARCH_SHF_SMALL 0
#endif

+/*
+ * List of acceptible module-license strings.
+ */
+static const char *licok[]= {
+ "GPL",
+ "GPL v2",
+ "GPL and additional rights",
+ "Dual BSD/GPL",
+ "Dual MPL/GPL",
+ "PUBLIC" };
+
+
/* If this is set, the section belongs in the init part of the module */
#define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1))

@@ -1362,11 +1374,11 @@

static inline int license_is_gpl_compatible(const char *license)
{
- return (strcmp(license, "GPL") == 0
- || strcmp(license, "GPL v2") == 0
- || strcmp(license, "GPL and additional rights") == 0
- || strcmp(license, "Dual BSD/GPL") == 0
- || strcmp(license, "Dual MPL/GPL") == 0);
+ size_t i;
+ for(i=0; i < sizeof(licok) / sizeof(licok[0]); i++)
+ if(strcmp(license, licok[i]) == 0)
+ return 1;
+ return 0;
}

static void set_license(struct module *mod, const char *license)


Cheers,
Dick Johnson
Penguin : Linux version 2.6.8 on an i686 machine (5537.79 BogoMips).
Note 96.31% of all statistics are fiction.
Greg KH
2004-10-18 16:33:46 UTC
Permalink
On Mon, Oct 18, 2004 at 08:53:46AM -0400, Richard B. Johnson wrote:
> +/*
> + * List of acceptable module-license strings.
> + */
> +static const char *licok[]= {
> + "GPL",
> + "GPL v2",
> + "CPL and additional rights",

The CPL is very different from the GPL and the two are not compatible,
so this isn't an acceptable patch.

thanks,

greg k-h
Richard B. Johnson
2004-10-18 17:14:32 UTC
Permalink
On Mon, 18 Oct 2004, Greg KH wrote:

> On Mon, Oct 18, 2004 at 08:53:46AM -0400, Richard B. Johnson wrote:
>> +/*
>> + * List of acceptable module-license strings.
>> + */
>> +static const char *licok[]= {
>> + "GPL",
>> + "GPL v2",
>> + "CPL and additional rights",
>
> The CPL is very different from the GPL and the two are not compatible,
> so this isn't an acceptable patch.
>
> thanks,
>
> greg k-h

Right and it wasn't that way when the patch was generated and
C and G are so far apart it couldn't be a typo so I don't
know why it shows up that way.


Script started on Mon 18 Oct 2004 01:10:46 PM EDT
# grep GPL sent-mail
> MODULE_LICENSE("GPL");
> If you can reproduce the same problem with some GPL version of
iriUIyCrAzt70kZPD/T3qtlHKJ+UwCGrMj1c6GPLs/J0VFvR2NEqY369qAC7
>> * lawyer, and require that a GPL License exist for every kernel
> GPL licensing. It provides help in understanding what symbols are
> source or GPL information.
a bug report. This whole GPL thing has taken a real stupid
> MODULE_LICENSE("GPL");
iriUIyCrAzt70kZPD/T3qtlHKJ+UwCGrMj1c6GPLs/J0VFvR2NEqY369qAC7
+ "GPL",
+ "GPL v2",
+ "GPL and additional rights",
+ "Dual BSD/GPL",
+ "Dual MPL/GPL",
- return (strcmp(license, "GPL") == 0
- || strcmp(license, "GPL v2") == 0
- || strcmp(license, "GPL and additional rights") == 0
- || strcmp(license, "Dual BSD/GPL") == 0
- || strcmp(license, "Dual MPL/GPL") == 0);
+ "GPL",
+ "GPL v2",
+ "GPL and additional rights",
+ "Dual BSD/GPL",
+ "Dual MPL/GPL",
- return (strcmp(license, "GPL") == 0
- || strcmp(license, "GPL v2") == 0
- || strcmp(license, "GPL and additional rights") == 0
- || strcmp(license, "Dual BSD/GPL") == 0
- || strcmp(license, "Dual MPL/GPL") == 0);
>> + "GPL",
>> + "GPL v2",
> ^^^ GPL
# bye
bash: bye: command not found
# exit

Script done on Mon 18 Oct 2004 01:11:05 PM EDT


Cheers,
Dick Johnson
Penguin : Linux version 2.6.8 on an i686 machine (5537.79 BogoMips).
Note 96.31% of all statistics are fiction.
Richard B. Johnson
2004-10-18 17:28:41 UTC
Permalink
On Mon, 18 Oct 2004, Richard B. Johnson wrote:

> On Mon, 18 Oct 2004, Greg KH wrote:
>
>> On Mon, Oct 18, 2004 at 08:53:46AM -0400, Richard B. Johnson wrote:
>>> +/*
>>> + * List of acceptable module-license strings.
>>> + */
>>> +static const char *licok[]= {
>>> + "GPL",
>>> + "GPL v2",
>>> + "CPL and additional rights",
>>
>> The CPL is very different from the GPL and the two are not compatible,
>> so this isn't an acceptable patch.
>>
>> thanks,
>>
>> greg k-h
>
> Right and it wasn't that way when the patch was generated and
> C and G are so far apart it couldn't be a typo so I don't
> know why it shows up that way.
>
>
> Script started on Mon 18 Oct 2004 01:10:46 PM EDT
> # grep GPL sent-mail
>> MODULE_LICENSE("GPL");
>> If you can reproduce the same problem with some GPL version of
> iriUIyCrAzt70kZPD/T3qtlHKJ+UwCGrMj1c6GPLs/J0VFvR2NEqY369qAC7
>>> * lawyer, and require that a GPL License exist for every kernel
>> GPL licensing. It provides help in understanding what symbols are
>> source or GPL information.
> a bug report. This whole GPL thing has taken a real stupid
>> MODULE_LICENSE("GPL");
> iriUIyCrAzt70kZPD/T3qtlHKJ+UwCGrMj1c6GPLs/J0VFvR2NEqY369qAC7
> + "GPL",
> + "GPL v2",
> + "GPL and additional rights",
> + "Dual BSD/GPL",
> + "Dual MPL/GPL",
> - return (strcmp(license, "GPL") == 0
> - || strcmp(license, "GPL v2") == 0
> - || strcmp(license, "GPL and additional rights") == 0
> - || strcmp(license, "Dual BSD/GPL") == 0
> - || strcmp(license, "Dual MPL/GPL") == 0);
> + "GPL",
> + "GPL v2",
> + "GPL and additional rights",
> + "Dual BSD/GPL",
> + "Dual MPL/GPL",
> - return (strcmp(license, "GPL") == 0
> - || strcmp(license, "GPL v2") == 0
> - || strcmp(license, "GPL and additional rights") == 0
> - || strcmp(license, "Dual BSD/GPL") == 0
> - || strcmp(license, "Dual MPL/GPL") == 0);
>>> + "GPL",
>>> + "GPL v2",
>> ^^^ GPL
> # bye
> bash: bye: command not found
> # exit
>
> Script done on Mon 18 Oct 2004 01:11:05 PM EDT
>
>
> Cheers,
> Dick Johnson
> Penguin : Linux version 2.6.8 on an i686 machine (5537.79 BogoMips).
> Note 96.31% of all statistics are fiction.
>

Single-bit error somewhere.

G = 0x47
C = 0x43

>>> + "GPL v2",
>> ^^^ GPL

... from the 'grep' above.

When somebody sent me a correction, it didn't appear here
as though it needed correction but I sent it again.

Cheers,
Dick Johnson
Penguin : Linux version 2.6.8 on an i686 machine (5537.79 BogoMips).
Note 96.31% of all statistics are fiction.
Josh Boyer
2004-10-15 17:46:06 UTC
Permalink
On Fri, 2004-10-15 at 11:59, Richard B. Johnson wrote:
>
> The technical details are that "signed", "sealed", "certified",
> relate to policy. For years policy was not allowed to be included in
> the kernel. In recent times, the kernel has become filthy with
> policy.

I'd disagree. Do you consider SELinux to be policy as well just because
it's in the kernel?

As David said in his response, it's a mechanism. Whether _you_ choose
to use it or not decides the "policy". That's why I said put a config
option around it. You would still have _choice_.

> it right. What's right for you is wrong for another.

Absolutely. So why are you trying to prevent people that want to use
module signing from doing so?

josh
Tonnerre
2004-10-15 20:11:47 UTC
Permalink
Salut,

On Fri, Oct 15, 2004 at 12:46:06PM -0500, Josh Boyer wrote:
> I'd disagree. Do you consider SELinux to be policy as well just because
> it's in the kernel?
>
> As David said in his response, it's a mechanism. Whether _you_ choose
> to use it or not decides the "policy". That's why I said put a config
> option around it. You would still have _choice_.

Actually, even though I agree that Richard is overdramatizing, his
point is not completely invalid. Remembering the trusted computing
initiative, it's always a question of who holds the keys to your
computer. In our case it's no problem, since we compile all the
software on the computer ourselves, and thus we have full control over
what we do.

What trusted computing revealed is that there is at least amongst some
companies a desire to be able to dictate what's going on on your
computer. Think Disney here.

Sure, TCPA is dead. But I've seen a TPM chip. On an Intel test board.
IBM has them as well. I agree that we can trust all these entities
now. But what's going to happen ten years from now? We don't know.

I'm not proclaiming paranoia. I don't say we should burn this patch
alive. I only say that from time to time we have to take care of not
getting to the Wernher von Braun excuse.

Tonnerre

PS. I did a module signing patch some years ago. I did a framework. I
did tests. I got scared of its power. All I say is, take care.
Thomas Weber
2004-10-17 20:18:32 UTC
Permalink
On Fri, Oct 15, 2004 at 10:11:47PM +0200, Tonnerre wrote:
>
> What trusted computing revealed is that there is at least amongst some
> companies a desire to be able to dictate what's going on on your
> computer. Think Disney here.


> Tonnerre
>
> PS. I did a module signing patch some years ago. I did a framework. I
> did tests. I got scared of its power. All I say is, take care.

Think about companies deploing binary only drivers for their hardware.
I guess they'd be happy to have a 'feature' like this in the kernel.
We might end up with hardware companies deploying binary only signed
modules for the major distributions (with which they have deals).
We might end up with weird patches from those companies to get their key
into the kernel source in order to be able to load their signed module.

Once a module itself requires this feature in the kernel you don't have
the choice of saying 'No' to this option of compile time and you can't
simply revert this patch anymore as others have suggested.

This patch would give power to those who make binary distributions and
(binary only) modules not to the admin who runs the system.
Only allowing modules to be loaded from a secured area (read only
device, signed 'container' of modules...) and leaving it to the
admin which modules he puts into this area would address all the reasons
for this patch without taking power away from the owner of the system.

Tom
Geert Uytterhoeven
2004-10-17 20:52:38 UTC
Permalink
On Sun, 17 Oct 2004, Thomas Weber wrote:
> On Fri, Oct 15, 2004 at 10:11:47PM +0200, Tonnerre wrote:
> > What trusted computing revealed is that there is at least amongst some
> > companies a desire to be able to dictate what's going on on your
> > computer. Think Disney here.
>
>
> > Tonnerre
> >
> > PS. I did a module signing patch some years ago. I did a framework. I
> > did tests. I got scared of its power. All I say is, take care.
>
> Think about companies deploing binary only drivers for their hardware.
> I guess they'd be happy to have a 'feature' like this in the kernel.
> We might end up with hardware companies deploying binary only signed
> modules for the major distributions (with which they have deals).
> We might end up with weird patches from those companies to get their key
> into the kernel source in order to be able to load their signed module.
>
> Once a module itself requires this feature in the kernel you don't have
> the choice of saying 'No' to this option of compile time and you can't
> simply revert this patch anymore as others have suggested.
>
> This patch would give power to those who make binary distributions and
> (binary only) modules not to the admin who runs the system.
> Only allowing modules to be loaded from a secured area (read only
> device, signed 'container' of modules...) and leaving it to the
> admin which modules he puts into this area would address all the reasons
> for this patch without taking power away from the owner of the system.

Solution: the module loader refuses to load signed modules that are not GPLed?
I.e. a combination of MODULE_LICENSE() and signed modules.

Opens up interesting legal actions if the signature owner signs modules that
claim to be GPL, but aren't. Digital signatures are starting to become valid
signatures in many countries...

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ***@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
Thomas Weber
2004-10-17 21:25:11 UTC
Permalink
On Sun, Oct 17, 2004 at 10:52:38PM +0200, Geert Uytterhoeven wrote:
> On Sun, 17 Oct 2004, Thomas Weber wrote:
> > On Fri, Oct 15, 2004 at 10:11:47PM +0200, Tonnerre wrote:
> > > What trusted computing revealed is that there is at least amongst some
> > > companies a desire to be able to dictate what's going on on your
> > > computer. Think Disney here.
> >
> >
> > > Tonnerre
> > >
> > > PS. I did a module signing patch some years ago. I did a framework. I
> > > did tests. I got scared of its power. All I say is, take care.
> >
> > Think about companies deploing binary only drivers for their hardware.
> > I guess they'd be happy to have a 'feature' like this in the kernel.
> > We might end up with hardware companies deploying binary only signed
> > modules for the major distributions (with which they have deals).
> > We might end up with weird patches from those companies to get their key
> > into the kernel source in order to be able to load their signed module.
> >
> > Once a module itself requires this feature in the kernel you don't have
> > the choice of saying 'No' to this option of compile time and you can't
> > simply revert this patch anymore as others have suggested.
> >
> > This patch would give power to those who make binary distributions and
> > (binary only) modules not to the admin who runs the system.
> > Only allowing modules to be loaded from a secured area (read only
> > device, signed 'container' of modules...) and leaving it to the
> > admin which modules he puts into this area would address all the reasons
> > for this patch without taking power away from the owner of the system.
>
> Solution: the module loader refuses to load signed modules that are not GPLed?
> I.e. a combination of MODULE_LICENSE() and signed modules.
>
> Opens up interesting legal actions if the signature owner signs modules that
> claim to be GPL, but aren't. Digital signatures are starting to become valid
> signatures in many countries...

What if distributions ship with this check removed (maybe distributions that
have deals with such companies)?
What if a binary module comes with a kernel source patch that removes this
check?
Who's gonna pay the lawyers?

Tom
Rusty Russell
2004-10-15 00:47:51 UTC
Permalink
On Thu, 2004-10-14 at 21:02, David Howells wrote:
> > I'd prefer to see:
> > err = module_verify(hdr, len, &gpgsig_ok);
> > if (err)
> > goto free_hdr;
>
> I've been moaned at for doing this before. Other people have told me they
> prefer to see the value returned through the return value since there's enough
> scope.

I suppose this is a matter of taste. I find it much clearer this way,
to overloading 0 vs 1 returns.

> > And then have module_verify for the !CONFIG_MODULE_SIG case (in
> > module-verify.h) simply be:
>
> I think it should still check the ELF, even if we're not going to check a
> signature. This permits us to drop a few checks later in the module loading
> process.

Not really: I've never had a single bug report, and I've had a fair
number of bug reports. Without signed modules, it's really 300 lines of
code for no actual gain. OTOH, it's going to be in the tree anyway.
Unless we want to "sign" modules with a straight checksum when
!CONFIG_MODULE_SIG? I'm not really convinced it's worth it. Thoughts
welcome.

> > Multiplicative overflow.
>
> Not so in this ELF incarnation.

Sorry, my bad.

Now we have the code in front of us, I'll ask you to answer honestly.
Do *you* think that the extra ~600 lines of code is a worthwhile
tradeoff so we can simply strip modules without resigning? You know my
opinion, but you've done the code, and if you're really convinced of
that, I'll ack it.

(I'm not sure that having a whole GPG format parser in the kernel
matches our minimalistic ideals either, but I can see a much stronger
incentive there: less risk of weakening the signatures, convenience, and
the signing infrastructure can be used for other things).

Cheers,
Rusty.
--
Anyone who quotes me in their signature is an idiot -- Rusty Russell
David Woodhouse
2004-10-15 14:01:37 UTC
Permalink
On Fri, 2004-10-15 at 13:12 +0200, Roman Zippel wrote:
> > I've uploaded an updated module signing patch with Rusty's suggested
> > additions:
>
> Can someone please put this patch into some context, where it's not
> completely pointless? As is it does not make anything more secure.
> Why is the kernel more trustable than a kernel module?

Because it's not that hard to put the kernel onto read-only media or in
a flash chip to which you physically cut the Vpen line.

One solution is just to disallow modules altogether -- but that isn't
really ideal in a number of cases. Allowing only certain _known_ modules
is a more functional solution.

--
dwmw2
Roman Zippel
2004-10-15 14:28:17 UTC
Permalink
Hi,

On Fri, 15 Oct 2004, David Woodhouse wrote:

> > Can someone please put this patch into some context, where it's not
> > completely pointless? As is it does not make anything more secure.
> > Why is the kernel more trustable than a kernel module?
>
> Because it's not that hard to put the kernel onto read-only media or in
> a flash chip to which you physically cut the Vpen line.

So put the modules there as well or put a ramdisk there that does module
verifying and loading (and disable module loading after that).
Again, why is this patch necessary? I have to repeat my main point from
the last mail: If someone could show me how I can trust the running
kernel, it should be rather easy to extend the same measures to modules
without the need for this patch.
Show me a way that this is not possible and I'll agree with you that this
patch is needed.

bye, Roman
Gene Heskett
2004-10-15 15:54:39 UTC
Permalink
On Friday 15 October 2004 10:01, David Woodhouse wrote:
>On Fri, 2004-10-15 at 13:12 +0200, Roman Zippel wrote:
>> > I've uploaded an updated module signing patch with Rusty's
>> > suggested additions:
>>
>> Can someone please put this patch into some context, where it's
>> not completely pointless? As is it does not make anything more
>> secure. Why is the kernel more trustable than a kernel module?
>
>Because it's not that hard to put the kernel onto read-only media or
> in a flash chip to which you physically cut the Vpen line.
>
>One solution is just to disallow modules altogether -- but that
> isn't really ideal in a number of cases. Allowing only certain
> _known_ modules is a more functional solution.

The point being that who decides what is a known module?

--
Cheers, Gene
"There are four boxes to be used in defense of liberty:
soap, ballot, jury, and ammo. Please use in that order."
-Ed Howdershelt (Author)
99.27% setiathome rank, not too shabby for a WV hillbilly
Yahoo.com attorneys please note, additions to this message
by Gene Heskett are:
Copyright 2004 by Maurice Eugene Heskett, all rights reserved.
Arjan van de Ven
2004-10-15 16:33:05 UTC
Permalink
On Fri, Oct 15, 2004 at 11:54:39AM -0400, Gene Heskett wrote:
>
> The point being that who decides what is a known module?

.. the person who builds the vmlinux.
Thomas Weber
2004-10-14 18:44:11 UTC
Permalink
On Mon, Oct 11, 2004 at 04:11:22PM +0100, David Howells wrote:
>
> > Sign the whole thing. Use a signature format which doesn't suck (ASN1
> > parsing in the kernel? Hmm...). Have your build system spit out two
> > RPMs, one with full debug modules, and one without. This is not rocket
> > science.
>
> You make it sound so simple...

I'n not a kernel hacker or anything like this. But reading this thread i
might have another idea to approach the problem - if it had been
discussed before just ignore me, i haven't searched much.

How about creating the /lib/modules/ fs tree in a file, stuff all your
modules there, sign that file and mount it ro via loopback to some fixed
place like /modules?
The kernel would only have to check the signature of the whole modules
container once. From my limited understanding it wouldn't need much more
kernel code and the userland tools to maintain the container file (adding,
signing) already exist too. After all it's the sysadmin who has to
decide which modules he trusts (and puts into the container).

as i said, just an idea from a non kernel hacking simple thinking admin,
Tom
Chuck Ebbert
2004-10-15 15:37:57 UTC
Permalink
David Woodhouse <***@infradead.org> wrote:

> On Thu, 2004-10-14 at 23:36 +0200, Roman Zippel wrote:
> > No. I still don't know, why the kernel has to do this? You avoided to
> > answer this question already before.
>
> Partly to protect against accidentally-corrupted modules causing damage.

OK, so why no integrity-checking code for the kernel itself? Surely it too
could be accidentally corrupted...


--Chuck Ebbert 15-Oct-04 11:13:15
Olivier Galibert
2004-10-15 16:05:32 UTC
Permalink
On Fri, Oct 15, 2004 at 11:37:57AM -0400, Chuck Ebbert wrote:
> OK, so why no integrity-checking code for the kernel itself? Surely it too
> could be accidentally corrupted...

The kernel is CRC32-ed. Maybe it's part of the bzimage handling
though.

OG.
Bodo Eggert
2004-10-17 15:13:10 UTC
Permalink
Richard B. Johnson wrote:

> One can make a 'certified' kernel with 'certified' modules
> for some hush-hush project. Adding this kind of junk isn't
> how it's done. You just take your favorite kernel with the
> modules you require, you verify that it meets your security
> requirements, then you CRC the kernel and its modules. You
> keep the CRCs somewhere safe, available from a read-only
> source like a CD/ROM or a network file-server. You automatically
> check these CRCs occasionally using a read-only program on
> read-only source like the network or a CD/ROM. If the checks
> fail, you call the "super" and shut down the system.

If a malicious module loads, you lose instantly. You cannot relaibly ch=
eck
module integrity on this system anymore. E.g. the malicious module migh=
t
patch the module checker to check a signed module instead of the malici=
ous
one. Or the Exploit saves the old module, puts in the patched one, load=
s it
and puts the old one back in place.

Therefore you have to check on loading the module, independent from the
program loading the module. (Or you'd have to check the program loading=
the
module and provide a reliable way to prevent any race condition, which
would be much harder.)
--=20
Our last fight was my fault: My wife asked me "What's on the TV?"
I said, "Dust!"

=46ri=DF, Spammer: ***@innbusbone.com ***@zbanrtq.com
Richard B. Johnson
2004-10-18 11:27:46 UTC
Permalink
On Sun, 17 Oct 2004, Bodo Eggert wrote:

> Richard B. Johnson wrote:
>
>> One can make a 'certified' kernel with 'certified' modules
>> for some hush-hush project. Adding this kind of junk isn't
>> how it's done. You just take your favorite kernel with the
>> modules you require, you verify that it meets your security
>> requirements, then you CRC the kernel and its modules. You
>> keep the CRCs somewhere safe, available from a read-only
>> source like a CD/ROM or a network file-server. You automatically
>> check these CRCs occasionally using a read-only program on
>> read-only source like the network or a CD/ROM. If the checks
>> fail, you call the "super" and shut down the system.
>
> If a malicious module loads, you lose instantly. You cannot relaibly check
> module integrity on this system anymore. E.g. the malicious module might
> patch the module checker to check a signed module instead of the malicious
> one. Or the Exploit saves the old module, puts in the patched one, loads it
> and puts the old one back in place.
>

What malicious module? They have all been certified. That ARE NO
OTHER modules. If you don't do it this way, i.e., if you allow
anybody to load a module, then you have no security, regardless of
what's in the module, the loader, or the kernel. Any crap inside
either of these is crap. Then can all be modified to do anything
so gigibytes of "protective" software is absouye bullshit, and
a lot of memory wasted.


Cheers,
Dick Johnson
Penguin : Linux version 2.6.8 on an i686 machine (5537.79 BogoMips).
Note 96.31% of all statistics are fiction.
Bodo Eggert
2004-10-23 10:19:46 UTC
Permalink
> On Sun, 17 Oct 2004, Bodo Eggert wrote:
> > Richard B. Johnson wrote:

> >> One can make a 'certified' kernel with 'certified' modules
> >> for some hush-hush project. Adding this kind of junk isn't
> >> how it's done. You just take your favorite kernel with the
> >> modules you require, you verify that it meets your security
> >> requirements, then you CRC the kernel and its modules. You
> >> keep the CRCs somewhere safe, available from a read-only
> >> source like a CD/ROM or a network file-server.
[...]

> > If a malicious module loads, you lose instantly. You cannot relaibly
> check
> > module integrity on this system anymore. E.g. the malicious module might
> > patch the module checker to check a signed module instead of the
> malicious
> > one. Or the Exploit saves the old module, puts in the patched one, loads
> it
> > and puts the old one back in place.

> What malicious module? They have all been certified. That ARE NO
> OTHER modules.

At least until an attacker uploads a malicious module or modifies one of the
(untill then) certified modules. (He can, because your kernel doesn't check
them while loading.)

> If you don't do it this way, i.e., if you allow
> anybody to load a module, then you have no security, regardless of
> what's in the module, the loader, or the kernel. Any crap inside
> either of these is crap. Then can all be modified to do anything
> so gigibytes of "protective" software is absouye bullshit, and
> a lot of memory wasted.

If your box is r00ted, you'll want to notice this fact and do something
against it. If you don't prevent loading malicious modules, the attacker can
hide his presence and use your system right under your eyes, and you won't
notice (even while checking the checksumes).

Signing modules is (off cause) just one step, the next one(s) would be to
prevent all other modifications to the kernel memory.

--
Geschenkt: 3 Monate GMX ProMail + 3 Ausgaben der TV Movie mit DVD
++++ Jetzt anmelden und testen http://www.gmx.net/de/go/mail ++++
Loading...