From: Rusty Russell <rusty@ozlabs.org>
To: David Howells <dhowells@redhat.com>
Cc: dhowells@redhat.com, keyrings@linux-nfs.org,
linux-crypto@vger.kernel.org,
linux-security-module@vger.kernel.org,
linux-kernel@vger.kernel.org, dmitry.kasatkin@intel.com,
zohar@linux.vnet.ibm.com, arjan.van.de.ven@intel.com,
alan.cox@intel.com, Jon Masters <jcm@jonmasters.org>
Subject: Re: [PATCH 21/21] MODSIGN: Apply signature checking to modules on module load [ver #3]
Date: Mon, 12 Dec 2011 19:39:34 +1030 [thread overview]
Message-ID: <87ty56taup.fsf@rustcorp.com.au> (raw)
In-Reply-To: <26644.1323652900@redhat.com>
On Mon, 12 Dec 2011 01:21:40 +0000, David Howells <dhowells@redhat.com> wrote:
> Rusty Russell <rusty@ozlabs.org> wrote:
>
> > I think you misunderstand, I'm talking about the modinfo command, not
> > the .modinfo section.
>
> Sorry, yes. But why do you need to enhance modinfo?
I was suggesting that you want it to print the signatures, or at least
indicate their existence. Maybe check them too, but that might be a bit
too heavy for modinfo.
> > But I need to know exactly what these version-dependent mangling of
> > modules is. Is it real? Is it more than strip? Is it so hard to fix
> > that it makes sense to add 450 lines of dense kernel code to allow
> > alteration of a module after signing?
>
> The strip program (as far as I know that's the only binutil that we need worry
> about) rearranges and reorders the section, symbol and relocation tables when
> it discards stuff, and different versions of strip have done it
> differently.
OK, then you need to generate stripped modules as part of the build,
too. It's a bit of a pain, sure, but hardly a showstopper.
> However, you said it should be fairly easy to jump over the ELF parcel to get
> to the signature. How do you plan on doing that?
> I presume you would just parse sufficient of the ELF to find the
> theoretical ELF EOF and then look there for a whole string of
> signatures
You could do that. But there's an easier way. Took me longer to figure
out the damn crypto API than actually write the module part :(
Subject: module: simple signature support.
A signature contains a magic marker: it signs everything up to the
magic marker (ie. just append them):
SUM=`md5sum drivers/block/loop.ko | cut -d\ -f1`; echo "@Module signature:$SUM" >> drivers/block/loop.ko
We can have false positives, but at worst that make us report EINVAL
(bad signature) instead of ENOENT (no signature).
diff --git a/kernel/module.c b/kernel/module.c
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2374,6 +2374,98 @@ free_hdr:
return err;
}
+/* CONFIG_MODULE_SIGN implies we don't trust modules: verify signature
+ * before we interpret (almost) anything. */
+#define MOD_SIGNATURE "@Module signature:"
+
+#include <linux/ctype.h>
+#include <crypto/hash.h>
+#include <crypto/md5.h>
+
+static int from_hex(char c)
+{
+ if (isdigit(c))
+ return c - '0';
+ if (isupper(c))
+ return c - 'A' + 10;
+ return c - 'a' + 10;
+}
+
+/* A signature signs everything before it. */
+static int try_signature(void *data, void *sig, unsigned long max_sig)
+{
+ unsigned long data_len = sig - data;
+
+ sig += strlen(MOD_SIGNATURE);
+ max_sig -= strlen(MOD_SIGNATURE);
+
+ /* Dummy: accept md5 as signature. */
+ {
+ struct crypto_api_blows {
+ struct shash_desc md5;
+ char morestuff[100];
+ } m;
+ u8 digest[MD5_DIGEST_SIZE], expected[MD5_DIGEST_SIZE];
+ char *s = sig;
+ int i;
+
+ /* Not a signature? */
+ if (max_sig < MD5_DIGEST_SIZE * 2) {
+ printk("Too close to end (%lu)\n", max_sig);
+ return -ENOENT;
+ }
+
+ for (i = 0; i < MD5_DIGEST_SIZE * 2; i += 2) {
+ /* Not a signature? */
+ if (!isxdigit(s[i]) || !isxdigit(s[i+1])) {
+ printk("Not hex digit (%c)\n", s[i]);
+ return -ENOENT;
+ }
+ digest[i/2] = (from_hex(s[i])<<4) | from_hex(s[i+1]);
+ }
+
+ m.md5.tfm = crypto_alloc_shash("md5", 0, 0);
+ if (IS_ERR(m.md5.tfm))
+ return PTR_ERR(m.md5.tfm);
+ m.md5.flags = 0;
+
+ crypto_shash_digest(&m.md5, data, data_len, expected);
+ crypto_free_shash(m.md5.tfm);
+
+ if (memcmp(digest, expected, sizeof(digest)) != 0) {
+ printk("Mismatch: given %02x%02x%02x...,"
+ " expect %02x%02x%02x...\n",
+ digest[0], digest[1], digest[2],
+ expected[0], expected[1], expected[2]);
+ return -EINVAL;
+ }
+ printk("Found valid signature!\n");
+ return 0;
+ }
+}
+
+/* -ENOENT if no signature found, -EINVAL if invalid, 0 if good. */
+static int find_and_check_signatures(struct load_info *info)
+{
+ void *p = info->hdr, *end = p + info->len;
+ const size_t sigsize = strlen(MOD_SIGNATURE);
+ int err = -ENOENT;
+
+ /* Poor man's memmem. len > sigsize */
+ while ((p = memchr(p, MOD_SIGNATURE[0], end - p))) {
+ if (p + sigsize > end)
+ break;
+
+ if (memcmp(p, MOD_SIGNATURE, sigsize) == 0) {
+ err = try_signature(info->hdr, p, end - p);
+ if (!err)
+ break;
+ }
+ p++;
+ }
+ return err;
+}
+
static void free_copy(struct load_info *info)
{
vfree(info->hdr);
@@ -2819,6 +2911,11 @@ static struct module *load_module(void _
if (err)
return ERR_PTR(err);
+ /* Before we trust it, carefully check signatures. */
+ err = find_and_check_signatures(&info);
+ if (err)
+ goto free_copy;
+
/* Figure out module layout, and allocate all the memory. */
mod = layout_and_allocate(&info);
if (IS_ERR(mod)) {
next prev parent reply other threads:[~2011-12-12 9:09 UTC|newest]
Thread overview: 52+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-12-02 18:42 [RFC][PATCH 00/21] Crypto keys and module signing [ver #3] David Howells
2011-12-02 18:42 ` [PATCH 01/21] MPILIB: Export some more symbols " David Howells
2011-12-02 18:42 ` [PATCH 02/21] MPILIB: Add a missing ENOMEM check " David Howells
2011-12-02 18:43 ` [PATCH 03/21] KEYS: Permit key_serial() to be called with a const key pointer " David Howells
2011-12-02 18:43 ` [PATCH 04/21] KEYS: Move the key config into security/keys/Kconfig " David Howells
2011-12-02 18:43 ` [PATCH 05/21] KEYS: Announce key type (un)registration " David Howells
2011-12-02 18:43 ` [PATCH 06/21] KEYS: Reorganise keys Makefile " David Howells
2011-12-02 18:43 ` [PATCH 07/21] KEYS: Create a key type that can be used for general cryptographic operations " David Howells
2012-01-16 12:53 ` Mimi Zohar
2012-01-17 15:32 ` David Howells
2012-01-18 10:56 ` Kasatkin, Dmitry
2011-12-02 18:44 ` [PATCH 08/21] KEYS: Add signature verification facility " David Howells
2012-01-18 11:20 ` Kasatkin, Dmitry
2012-01-18 12:26 ` David Howells
2012-01-18 13:26 ` Kasatkin, Dmitry
2012-01-18 15:13 ` David Howells
2012-01-18 15:20 ` Kasatkin, Dmitry
2012-01-18 15:20 ` Kasatkin, Dmitry
2012-01-18 19:59 ` David Howells
2012-01-20 1:52 ` Herbert Xu
2012-01-20 1:52 ` Herbert Xu
2011-12-02 18:44 ` [PATCH 09/21] KEYS: Asymmetric public-key algorithm crypto key subtype " David Howells
2011-12-02 18:44 ` [PATCH 10/21] KEYS: DSA signature verification algorithm " David Howells
2011-12-02 18:44 ` [PATCH 11/21] KEYS: RSA " David Howells
2011-12-02 18:44 ` [PATCH 12/21] PGPLIB: PGP definitions (RFC 4880) " David Howells
2011-12-02 18:45 ` [PATCH 13/21] PGPLIB: Basic packet parser " David Howells
2011-12-02 18:45 ` [PATCH 14/21] PGPLIB: Signature " David Howells
2011-12-02 18:45 ` [PATCH 15/21] KEYS: PGP data " David Howells
2011-12-02 18:45 ` [PATCH 16/21] KEYS: PGP-based public key signature verification " David Howells
2012-01-18 11:36 ` Kasatkin, Dmitry
2012-01-18 12:49 ` David Howells
2012-01-18 13:34 ` Kasatkin, Dmitry
2012-01-18 13:34 ` Kasatkin, Dmitry
2011-12-02 18:46 ` [PATCH 17/21] KEYS: PGP format signature parser " David Howells
2011-12-02 18:46 ` [PATCH 18/21] KEYS: Provide a function to load keys from a PGP keyring blob " David Howells
2011-12-02 18:46 ` [PATCH 19/21] MODSIGN: Add indications of module ELF types " David Howells
2011-12-02 18:46 ` [PATCH 20/21] MODSIGN: Module ELF verifier " David Howells
2011-12-02 18:46 ` [PATCH 21/21] MODSIGN: Apply signature checking to modules on module load " David Howells
2011-12-09 11:18 ` Rusty Russell
2011-12-09 18:43 ` David Howells
2011-12-10 7:01 ` Rusty Russell
2011-12-10 14:08 ` David Howells
2011-12-11 4:57 ` Rusty Russell
2011-12-12 1:21 ` David Howells
2011-12-12 9:09 ` Rusty Russell [this message]
2011-12-12 16:11 ` David Howells
2011-12-13 2:15 ` Rusty Russell
2011-12-15 0:14 ` David Howells
2011-12-16 0:41 ` Rusty Russell
2011-12-10 18:37 ` Arjan van de Ven
2011-12-11 4:59 ` Rusty Russell
2012-01-08 22:02 ` [RFC][PATCH 00/21] Crypto keys and module signing " Mimi Zohar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87ty56taup.fsf@rustcorp.com.au \
--to=rusty@ozlabs.org \
--cc=alan.cox@intel.com \
--cc=arjan.van.de.ven@intel.com \
--cc=dhowells@redhat.com \
--cc=dmitry.kasatkin@intel.com \
--cc=jcm@jonmasters.org \
--cc=keyrings@linux-nfs.org \
--cc=linux-crypto@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=zohar@linux.vnet.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.