lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20120510234349.4137.40185.stgit@warthog.procyon.org.uk>
Date:	Fri, 11 May 2012 00:43:49 +0100
From:	David Howells <dhowells@...hat.com>
To:	rusty@...tcorp.com.au
Cc:	kyle@...artin.ca, linux-kernel@...r.kernel.org,
	linux-security-module@...r.kernel.org, keyrings@...ux-nfs.org,
	David Howells <dhowells@...hat.com>
Subject: [PATCH 26/29] MODSIGN: Produce a filtered and canonicalised section
 list [ver #4]

Build a list of the sections in which we're interested and canonicalise the
section indices to avoid the problems of the section table being altered by ld
when the signature is linked into the binary and by strip.

The only sections in which we're actually interested are those that are marked
allocatable (which will be kept in memory) and relocation tables that are
applicable to those sections.

Canonicalisation is done by sorting the filtered list in order of section name.

Signed-off-by: David Howells <dhowells@...hat.com>
---

 kernel/module-verify.c |   80 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 80 insertions(+), 0 deletions(-)


diff --git a/kernel/module-verify.c b/kernel/module-verify.c
index 5711aeb..13c60c2 100644
--- a/kernel/module-verify.c
+++ b/kernel/module-verify.c
@@ -268,6 +268,80 @@ symcheck_error:
 }
 
 /*
+ * Canonicalise the section table index numbers.
+ *
+ * We build a list of the sections we want to add to the digest and sort it by
+ * name.  We're only interested in adding two types of section:
+ *
+ *  (1) Allocatable sections.  These should have no references to other
+ *      sections.
+ *
+ *  (2) Relocation tables for allocatable sections.  The section table entry
+ *      has a reference to the target section to which the relocations will be
+ *      applied.  The relocation entries have references to symbols in
+ *      non-allocatable sections.  Symbols can be replaced by their contents,
+ *      but do include a further reference to a section - which must be
+ *      canonicalised.
+ *
+ * We also build a map of raw section index to canonical section index.
+ */
+static int module_verify_canonicalise(struct module_verify_data *mvdata)
+{
+	const Elf_Shdr *sechdrs = mvdata->sections;
+	unsigned *canonlist, canon, loop, tmp;
+	bool changed;
+
+	canonlist = kmalloc(sizeof(unsigned) * mvdata->nsects * 2, GFP_KERNEL);
+	if (!canonlist)
+		return -ENOMEM;
+
+	mvdata->canonlist = canonlist;
+	mvdata->canonmap = canonlist + mvdata->nsects;
+	canon = 0;
+
+	for (loop = 1; loop < mvdata->nsects; loop++) {
+		const Elf_Shdr *section = mvdata->sections + loop;
+
+		if (loop == mvdata->sig_index)
+			continue;
+
+		/* We only want allocatable sections and relocation tables */
+		if (section->sh_flags & SHF_ALLOC)
+			canonlist[canon++] = loop;
+		else if ((is_elf_rel(section->sh_type) ||
+			  is_elf_rela(section->sh_type)) &&
+			 mvdata->sections[section->sh_info].sh_flags & SHF_ALLOC)
+			canonlist[canon++] = loop;
+	}
+
+	/* Sort the canonicalisation list */
+	do {
+		changed = false;
+
+		for (loop = 0; loop < canon - 1; loop++) {
+			const char *x, *y;
+
+			x = mvdata->secstrings + sechdrs[canonlist[loop + 0]].sh_name;
+			y = mvdata->secstrings + sechdrs[canonlist[loop + 1]].sh_name;
+
+			if (strcmp(x, y) > 0) {
+				tmp = canonlist[loop + 0];
+				canonlist[loop + 0] = canonlist[loop + 1];
+				canonlist[loop + 1] = tmp;
+				changed = true;
+			}
+		}
+	} while (changed);
+
+	/* What we really want is a raw-to-canon lookup table */
+	memset(mvdata->canonmap, 0xff, mvdata->nsects * sizeof(unsigned));
+	for (loop = 0; loop < canon; loop++)
+		mvdata->canonmap[mvdata->canonlist[loop]] = loop + 1;
+	mvdata->ncanon = canon;
+	return 0;
+}
+
+/*
  * Verify a module's integrity
  */
 int module_verify(const Elf_Ehdr *hdr, size_t size, bool *_gpgsig_ok)
@@ -298,7 +372,13 @@ int module_verify(const Elf_Ehdr *hdr, size_t size, bool *_gpgsig_ok)
 		goto out;
 	}
 
+	/* Produce a canonicalisation map for the sections */
+	ret = module_verify_canonicalise(&mvdata);
+	if (ret < 0)
+		goto out;
+
 	ret = 0;
+	kfree(mvdata.canonlist);
 
 out:
 	switch (ret) {

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ