rpms/kernel/devel linux-2.6-NFSD-ctlbits.patch, NONE, 1.1 linux-2.6-NFSD-non-null-getxattr.patch, NONE, 1.1 linux-2.6-acpi-thinkpad-c2c3.patch, NONE, 1.1 linux-2.6-atkbd-dell-multimedia.patch, NONE, 1.1 linux-2.6-debug-panic-stackdump.patch, NONE, 1.1 linux-2.6-input-kill-stupid-messages.patch, NONE, 1.1 linux-2.6-missing-exports.patch, NONE, 1.1 linux-2.6-modsign-core.patch, NONE, 1.1 linux-2.6-modsign-crypto.patch, NONE, 1.1 linux-2.6-modsign-include.patch, NONE, 1.1 linux-2.6-modsign-ksign.patch, NONE, 1.1 linux-2.6-modsign-mpilib.patch, NONE, 1.1 linux-2.6-modsign-script.patch, NONE, 1.1 linux-2.6-module_version.patch, NONE, 1.1 linux-2.6-net-atm-lanai-nodev-rmmod.patch, NONE, 1.1 linux-2.6-net-sundance-ip100A.patch, NONE, 1.1 linux-2.6-ppc64-build.patch, NONE, 1.1 linux-2.6-ppc64-eeh-panic.patch, NONE, 1.1 linux-2.6-serial-tickle-nmi.patch, NONE, 1.1 linux-2.6-x86-vga-vidfail.patch, NONE, 1.1 .cvsignore, 1.249, 1.250 kernel-2.6.spec, 1.1611, 1.1612 linux-2.4.0-test11-vidfail.patch, 1.6, NONE linux-2.6.11-a! cpi-thinkpad-c2c3.patch, 1.6, NONE linux-2.6.11-atkbd-dell-multimedia.patch, 1.1, NONE linux-2.6.11-panic-stackdump.patch, 1.2, NONE linux-2.6.11-serial-tickle-nmi.patch, 1.3, NONE linux-2.6.12-input-kill-stupid-messages.patch, 1.1, NONE linux-2.6.12-missing-exports.patch, 1.2, NONE linux-2.6.12-net-atm-lanai-nodev-rmmod.patch, 1.1, NONE linux-2.6.12-net-sundance-ip100A.patch, 1.1, NONE linux-2.6.13-eeh-panic.patch, 1.1, NONE linux-2.6.13-knfsd-ctlbits.patch, 1.2, NONE linux-2.6.2-ppc64-build.patch, 1.10, NONE linux-2.6.7-modsign-core.patch, 1.10, NONE linux-2.6.7-modsign-crypto.patch, 1.5, NONE linux-2.6.7-modsign-include.patch, 1.4, NONE linux-2.6.7-modsign-ksign.patch, 1.13, NONE linux-2.6.7-modsign-mpilib.patch, 1.3, NONE linux-2.6.7-modsign-script.patch, 1.7, NONE linux-2.6.9-NFSD-non-null-getxattr.patch, 1.3, NONE linux-2.6.9-module_version.patch, 1.17, NONE
fedora-cvs-commits at redhat.com
fedora-cvs-commits at redhat.com
Sun Oct 16 22:23:51 UTC 2005
Author: davej
Update of /cvs/dist/rpms/kernel/devel
In directory cvs.devel.redhat.com:/tmp/cvs-serv439
Modified Files:
.cvsignore kernel-2.6.spec
Added Files:
linux-2.6-NFSD-ctlbits.patch
linux-2.6-NFSD-non-null-getxattr.patch
linux-2.6-acpi-thinkpad-c2c3.patch
linux-2.6-atkbd-dell-multimedia.patch
linux-2.6-debug-panic-stackdump.patch
linux-2.6-input-kill-stupid-messages.patch
linux-2.6-missing-exports.patch linux-2.6-modsign-core.patch
linux-2.6-modsign-crypto.patch linux-2.6-modsign-include.patch
linux-2.6-modsign-ksign.patch linux-2.6-modsign-mpilib.patch
linux-2.6-modsign-script.patch linux-2.6-module_version.patch
linux-2.6-net-atm-lanai-nodev-rmmod.patch
linux-2.6-net-sundance-ip100A.patch
linux-2.6-ppc64-build.patch linux-2.6-ppc64-eeh-panic.patch
linux-2.6-serial-tickle-nmi.patch
linux-2.6-x86-vga-vidfail.patch
Removed Files:
linux-2.4.0-test11-vidfail.patch
linux-2.6.11-acpi-thinkpad-c2c3.patch
linux-2.6.11-atkbd-dell-multimedia.patch
linux-2.6.11-panic-stackdump.patch
linux-2.6.11-serial-tickle-nmi.patch
linux-2.6.12-input-kill-stupid-messages.patch
linux-2.6.12-missing-exports.patch
linux-2.6.12-net-atm-lanai-nodev-rmmod.patch
linux-2.6.12-net-sundance-ip100A.patch
linux-2.6.13-eeh-panic.patch linux-2.6.13-knfsd-ctlbits.patch
linux-2.6.2-ppc64-build.patch linux-2.6.7-modsign-core.patch
linux-2.6.7-modsign-crypto.patch
linux-2.6.7-modsign-include.patch
linux-2.6.7-modsign-ksign.patch
linux-2.6.7-modsign-mpilib.patch
linux-2.6.7-modsign-script.patch
linux-2.6.9-NFSD-non-null-getxattr.patch
linux-2.6.9-module_version.patch
Log Message:
mass renaming, and spec file cleanup.
linux-2.6-NFSD-ctlbits.patch:
fs/nfsd/nfs4state.c | 3 +
fs/nfsd/nfsctl.c | 113 +++++++++++++++++++++++++++++++++++++++++--
fs/nfsd/nfssvc.c | 82 ++++++++++++++++++++-----------
include/linux/nfsd/syscall.h | 19 +++++++
4 files changed, 186 insertions(+), 31 deletions(-)
--- NEW FILE linux-2.6-NFSD-ctlbits.patch ---
--- linux-2.6.13/fs/nfsd/nfs4state.c.ctlbits 2005-09-23 11:47:27.817646000 -0400
+++ linux-2.6.13/fs/nfsd/nfs4state.c 2005-09-23 11:47:40.413006000 -0400
@@ -3319,6 +3319,9 @@ __nfs4_state_shutdown(void)
void
nfs4_state_shutdown(void)
{
+ if (!nfs4_init)
+ return;
+
nfs4_lock_state();
nfs4_release_reclaim();
__nfs4_state_shutdown();
--- linux-2.6.13/fs/nfsd/nfsctl.c.ctlbits 2005-08-28 19:41:01.000000000 -0400
+++ linux-2.6.13/fs/nfsd/nfsctl.c 2005-09-23 11:47:40.419006000 -0400
@@ -23,6 +23,7 @@
#include <linux/seq_file.h>
#include <linux/pagemap.h>
#include <linux/init.h>
+#include <linux/string.h>
#include <linux/nfs.h>
#include <linux/nfsd_idmap.h>
@@ -35,6 +36,10 @@
#include <asm/uaccess.h>
+int nfsd_port = 2049;
+unsigned int nfsd_portbits = 0;
+unsigned int nfsd_versbits = 0;
+
/*
* We have a single directory with 9 nodes in it.
*/
@@ -51,6 +56,8 @@ enum {
NFSD_Fh,
NFSD_Threads,
NFSD_Leasetime,
+ NFSD_Ports,
+ NFSD_Versions,
NFSD_RecoveryDir,
};
@@ -67,6 +74,8 @@ static ssize_t write_getfs(struct file *
static ssize_t write_filehandle(struct file *file, char *buf, size_t size);
static ssize_t write_threads(struct file *file, char *buf, size_t size);
static ssize_t write_leasetime(struct file *file, char *buf, size_t size);
+static ssize_t write_ports(struct file *file, char *buf, size_t size);
+static ssize_t write_versions(struct file *file, char *buf, size_t size);
static ssize_t write_recoverydir(struct file *file, char *buf, size_t size);
static ssize_t (*write_op[])(struct file *, char *, size_t) = {
@@ -80,6 +89,8 @@ static ssize_t (*write_op[])(struct file
[NFSD_Fh] = write_filehandle,
[NFSD_Threads] = write_threads,
[NFSD_Leasetime] = write_leasetime,
+ [NFSD_Ports] = write_ports,
+ [NFSD_Versions] = write_versions,
[NFSD_RecoveryDir] = write_recoverydir,
};
@@ -88,14 +99,12 @@ static ssize_t nfsctl_transaction_write(
ino_t ino = file->f_dentry->d_inode->i_ino;
char *data;
ssize_t rv;
-
if (ino >= sizeof(write_op)/sizeof(write_op[0]) || !write_op[ino])
return -EINVAL;
data = simple_transaction_get(file, buf, size);
if (IS_ERR(data))
return PTR_ERR(data);
-
rv = write_op[ino](file, data, size);
if (rv>0) {
simple_transaction_set(file, rv);
@@ -259,7 +268,7 @@ static ssize_t write_filehandle(struct f
* qword quoting is used, so filehandle will be \x....
*/
char *dname, *path;
- int maxsize;
+ int maxsize = 0;
char *mesg = buf;
int len;
struct auth_domain *dom;
@@ -328,6 +337,102 @@ static ssize_t write_threads(struct file
sprintf(buf, "%d\n", nfsd_nrthreads());
return strlen(buf);
}
+static ssize_t write_ports(struct file *file, char *buf, size_t size)
+{
+ /*
+ * Format:
+ * family proto proto address port
+ */
+ char *mesg = buf;
+ char *family, *udp, *tcp, *addr;
+ int len, port = 0;
+ ssize_t tlen = 0;
+
+ if (buf[size-1] != '\n')
+ return -EINVAL;
+ buf[size-1] = 0;
+
+ family = mesg;
+ len = qword_get(&mesg, family, size);
+ if (len <= 0) return -EINVAL;
+
+ tlen += len;
+ udp = family+len+1;
+ len = qword_get(&mesg, udp, size);
+ if (len <= 0) return -EINVAL;
+
+ tlen += len;
+ tcp = udp+len+1;
+ len = qword_get(&mesg, tcp, size);
+ if (len <= 0) return -EINVAL;
+
+ tlen += len;
+ addr = tcp+len+1;
+ len = qword_get(&mesg, addr, size);
+ if (len <= 0) return -EINVAL;
+
+ len = get_int(&mesg, &port);
+ if (len)
+ return len;
+
+ tlen += sizeof(port);
+ if (port)
+ nfsd_port = port;
+
+ if (strcmp(tcp, "tcp") == 0 || strcmp(tcp, "TCP") == 0)
+ NFSCTL_TCPSET(nfsd_portbits);
+ else
+ NFSCTL_TCPUNSET(nfsd_portbits);
+
+ if (strcmp(udp, "udp") == 0 || strcmp(udp, "UDP") == 0)
+ NFSCTL_UDPSET(nfsd_portbits);
+ else
+ NFSCTL_UDPUNSET(nfsd_portbits);
+
+ return tlen;
+}
+static ssize_t write_versions(struct file *file, char *buf, size_t size)
+{
+ /*
+ * Format:
+ * [-/+]vers [-/+]vers ...
+ */
+ char *mesg = buf;
+ char *vers, sign;
+ int len, num;
+ ssize_t tlen = 0;
+
+ if (buf[size-1] != '\n')
+ return -EINVAL;
+ buf[size-1] = 0;
+
+ vers = mesg;
+ len = qword_get(&mesg, vers, size);
+ if (len <= 0) return -EINVAL;
+ do {
+ sign = *vers;
+ if (sign == '+' || sign == '-')
+ num = simple_strtol((vers+1), NULL, 0);
+ else
+ num = simple_strtol(vers, NULL, 0);
+ switch(num) {
+ case 2:
+ case 3:
+ case 4:
+ if (sign != '-')
+ NFSCTL_VERSET(nfsd_versbits, num);
+ else
+ NFSCTL_VERUNSET(nfsd_versbits, num);
+ break;
+ default:
+ return -EINVAL;
+ }
+ vers += len + 1;
+ tlen += len;
+ } while ((len = qword_get(&mesg, vers, size)) > 0);
+
+ return tlen;
+}
extern time_t nfs4_leasetime(void);
@@ -393,6 +498,8 @@ static int nfsd_fill_super(struct super_
[NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR},
[NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR},
#endif
+ [NFSD_Ports] = {"ports", &transaction_ops, S_IWUSR|S_IRUSR},
+ [NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR},
/* last one */ {""}
};
return simple_fill_super(sb, 0x6e667364, nfsd_files);
--- linux-2.6.13/fs/nfsd/nfssvc.c.ctlbits 2005-08-28 19:41:01.000000000 -0400
+++ linux-2.6.13/fs/nfsd/nfssvc.c 2005-09-27 09:04:40.273630000 -0400
@@ -30,6 +30,7 @@
#include <linux/nfsd/nfsd.h>
#include <linux/nfsd/stats.h>
#include <linux/nfsd/cache.h>
+#include <linux/nfsd/syscall.h>
#include <linux/lockd/bind.h>
#include <linux/nfsacl.h>
@@ -63,6 +64,33 @@ struct nfsd_list {
};
static struct list_head nfsd_list = LIST_HEAD_INIT(nfsd_list);
+extern struct svc_version nfsd_version2, nfsd_version3, nfsd_version4;
+
+static struct svc_version * nfsd_version[] = {
+ [2] = &nfsd_version2,
+#if defined(CONFIG_NFSD_V3)
+ [3] = &nfsd_version3,
+#endif
+#if defined(CONFIG_NFSD_V4)
+ [4] = &nfsd_version4,
+#endif
+};
+
+#define NFSD_MINVERS 2
+#define NFSD_NRVERS (sizeof(nfsd_version)/sizeof(nfsd_version[0]))
+static struct svc_version *nfsd_versions[NFSD_NRVERS];
+
+struct svc_program nfsd_program = {
+ .pg_prog = NFS_PROGRAM, /* program number */
+ .pg_nvers = NFSD_NRVERS, /* nr of entries in nfsd_version */
+ .pg_vers = nfsd_versions, /* version table */
+ .pg_name = "nfsd", /* program name */
+ .pg_class = "nfsd", /* authentication class */
+ .pg_stats = &nfsd_svcstats, /* version table */
+ .pg_authenticate = &svc_set_client, /* export authentication */
+
+};
+
/*
* Maximum number of nfsd processes
*/
@@ -80,17 +108,37 @@ int
nfsd_svc(unsigned short port, int nrservs)
{
int error;
- int none_left;
+ int none_left, found_one, i;
struct list_head *victim;
lock_kernel();
- dprintk("nfsd: creating service\n");
+ dprintk("nfsd: creating service: port %d vers 0x%x proto 0x%x\n",
+ nfsd_port, nfsd_versbits, nfsd_portbits);
error = -EINVAL;
if (nrservs <= 0)
nrservs = 0;
if (nrservs > NFSD_MAXSERVS)
nrservs = NFSD_MAXSERVS;
+ /*
+ * If set, use the nfsd_ctlbits to define which
+ * versions that will be advertised
+ */
+ found_one = 0;
+ if (nfsd_versbits) {
+ for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) {
+ if (NFSCTL_VERISSET(nfsd_versbits, i)) {
+ nfsd_program.pg_vers[i] = nfsd_version[i];
+ found_one = 1;
+ } else
+ nfsd_program.pg_vers[i] = NULL;
+ }
+ }
+ if (!found_one) {
+ for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++)
+ nfsd_program.pg_vers[i] = nfsd_version[i];
+ }
+
/* Readahead param cache - will no-op if it already exists */
error = nfsd_racache_init(2*nrservs);
if (error<0)
@@ -104,11 +152,14 @@ nfsd_svc(unsigned short port, int nrserv
nfsd_serv = svc_create(&nfsd_program, NFSD_BUFSIZE);
if (nfsd_serv == NULL)
goto out;
+ if (NFSCTL_UDPISSET(nfsd_portbits))
+ port = nfsd_port;
error = svc_makesock(nfsd_serv, IPPROTO_UDP, port);
if (error < 0)
goto failure;
-
#ifdef CONFIG_NFSD_TCP
+ if (NFSCTL_TCPISSET(nfsd_portbits))
+ port = nfsd_port;
error = svc_makesock(nfsd_serv, IPPROTO_TCP, port);
if (error < 0)
goto failure;
@@ -389,28 +440,3 @@ static struct svc_stat nfsd_acl_svcstats
#else
#define nfsd_acl_program_p NULL
#endif /* defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) */
-
-extern struct svc_version nfsd_version2, nfsd_version3, nfsd_version4;
-
-static struct svc_version * nfsd_version[] = {
- [2] = &nfsd_version2,
-#if defined(CONFIG_NFSD_V3)
- [3] = &nfsd_version3,
-#endif
-#if defined(CONFIG_NFSD_V4)
- [4] = &nfsd_version4,
-#endif
-};
-
-#define NFSD_NRVERS (sizeof(nfsd_version)/sizeof(nfsd_version[0]))
-struct svc_program nfsd_program = {
- .pg_next = nfsd_acl_program_p,
- .pg_prog = NFS_PROGRAM, /* program number */
- .pg_nvers = NFSD_NRVERS, /* nr of entries in nfsd_version */
- .pg_vers = nfsd_version, /* version table */
- .pg_name = "nfsd", /* program name */
- .pg_class = "nfsd", /* authentication class */
- .pg_stats = &nfsd_svcstats, /* version table */
- .pg_authenticate = &svc_set_client, /* export authentication */
-
-};
--- linux-2.6.13/include/linux/nfsd/syscall.h.ctlbits 2005-08-28 19:41:01.000000000 -0400
+++ linux-2.6.13/include/linux/nfsd/syscall.h 2005-09-23 11:47:40.430008000 -0400
@@ -39,6 +39,22 @@
#define NFSCTL_GETFD 7 /* get an fh by path (used by mountd) */
#define NFSCTL_GETFS 8 /* get an fh by path with max FH len */
+/*
+ * Macros used to set version and protocol
+ */
+#define NFSCTL_VERSET(_cltbits, _v) ((_cltbits) |= (1 << ((_v) - 1)))
+#define NFSCTL_VERUNSET(_cltbits, _v) ((_cltbits) &= ~(1 << ((_v) - 1)))
+#define NFSCTL_VERISSET(_cltbits, _v) ((_cltbits) & (1 << ((_v) - 1)))
+
+#define NFSCTL_UDPSET(_cltbits) ((_cltbits) |= (1 << (17 - 1)))
+#define NFSCTL_UDPUNSET(_cltbits) ((_cltbits) &= ~(1 << (17 - 1)))
+#define NFSCTL_UDPISSET(_cltbits) ((_cltbits) & (1 << (17 - 1)))
+
+#define NFSCTL_TCPSET(_cltbits) ((_cltbits) |= (1 << (18 - 1)))
+#define NFSCTL_TCPUNSET(_cltbits) ((_cltbits) &= ~(1 << (18 - 1)))
+#define NFSCTL_TCPISSET(_cltbits) ((_cltbits) & (1 << (18 - 1)))
+
+
/* SVC */
struct nfsctl_svc {
unsigned short svc_port;
@@ -120,6 +136,9 @@ extern int exp_delclient(struct nfsctl_
extern int exp_export(struct nfsctl_export *nxp);
extern int exp_unexport(struct nfsctl_export *nxp);
+extern int nfsd_port;
+extern unsigned int nfsd_versbits, nfsd_portbits;
+
#endif /* __KERNEL__ */
#endif /* NFSD_SYSCALL_H */
linux-2.6-NFSD-non-null-getxattr.patch:
vfs.c | 10 ++++++++++
1 files changed, 10 insertions(+)
--- NEW FILE linux-2.6-NFSD-non-null-getxattr.patch ---
diff -urNp --exclude-from=/home/davej/.exclude linux-1102/fs/nfsd/vfs.c linux-1200/fs/nfsd/vfs.c
--- linux-1102/fs/nfsd/vfs.c
+++ linux-1200/fs/nfsd/vfs.c
@@ -461,6 +461,16 @@ _get_posix_acl(struct dentry *dentry, ch
if (error)
goto out_err;
+ error = -EOPNOTSUPP;
+ if (inode->i_op == NULL)
+ goto out_err;
+ if (inode->i_op->getxattr == NULL)
+ goto out_err;
+
+ error = security_inode_getxattr(dentry, key);
+ if (error)
+ goto out_err;
+
buflen = inode->i_op->getxattr(dentry, key, NULL, 0);
if (buflen <= 0) {
error = buflen < 0 ? buflen : -ENODATA;
linux-2.6-acpi-thinkpad-c2c3.patch:
processor_idle.c | 31 ++++++++++++++++++-------------
1 files changed, 18 insertions(+), 13 deletions(-)
--- NEW FILE linux-2.6-acpi-thinkpad-c2c3.patch ---
processor_idle.c vs Lindent resulted in something of a trainwreck
with whitespace all over the place. This diff rearranges teh
processor_power_dmi_table to look like it did before that accident,
and adds two additional BIOS's to the list as encountered by
Fedora users.
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=165590
Signed-off-by: Dave Jones <davej at redhat.com>
--- linux-2.6.13/drivers/acpi/processor_idle.c~ 2005-09-09 19:24:25.000000000 -0400
+++ linux-2.6.13/drivers/acpi/processor_idle.c 2005-09-09 19:33:18.000000000 -0400
@@ -94,22 +94,27 @@ static int set_max_cstate(struct dmi_sys
}
static struct dmi_system_id __initdata processor_power_dmi_table[] = {
- {set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,
- "IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,
- "1SET60WW")},
+ { set_max_cstate, "IBM ThinkPad R40e", {
+ DMI_MATCH(DMI_BIOS_VENDOR, "IBM"),
+ DMI_MATCH(DMI_BIOS_VERSION, "1SET60WW")},
(void *)1},
+ { set_max_cstate, "IBM ThinkPad R40e", {
+ DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
+ DMI_MATCH(DMI_BIOS_VERSION,"1SET61WW")},
+ (void*)1},
+ { set_max_cstate, "IBM ThinkPad R40e", {
+ DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
+ DMI_MATCH(DMI_BIOS_VERSION,"1SET68WW") },
+ (void*)1},
+
{set_max_cstate, "Medion 41700", {
- DMI_MATCH(DMI_BIOS_VENDOR,
- "Phoenix Technologies LTD"),
- DMI_MATCH(DMI_BIOS_VERSION,
- "R01-A1J")}, (void *)1},
+ DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
+ DMI_MATCH(DMI_BIOS_VERSION, "R01-A1J")},
+ (void *)1},
+
{set_max_cstate, "Clevo 5600D", {
- DMI_MATCH(DMI_BIOS_VENDOR,
- "Phoenix Technologies LTD"),
- DMI_MATCH(DMI_BIOS_VERSION,
- "SHE845M0.86C.0013.D.0302131307")},
+ DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
+ DMI_MATCH(DMI_BIOS_VERSION, "SHE845M0.86C.0013.D.0302131307")},
(void *)2},
{},
};
linux-2.6-atkbd-dell-multimedia.patch:
atkbd.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
--- NEW FILE linux-2.6-atkbd-dell-multimedia.patch ---
bz 126148
--- linux-2.6.11/drivers/input/keyboard/atkbd.c~ 2005-04-16 12:45:00.000000000 -0400
+++ linux-2.6.11/drivers/input/keyboard/atkbd.c 2005-04-16 12:46:28.000000000 -0400
@@ -90,13 +90,13 @@ static unsigned char atkbd_set2_keycode[
82, 83, 80, 76, 77, 72, 1, 69, 87, 78, 81, 74, 55, 73, 70, 99,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 217,100,255, 0, 97,165, 0, 0,156, 0, 0, 0, 0, 0, 0,125,
- 173,114, 0,113, 0, 0, 0,126,128, 0, 0,140, 0, 0, 0,127,
+ 217,100,255, 0, 97,165,196, 0,156, 0, 0, 0, 0, 0,197,125,
+ 173,114, 0,113, 0, 0,198,126,128, 0, 0,140, 0, 0, 0,127,
159, 0,115, 0,164, 0, 0,116,158, 0,150,166, 0, 0, 0,142,
157, 0, 0, 0, 0, 0, 0, 0,155, 0, 98, 0, 0,163, 0, 0,
226, 0, 0, 0, 0, 0, 0, 0, 0,255, 96, 0, 0, 0,143, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,107, 0,105,102, 0, 0,112,
- 110,111,108,112,106,103, 0,119, 0,118,109, 0, 99,104,119, 0,
+ 110,111,108,112,106,103,195,119, 0,118,109, 0, 99,104,119, 0,
0, 0, 0, 65, 99,
#endif
linux-2.6-debug-panic-stackdump.patch:
panic.c | 1 +
1 files changed, 1 insertion(+)
--- NEW FILE linux-2.6-debug-panic-stackdump.patch ---
--- linux-2.6.12/kernel/panic.c~ 2005-06-27 01:31:30.000000000 -0400
+++ linux-2.6.12/kernel/panic.c 2005-06-27 01:31:40.000000000 -0400
@@ -76,6 +76,7 @@ NORET_TYPE void panic(const char * fmt,
vsnprintf(buf, sizeof(buf), fmt, args);
va_end(args);
printk(KERN_EMERG "Kernel panic - not syncing: %s\n",buf);
+ dump_stack();
bust_spinlocks(0);
/*
linux-2.6-input-kill-stupid-messages.patch:
atkbd.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletion(-)
--- NEW FILE linux-2.6-input-kill-stupid-messages.patch ---
--- linux-2.6.11/drivers/input/keyboard/atkbd.c~ 2005-04-30 15:40:09.000000000 -0400
+++ linux-2.6.11/drivers/input/keyboard/atkbd.c 2005-04-30 15:40:35.000000000 -0400
@@ -328,7 +328,7 @@ static irqreturn_t atkbd_interrupt(struc
atkbd_report_key(&atkbd->dev, regs, KEY_HANJA, 3);
goto out;
case ATKBD_RET_ERR:
- printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys);
+// printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys);
goto out;
}
@@ -348,9 +348,13 @@
break;
case ATKBD_KEY_UNKNOWN:
if (data == ATKBD_RET_ACK || data == ATKBD_RET_NAK) {
+#if 0
+/* Quite a few key switchers and other tools trigger this and it confuses
+ people who can do nothing about it */
printk(KERN_WARNING "atkbd.c: Spurious %s on %s. Some program, "
"like XFree86, might be trying access hardware directly.\n",
data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys);
+#endif
} else {
printk(KERN_WARNING "atkbd.c: Unknown key %s "
"(%s set %d, code %#x on %s).\n",
linux-2.6-missing-exports.patch:
drivers/char/random.c | 1 +
lib/kobject_uevent.c | 1 +
2 files changed, 2 insertions(+)
--- NEW FILE linux-2.6-missing-exports.patch ---
WARNING:
/usr/src/build/566509-ppc64iseries/install/lib/modules/2.6.11-1.1311_FC4/kernel/drivers/input/input.ko
needs unknown symbol add_input_randomness
--- linux-2.6.11/drivers/char/random.c~ 2005-05-14 16:42:24.000000000 -0400
+++ linux-2.6.11/drivers/char/random.c 2005-05-14 16:42:46.000000000 -0400
@@ -646,6 +646,7 @@ extern void add_input_randomness(unsigne
add_timer_randomness(&input_timer_state,
(type << 4) ^ code ^ (code >> 4) ^ value);
}
+EXPORT_SYMBOL_GPL(add_input_randomness);
void add_interrupt_randomness(int irq)
{
WARNING:
/usr/src/build/566509-ppc64iseries/install/lib/modules/2.6.11-1.1311_FC4/kernel/drivers/input/input.ko
needs unknown symbol hotplug_path
--- linux-2.6.11/lib/kobject_uevent.c~ 2005-05-14 16:45:13.000000000 -0400
+++ linux-2.6.11/lib/kobject_uevent.c 2005-05-14 16:45:27.000000000 -0400
@@ -178,6 +178,7 @@ static inline int send_uevent(const char
#ifdef CONFIG_HOTPLUG
char hotplug_path[HOTPLUG_PATH_LEN] = "/sbin/hotplug";
+EXPORT_SYMBOL_GPL(hotplug_path);
u64 hotplug_seqnum;
static DEFINE_SPINLOCK(sequence_lock);
linux-2.6-modsign-core.patch:
linux-2.6.12/kernel/module-verify.c | 2
linux-900/include/linux/module.h | 3
linux-900/init/Kconfig | 16 +
linux-900/kernel/Makefile | 3
linux-900/kernel/module-verify-sig.c | 442 +++++++++++++++++++++++++++++++++++
linux-900/kernel/module-verify.c | 340 ++++++++++++++++++++++++++
linux-900/kernel/module-verify.h | 37 ++
linux-900/kernel/module.c | 19 +
8 files changed, 857 insertions(+), 5 deletions(-)
--- NEW FILE linux-2.6-modsign-core.patch ---
diff -urNp --exclude-from=/home/davej/.exclude linux-811/include/linux/module.h linux-900/include/linux/module.h
--- linux-811/include/linux/module.h
+++ linux-900/include/linux/module.h
@@ -277,6 +277,9 @@ struct module
/* Am I GPL-compatible */
int license_gplok;
+
+ /* Am I gpg signed */
+ int gpgsig_ok;
#ifdef CONFIG_MODULE_UNLOAD
/* Reference counts */
diff -urNp --exclude-from=/home/davej/.exclude linux-811/init/Kconfig linux-900/init/Kconfig
--- linux-811/init/Kconfig
+++ linux-900/init/Kconfig
@@ -434,6 +434,22 @@ config MODULE_SRCVERSION_ALL
the version). With this option, such a "srcversion" field
will be created for all modules. If unsure, say N.
+config MODULE_SIG
+ bool "Module signature verification (EXPERIMENTAL)"
+ depends on MODULES && EXPERIMENTAL
+ select CRYPTO
+ select CRYPTO_SHA1
+ select CRYPTO_SIGNATURE
+ help
+ Check modules for valid signatures upon load.
+
+config MODULE_SIG_FORCE
+ bool "Required modules to be validly signed (EXPERIMENTAL)"
+ depends on MODULE_SIG
+ help
+ Reject unsigned modules or signed modules for which we don't have a
+ key.
+
config KMOD
bool "Automatic kernel module loading"
depends on MODULES
diff -urNp --exclude-from=/home/davej/.exclude linux-811/kernel/Makefile linux-900/kernel/Makefile
--- linux-811/kernel/Makefile
+++ linux-900/kernel/Makefile
@@ -13,7 +13,8 @@ obj-$(CONFIG_FUTEX) += futex.o
obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o
obj-$(CONFIG_SMP) += cpu.o spinlock.o
obj-$(CONFIG_UID16) += uid16.o
-obj-$(CONFIG_MODULES) += module.o
+obj-$(CONFIG_MODULES) += module.o module-verify.o
+obj-$(CONFIG_MODULE_SIG) += module-verify-sig.o
obj-$(CONFIG_KALLSYMS) += kallsyms.o
obj-$(CONFIG_PM) += power/
obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
diff -urNp --exclude-from=/home/davej/.exclude linux-811/kernel/module.c linux-900/kernel/module.c
--- linux-811/kernel/module.c
+++ linux-900/kernel/module.c
@@ -38,6 +38,7 @@
#include <asm/uaccess.h>
#include <asm/semaphore.h>
#include <asm/cacheflush.h>
+#include "module-verify.h"
#if 0
#define DEBUGP printk
@@ -1413,6 +1414,7 @@ static struct module *load_module(void _
long err = 0;
void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
struct exception_table_entry *extable;
mm_segment_t old_fs;
+ int gpgsig_ok;
DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
@@ -1438,8 +1440,13 @@ 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;
@@ -1476,6 +1483,7 @@ static struct module *load_module(void _
goto free_hdr;
}
mod = (void *)sechdrs[modindex].sh_addr;
+ mod->gpgsig_ok = gpgsig_ok;
if (symindex == 0) {
printk(KERN_WARNING "%s: module has no symbols (stripped?)\n",
@@ -2078,8 +2086,13 @@ void print_modules(void)
struct module *mod;
printk("Modules linked in:");
- list_for_each_entry(mod, &modules, list)
+ list_for_each_entry(mod, &modules, list) {
printk(" %s", mod->name);
+#if CONFIG_MODULE_SIG
+ if (!mod->gpgsig_ok)
+ printk("(U)");
+#endif
+ }
printk("\n");
}
diff -urNp --exclude-from=/home/davej/.exclude linux-811/kernel/module-verify.c linux-900/kernel/module-verify.c
--- linux-811/kernel/module-verify.c
+++ linux-900/kernel/module-verify.c
@@ -0,0 +1,340 @@
+/* module-verify.c: module verifier
+ *
+ * Written by David Howells (dhowells at redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/elf.h>
+#include <linux/crypto.h>
+#include <linux/crypto/ksign.h>
+#include "module-verify.h"
+
+#if 0
+#define _debug(FMT, ...) printk(FMT, ##__VA_ARGS__)
+#else
+#define _debug(FMT, ...) do {} while (0)
+#endif
+
+static int module_verify_elf(struct module_verify_data *mvdata);
+
+/*****************************************************************************/
+/*
+ * verify a module's integrity
+ * - check the ELF is viable
+ * - check the module's signature if it has one
+ */
+int module_verify(const Elf_Ehdr *hdr, size_t size)
+{
+ struct module_verify_data mvdata;
+ int ret;
+
+ memset(&mvdata, 0, sizeof(mvdata));
+ mvdata.buffer = hdr;
+ mvdata.hdr = hdr;
+ mvdata.size = size;
+
+ ret = module_verify_elf(&mvdata);
+ if (ret < 0) {
+ if (ret == -ELIBBAD)
+ printk("Module failed ELF checks\n");
+ goto error;
+ }
+
+#ifdef CONFIG_MODULE_SIG
+ ret = module_verify_signature(&mvdata);
+#endif
+
+ error:
+ kfree(mvdata.secsizes);
+ kfree(mvdata.canonlist);
+ return ret;
+
+} /* end module_verify() */
+
+/*****************************************************************************/
+/*
+ * 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;
+ long last;
+ 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_shnum < SHN_LORESERVE);
+ 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);
+ elfcheck(hdr->e_shentsize == sizeof(Elf_Shdr));
+
+ 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_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:
+ seccheck(section->sh_entsize == sizeof(Elf_Rel));
+ goto more_rel_checks;
+
+ case SHT_RELA:
+ seccheck(section->sh_entsize == sizeof(Elf_Rela));
+ more_rel_checks:
+ seccheck(section->sh_info > 0);
+ seccheck(section->sh_info < hdr->e_shnum);
+ goto more_sec_checks;
+
+ case SHT_SYMTAB:
+ seccheck(section->sh_entsize == sizeof(Elf_Sym));
+ goto more_sec_checks;
+
+ default:
+ more_sec_checks:
+ /* 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;
+
+ last = -1;
+ 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);
+ if (section->sh_name > last)
+ last = section->sh_name;
+ }
+
+ if (last > -1) {
+ tmp = sssize - last;
+ elfcheck(memchr(mvdata->secstrings + last, 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);
+
+ last = -1;
+ for (symbol++; symbol < symstop; symbol++) {
+ symcheck(symbol->st_name < sssize);
+ if (symbol->st_name > last)
+ last = symbol->st_name;
+ symcheck(symbol->st_shndx < mvdata->nsects ||
+ symbol->st_shndx >= SHN_LORESERVE);
+ }
+
+ if (last > -1) {
+ tmp = sssize - last;
+ elfcheck(memchr(mvdata->strings + last, 0, tmp) != NULL);
+ }
+
+ /* 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",
+ (long)(section - mvdata->sections), line);
+ goto format_error;
+
+ symcheck_error:
+ printk("Verify ELF error [sym %ld] (assertion %d)\n",
+ (long)(symbol - mvdata->symbols), line);
+ goto format_error;
+
+ relcheck_error:
+ printk("Verify ELF error [sec %ld rel %ld] (assertion %d)\n",
+ (long)(section - mvdata->sections),
+ (long)(rel - rels), line);
+ goto format_error;
+
+ relacheck_error:
+ printk("Verify ELF error [sec %ld rela %ld] (assertion %d)\n",
+ (long)(section - mvdata->sections),
+ (long)(rela - relas), line);
+ goto format_error;
+
+ format_error:
+ return -ELIBBAD;
+
+} /* end module_verify_elf() */
diff -urNp --exclude-from=/home/davej/.exclude linux-811/kernel/module-verify.h linux-900/kernel/module-verify.h
--- linux-811/kernel/module-verify.h
+++ linux-900/kernel/module-verify.h
@@ -0,0 +1,37 @@
+/* module-verify.h: module verification definitions
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells at redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/types.h>
+#include <asm/module.h>
+
+struct module_verify_data {
+ struct crypto_tfm *digest; /* module signature digest */
+ const void *buffer; /* module buffer */
+ const Elf_Ehdr *hdr; /* ELF header */
+ const Elf_Shdr *sections; /* ELF section table */
+ const Elf_Sym *symbols; /* ELF symbol table */
+ const char *secstrings; /* ELF section string table */
+ const char *strings; /* ELF string table */
+ size_t *secsizes; /* section size list */
+ size_t size; /* module object size */
+ size_t nsects; /* number of sections */
+ size_t nsyms; /* number of symbols */
+ size_t nstrings; /* size of strings section */
+ size_t signed_size; /* count of bytes contributed to digest */
+ int *canonlist; /* list of canonicalised sections */
+ int *canonmap; /* section canonicalisation map */
+ int sig_index; /* module signature section index */
+ uint8_t xcsum; /* checksum of bytes contributed to digest */
+ uint8_t csum; /* checksum of bytes representing a section */
+};
+
+extern int module_verify(const Elf_Ehdr *hdr, size_t size);
+extern int module_verify_signature(struct module_verify_data *mvdata);
diff -urNp --exclude-from=/home/davej/.exclude linux-811/kernel/module-verify-sig.c linux-900/kernel/module-verify-sig.c
--- linux-811/kernel/module-verify-sig.c
+++ linux-900/kernel/module-verify-sig.c
@@ -0,0 +1,442 @@
+/* module-verify-sig.c: module signature checker
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells at redhat.com)
+ * - Derived from GregKH's RSA module signer
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/elf.h>
+#include <linux/crypto.h>
+#include <linux/crypto/ksign.h>
+#include "module-verify.h"
+
+#undef MODSIGN_DEBUG
+
+#ifdef MODSIGN_DEBUG
+#define _debug(FMT, ...) printk(FMT, ##__VA_ARGS__)
+#else
+#define _debug(FMT, ...) do {} while (0)
+#endif
+
+#ifdef MODSIGN_DEBUG
+#define count_and_csum(C, __p,__n) \
+do { \
+ int __loop; \
+ for (__loop = 0; __loop < __n; __loop++) { \
+ (C)->csum += __p[__loop]; \
+ (C)->xcsum += __p[__loop]; \
+ } \
+ (C)->signed_size += __n; \
+} while(0)
+#else
+#define count_and_csum(C, __p,__n) \
+do { \
+ (C)->signed_size += __n; \
+} while(0)
+#endif
+
+#define crypto_digest_update_data(C,PTR,N) \
+do { \
+ size_t __n = (N); \
+ uint8_t *__p = (uint8_t *)(PTR); \
+ count_and_csum((C), __p, __n); \
+ crypto_digest_update_kernel((C)->digest, __p, __n); \
+} while(0)
+
+#define crypto_digest_update_val(C,VAL) \
+do { \
+ size_t __n = sizeof(VAL); \
+ uint8_t *__p = (uint8_t *)&(VAL); \
+ count_and_csum((C), __p, __n); \
+ crypto_digest_update_kernel((C)->digest, __p, __n); \
+} while(0)
+
+static int module_verify_canonicalise(struct module_verify_data *mvdata);
+
+static int extract_elf_rela(struct module_verify_data *mvdata,
+ int secix,
+ const Elf_Rela *relatab, size_t nrels,
+ const char *sh_name);
+
+static int extract_elf_rel(struct module_verify_data *mvdata,
+ int secix,
+ const Elf_Rel *reltab, size_t nrels,
+ const char *sh_name);
+
+static int signedonly;
+
+/*****************************************************************************/
+/*
+ * verify a module's signature
+ */
+int module_verify_signature(struct module_verify_data *mvdata)
+{
+ const Elf_Shdr *sechdrs = mvdata->sections;
+ const char *secstrings = mvdata->secstrings;
+ const char *sig;
+ unsigned sig_size;
+ int i, ret;
+
+ for (i = 1; i < mvdata->nsects; i++) {
+ switch (sechdrs[i].sh_type) {
+ case SHT_PROGBITS:
+ if (strcmp(mvdata->secstrings + sechdrs[i].sh_name,
+ ".module_sig") == 0) {
+ mvdata->sig_index = i;
+ }
+ break;
+ }
+ }
+
+ if (mvdata->sig_index <= 0)
+ goto no_signature;
+
+ sig = mvdata->buffer + sechdrs[mvdata->sig_index].sh_offset;
+ sig_size = sechdrs[mvdata->sig_index].sh_size;
+
+ _debug("sig in section %d (size %d)\n",
+ mvdata->sig_index, sig_size);
+
+ /* produce a canonicalisation map for the sections */
+ ret = module_verify_canonicalise(mvdata);
+ if (ret < 0)
+ return ret;
+
+ /* grab an SHA1 transformation context
+ * - !!! if this tries to load the sha1.ko module, we will deadlock!!!
+ */
+ mvdata->digest = crypto_alloc_tfm2("sha1", 0, 1);
+ if (!mvdata->digest) {
+ printk("Couldn't load module - SHA1 transform unavailable\n");
+ return -EPERM;
+ }
+
+ crypto_digest_init(mvdata->digest);
+
+#ifdef MODSIGN_DEBUG
+ mvdata->xcsum = 0;
+#endif
+
+ /* load data from each relevant section into the digest */
+ for (i = 1; i < mvdata->nsects; i++) {
+ unsigned long sh_type = sechdrs[i].sh_type;
+ unsigned long sh_info = sechdrs[i].sh_info;
+ unsigned long sh_size = sechdrs[i].sh_size;
+ unsigned long sh_flags = sechdrs[i].sh_flags;
+ const char *sh_name = secstrings + sechdrs[i].sh_name;
+ const void *data = mvdata->buffer + sechdrs[i].sh_offset;
+
+ if (i == mvdata->sig_index)
+ continue;
+
+#ifdef MODSIGN_DEBUG
+ mvdata->csum = 0;
+#endif
+
+ /* it would be nice to include relocation sections, but the act
+ * of adding a signature to the module seems changes their
+ * contents, because the symtab gets changed when sections are
+ * added or removed */
+ if (sh_type == SHT_REL || sh_type == SHT_RELA) {
+ if (mvdata->canonlist[sh_info]) {
+ uint32_t xsh_info = mvdata->canonmap[sh_info];
+
+ crypto_digest_update_data(mvdata, sh_name, strlen(sh_name));
+ crypto_digest_update_val(mvdata, sechdrs[i].sh_type);
+ crypto_digest_update_val(mvdata, sechdrs[i].sh_flags);
+ crypto_digest_update_val(mvdata, sechdrs[i].sh_size);
+ crypto_digest_update_val(mvdata, sechdrs[i].sh_addralign);
+ crypto_digest_update_val(mvdata, xsh_info);
+
+ if (sh_type == SHT_RELA)
+ ret = extract_elf_rela(
+ mvdata, i,
+ data,
+ sh_size / sizeof(Elf_Rela),
+ sh_name);
+ else
+ ret = extract_elf_rel(
+ mvdata, i,
+ data,
+ sh_size / sizeof(Elf_Rel),
+ sh_name);
+
+ if (ret < 0)
+ goto format_error;
+ }
+
+ continue;
+ }
+
+ /* include allocatable loadable sections */
+ if (sh_type != SHT_NOBITS && sh_flags & SHF_ALLOC)
+ goto include_section;
+
+ continue;
+
+ include_section:
+ crypto_digest_update_data(mvdata, sh_name, strlen(sh_name));
+ crypto_digest_update_val(mvdata, sechdrs[i].sh_type);
+ crypto_digest_update_val(mvdata, sechdrs[i].sh_flags);
+ crypto_digest_update_val(mvdata, sechdrs[i].sh_size);
+ crypto_digest_update_val(mvdata, sechdrs[i].sh_addralign);
+ crypto_digest_update_data(mvdata, data, sh_size);
+
+ _debug("%08zx %02x digested the %s section, size %ld\n",
+ mvdata->signed_size, mvdata->csum, sh_name, sh_size);
+
+ mvdata->canonlist[i] = 1;
+ }
+
+ _debug("Contributed %zu bytes to the digest (csum 0x%02x)\n",
+ mvdata->signed_size, mvdata->xcsum);
+
+ /* do the actual signature verification */
+ i = ksign_verify_signature(sig, sig_size, mvdata->digest);
+
+ _debug("verify-sig : %d\n", i);
+
+ if (i == 0)
+ i = 1;
+ return i;
+
+ format_error:
+ crypto_free_tfm(mvdata->digest);
+ return -ELIBBAD;
+
+ /* deal with the case of an unsigned module */
+ no_signature:
+ if (!signedonly)
+ return 0;
+ printk("An attempt to load unsigned module was rejected\n");
+ return -EPERM;
+
+} /* end module_verify_signature() */
+
+/*****************************************************************************/
+/*
+ * canonicalise the section table index numbers
+ */
+static int module_verify_canonicalise(struct module_verify_data *mvdata)
+{
+ int canon, loop, changed, tmp;
+
+ /* produce a list of index numbers of sections that contribute
+ * to the kernel's module image
+ */
+ mvdata->canonlist =
+ kmalloc(sizeof(int) * mvdata->nsects * 2, GFP_KERNEL);
+ if (!mvdata->canonlist)
+ return -ENOMEM;
+
+ mvdata->canonmap = mvdata->canonlist + mvdata->nsects;
+ canon = 0;
+
+ for (loop = 1; loop < mvdata->nsects; loop++) {
+ const Elf_Shdr *section = mvdata->sections + loop;
+
+ if (loop != mvdata->sig_index) {
+ /* we only need to canonicalise allocatable sections */
+ if (section->sh_flags & SHF_ALLOC)
+ mvdata->canonlist[canon++] = loop;
+ }
+ }
+
+ /* canonicalise the index numbers of the contributing section */
+ do {
+ changed = 0;
+
+ for (loop = 0; loop < canon - 1; loop++) {
+ const char *x, *y;
+
+ x = mvdata->secstrings +
+ mvdata->sections[mvdata->canonlist[loop + 0]].sh_name;
+ y = mvdata->secstrings +
+ mvdata->sections[mvdata->canonlist[loop + 1]].sh_name;
+
+ if (strcmp(x, y) > 0) {
+ tmp = mvdata->canonlist[loop + 0];
+ mvdata->canonlist[loop + 0] =
+ mvdata->canonlist[loop + 1];
+ mvdata->canonlist[loop + 1] = tmp;
+ changed = 1;
+ }
+ }
+
+ } while(changed);
+
+ for (loop = 0; loop < canon; loop++)
+ mvdata->canonmap[mvdata->canonlist[loop]] = loop + 1;
+
+ return 0;
+
+} /* end module_verify_canonicalise() */
+
+/*****************************************************************************/
+/*
+ * extract a RELA table
+ * - need to canonicalise the entries in case section addition/removal has
+ * rearranged the symbol table and the section table
+ */
+static int extract_elf_rela(struct module_verify_data *mvdata,
+ int secix,
+ const Elf_Rela *relatab, size_t nrels,
+ const char *sh_name)
+{
+ struct {
+#if defined(MODULES_ARE_ELF32)
+ uint32_t r_offset;
+ uint32_t r_addend;
+ uint32_t st_value;
+ uint32_t st_size;
+ uint16_t st_shndx;
+ uint8_t r_type;
+ uint8_t st_info;
+ uint8_t st_other;
+#elif defined(MODULES_ARE_ELF64)
+ uint64_t r_offset;
+ uint64_t r_addend;
+ uint64_t st_value;
+ uint64_t st_size;
+ uint32_t r_type;
+ uint16_t st_shndx;
+ uint8_t st_info;
+ uint8_t st_other;
+#else
+#error unsupported module type
+#endif
+ } __attribute__((packed)) relocation;
+
+ const Elf_Rela *reloc;
+ const Elf_Sym *symbol;
+ size_t loop;
+
+ /* contribute the relevant bits from a join of { RELA, SYMBOL, SECTION } */
+ for (loop = 0; loop < nrels; loop++) {
+ int st_shndx;
+
+ reloc = &relatab[loop];
+
+ /* decode the relocation */
+ relocation.r_offset = reloc->r_offset;
+ relocation.r_addend = reloc->r_addend;
+ relocation.r_type = ELF_R_TYPE(reloc->r_info);
+
+ /* decode the symbol referenced by the relocation */
+ symbol = &mvdata->symbols[ELF_R_SYM(reloc->r_info)];
+ relocation.st_info = symbol->st_info;
+ relocation.st_other = symbol->st_other;
+ relocation.st_value = symbol->st_value;
+ relocation.st_size = symbol->st_size;
+ relocation.st_shndx = symbol->st_shndx;
+ st_shndx = symbol->st_shndx;
+
+ /* canonicalise the section used by the symbol */
+ if (st_shndx > SHN_UNDEF && st_shndx < mvdata->nsects)
+ relocation.st_shndx = mvdata->canonmap[st_shndx];
+
+ crypto_digest_update_val(mvdata, relocation);
+
+ /* undefined symbols must be named if referenced */
+ if (st_shndx == SHN_UNDEF) {
+ const char *name = mvdata->strings + symbol->st_name;
+ crypto_digest_update_data(mvdata,
+ name, strlen(name) + 1);
+ }
+ }
+
+ _debug("%08zx %02x digested the %s section, nrels %zu\n",
+ mvdata->signed_size, mvdata->csum, sh_name, nrels);
+
+ return 0;
+} /* end extract_elf_rela() */
+
+/*****************************************************************************/
+/*
+ *
+ */
+static int extract_elf_rel(struct module_verify_data *mvdata,
+ int secix,
+ const Elf_Rel *reltab, size_t nrels,
+ const char *sh_name)
+{
+ struct {
+#if defined(MODULES_ARE_ELF32)
+ uint32_t r_offset;
+ uint32_t st_value;
+ uint32_t st_size;
+ uint16_t st_shndx;
+ uint8_t r_type;
+ uint8_t st_info;
+ uint8_t st_other;
+#elif defined(MODULES_ARE_ELF64)
+ uint64_t r_offset;
+ uint64_t st_value;
+ uint64_t st_size;
+ uint32_t r_type;
+ uint16_t st_shndx;
+ uint8_t st_info;
+ uint8_t st_other;
+#else
+#error unsupported module type
+#endif
+ } __attribute__((packed)) relocation;
+
+ const Elf_Rel *reloc;
+ const Elf_Sym *symbol;
+ size_t loop;
+
+ /* contribute the relevant bits from a join of { RELA, SYMBOL, SECTION } */
+ for (loop = 0; loop < nrels; loop++) {
+ int st_shndx;
+
+ reloc = &reltab[loop];
+
+ /* decode the relocation */
+ relocation.r_offset = reloc->r_offset;
+ relocation.r_type = ELF_R_TYPE(reloc->r_info);
+
+ /* decode the symbol referenced by the relocation */
+ symbol = &mvdata->symbols[ELF_R_SYM(reloc->r_info)];
+ relocation.st_info = symbol->st_info;
+ relocation.st_other = symbol->st_other;
+ relocation.st_value = symbol->st_value;
+ relocation.st_size = symbol->st_size;
+ relocation.st_shndx = symbol->st_shndx;
+ st_shndx = symbol->st_shndx;
+
+ /* canonicalise the section used by the symbol */
+ if (st_shndx > SHN_UNDEF && st_shndx < mvdata->nsects)
+ relocation.st_shndx = mvdata->canonmap[st_shndx];
+
+ crypto_digest_update_val(mvdata, relocation);
+
+ /* undefined symbols must be named if referenced */
+ if (st_shndx == SHN_UNDEF) {
+ const char *name = mvdata->strings + symbol->st_name;
+ crypto_digest_update_data(mvdata,
+ name, strlen(name) + 1);
+ }
+ }
+
+ _debug("%08zx %02x digested the %s section, nrels %zu\n",
+ mvdata->signed_size, mvdata->csum, sh_name, nrels);
+
+ return 0;
+} /* end extract_elf_rel() */
+
+static int __init sign_setup(char *str)
+{
+ signedonly = 1;
+ return 0;
+}
+__setup("enforcemodulesig", sign_setup);
--- linux-2.6.12/kernel/module-verify.c.~1~ 2005-08-07 17:39:38.000000000 -0700
+++ linux-2.6.12/kernel/module-verify.c 2005-08-10 00:48:43.000000000 -0700
@@ -107,7 +107,7 @@ do { if (unlikely(!(X))) { line = __LINE
elfcheck(hdr->e_shentsize == sizeof(Elf_Shdr));
tmp = (size_t) hdr->e_shentsize * (size_t) hdr->e_shnum;
- elfcheck(tmp < size - hdr->e_shoff);
+ 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);
linux-2.6-modsign-crypto.patch:
crypto/Kconfig | 19 +++++++++++++++++++
crypto/Makefile | 3 +++
crypto/api.c | 16 ++++++++++++++--
include/linux/crypto.h | 4 ++++
4 files changed, 40 insertions(+), 2 deletions(-)
--- NEW FILE linux-2.6-modsign-crypto.patch ---
diff -urNp --exclude-from=/home/davej/.exclude linux-900/crypto/api.c linux-901/crypto/api.c
--- linux-900/crypto/api.c
+++ linux-901/crypto/api.c
@@ -117,12 +117,19 @@ static void crypto_exit_ops(struct crypt
}
}
-struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags)
+struct crypto_tfm *crypto_alloc_tfm2(const char *name, u32 flags,
+ int nomodload)
{
struct crypto_tfm *tfm = NULL;
struct crypto_alg *alg;
unsigned int tfm_size;
- alg = crypto_alg_mod_lookup(name);
+ if (!nomodload) {
+ alg = crypto_alg_mod_lookup(name);
+ }
+ else {
+ alg = crypto_alg_lookup(name);
+ }
+
if (alg == NULL)
goto out;
@@ -153,6 +160,11 @@ out:
return tfm;
}
+struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags)
+{
+ return crypto_alloc_tfm2(name, flags, 0);
+}
+
void crypto_free_tfm(struct crypto_tfm *tfm)
{
struct crypto_alg *alg = tfm->__crt_alg;
diff -urNp --exclude-from=/home/davej/.exclude linux-900/crypto/Kconfig linux-901/crypto/Kconfig
--- linux-900/crypto/Kconfig
+++ linux-901/crypto/Kconfig
@@ -287,6 +287,25 @@ config CRYPTO_TEST
help
Quick & dirty crypto test module.
+config CRYPTO_SIGNATURE
+ bool "In-kernel signature checker (EXPERIMENTAL)"
+ depends on CRYPTO
+ help
+ Signature checker (used for module sig checking).
+
+config CRYPTO_SIGNATURE_DSA
+ bool "Handle DSA signatures (EXPERIMENTAL)"
+ depends on CRYPTO_SIGNATURE
+ select CRYPTO_MPILIB
+ help
+ DSA Signature checker.
+
+config CRYPTO_MPILIB
+ bool "Multiprecision maths library (EXPERIMENTAL)"
+ depends on CRYPTO
+ help
+ Multiprecision maths library from GnuPG
+
source "drivers/crypto/Kconfig"
endmenu
diff -urNp --exclude-from=/home/davej/.exclude linux-900/crypto/Makefile linux-901/crypto/Makefile
--- linux-900/crypto/Makefile
+++ linux-901/crypto/Makefile
@@ -32,3 +32,6 @@ obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += mich
obj-$(CONFIG_CRYPTO_CRC32C) += crc32c.o
obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o
+
+obj-$(CONFIG_CRYPTO_SIGNATURE) += signature/
+obj-$(CONFIG_CRYPTO_MPILIB) += mpi/
diff -urNp --exclude-from=/home/davej/.exclude linux-900/include/linux/crypto.h linux-901/include/linux/crypto.h
--- linux-900/include/linux/crypto.h
+++ linux-901/include/linux/crypto.h
@@ -213,10 +213,14 @@ struct crypto_tfm {
* will then attempt to load a module of the same name or alias. A refcount
* is grabbed on the algorithm which is then associated with the new transform.
*
+ * crypto_alloc_tfm2() is similar, but allows module loading to be suppressed.
+ *
* crypto_free_tfm() frees up the transform and any associated resources,
* then drops the refcount on the associated algorithm.
*/
struct crypto_tfm *crypto_alloc_tfm(const char *alg_name, u32 tfm_flags);
+struct crypto_tfm *crypto_alloc_tfm2(const char *alg_name, u32 tfm_flags,
+ int nomodload);
void crypto_free_tfm(struct crypto_tfm *tfm);
/*
linux-2.6-modsign-include.patch:
linux-2.6.13/include/asm-mips/module.h | 13 ++++++++++---
linux-2.6.13/include/asm-powerpc/module.h | 10 ++++++++++
linux-905/include/asm-alpha/module.h | 3 +++
linux-905/include/asm-arm/module.h | 5 +++++
linux-905/include/asm-cris/module.h | 5 +++++
linux-905/include/asm-h8300/module.h | 5 +++++
linux-905/include/asm-i386/module.h | 5 +++++
linux-905/include/asm-ia64/module.h | 5 +++++
linux-905/include/asm-m32r/module.h | 5 +++++
linux-905/include/asm-m68k/module.h | 5 +++++
linux-905/include/asm-parisc/module.h | 8 ++++++++
linux-905/include/asm-s390/module.h | 3 +++
linux-905/include/asm-sh/module.h | 5 +++++
linux-905/include/asm-sparc/module.h | 5 +++++
linux-905/include/asm-sparc64/module.h | 5 +++++
linux-905/include/asm-um/module-i386.h | 4 ++++
linux-905/include/asm-v850/module.h | 5 +++++
linux-905/include/asm-x86_64/module.h | 5 +++++
18 files changed, 98 insertions(+), 3 deletions(-)
--- NEW FILE linux-2.6-modsign-include.patch ---
diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-alpha/module.h linux-905/include/asm-alpha/module.h
--- linux-904/include/asm-alpha/module.h
+++ linux-905/include/asm-alpha/module.h
@@ -6,6 +6,7 @@ struct mod_arch_specific
unsigned int gotsecindex;
};
+#define MODULES_ARE_ELF64
#define Elf_Sym Elf64_Sym
#define Elf_Shdr Elf64_Shdr
#define Elf_Ehdr Elf64_Ehdr
@@ -13,6 +14,8 @@ struct mod_arch_specific
#define Elf_Dyn Elf64_Dyn
#define Elf_Rel Elf64_Rel
#define Elf_Rela Elf64_Rela
+#define ELF_R_TYPE(X) ELF64_R_TYPE(X)
+#define ELF_R_SYM(X) ELF64_R_SYM(X)
#define ARCH_SHF_SMALL SHF_ALPHA_GPREL
diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-arm/module.h linux-905/include/asm-arm/module.h
--- linux-904/include/asm-arm/module.h
+++ linux-905/include/asm-arm/module.h
@@ -6,9 +6,14 @@ struct mod_arch_specific
int foo;
};
+#define MODULES_ARE_ELF32
#define Elf_Shdr Elf32_Shdr
#define Elf_Sym Elf32_Sym
#define Elf_Ehdr Elf32_Ehdr
+#define Elf_Rel Elf32_Rel
+#define Elf_Rela Elf32_Rela
+#define ELF_R_TYPE(X) ELF32_R_TYPE(X)
+#define ELF_R_SYM(X) ELF32_R_SYM(X)
/*
* Include the ARM architecture version.
diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-cris/module.h linux-905/include/asm-cris/module.h
--- linux-904/include/asm-cris/module.h
+++ linux-905/include/asm-cris/module.h
@@ -3,7 +3,12 @@
/* cris is simple */
struct mod_arch_specific { };
+#define MODULES_ARE_ELF32
#define Elf_Shdr Elf32_Shdr
#define Elf_Sym Elf32_Sym
#define Elf_Ehdr Elf32_Ehdr
+#define Elf_Rel Elf32_Rel
+#define Elf_Rela Elf32_Rela
+#define ELF_R_TYPE(X) ELF32_R_TYPE(X)
+#define ELF_R_SYM(X) ELF32_R_SYM(X)
#endif /* _ASM_CRIS_MODULE_H */
diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-h8300/module.h linux-905/include/asm-h8300/module.h
--- linux-904/include/asm-h8300/module.h
+++ linux-905/include/asm-h8300/module.h
@@ -4,9 +4,14 @@
* This file contains the H8/300 architecture specific module code.
*/
struct mod_arch_specific { };
+#define MODULES_ARE_ELF32
#define Elf_Shdr Elf32_Shdr
#define Elf_Sym Elf32_Sym
#define Elf_Ehdr Elf32_Ehdr
+#define Elf_Rel Elf32_Rel
+#define Elf_Rela Elf32_Rela
+#define ELF_R_TYPE(X) ELF32_R_TYPE(X)
+#define ELF_R_SYM(X) ELF32_R_SYM(X)
#define MODULE_SYMBOL_PREFIX "_"
diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-i386/module.h linux-905/include/asm-i386/module.h
--- linux-904/include/asm-i386/module.h
+++ linux-905/include/asm-i386/module.h
@@ -6,9 +6,14 @@ struct mod_arch_specific
{
};
+#define MODULES_ARE_ELF32
#define Elf_Shdr Elf32_Shdr
#define Elf_Sym Elf32_Sym
#define Elf_Ehdr Elf32_Ehdr
+#define Elf_Rel Elf32_Rel
+#define Elf_Rela Elf32_Rela
+#define ELF_R_TYPE(X) ELF32_R_TYPE(X)
+#define ELF_R_SYM(X) ELF32_R_SYM(X)
#ifdef CONFIG_M386
#define MODULE_PROC_FAMILY "386 "
diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-ia64/module.h linux-905/include/asm-ia64/module.h
--- linux-904/include/asm-ia64/module.h
+++ linux-905/include/asm-ia64/module.h
@@ -23,9 +23,14 @@ struct mod_arch_specific {
unsigned int next_got_entry; /* index of next available got entry */
};
+#define MODULES_ARE_ELF64
#define Elf_Shdr Elf64_Shdr
#define Elf_Sym Elf64_Sym
#define Elf_Ehdr Elf64_Ehdr
+#define Elf_Rel Elf64_Rel
+#define Elf_Rela Elf64_Rela
+#define ELF_R_TYPE(X) ELF64_R_TYPE(X)
+#define ELF_R_SYM(X) ELF64_R_SYM(X)
#define MODULE_PROC_FAMILY "ia64"
#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY
diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-m32r/module.h linux-905/include/asm-m32r/module.h
--- linux-904/include/asm-m32r/module.h
+++ linux-905/include/asm-m32r/module.h
@@ -5,9 +5,14 @@
struct mod_arch_specific { };
+#define MODULES_ARE_ELF32
#define Elf_Shdr Elf32_Shdr
#define Elf_Sym Elf32_Sym
#define Elf_Ehdr Elf32_Ehdr
+#define Elf_Rel Elf32_Rel
+#define Elf_Rela Elf32_Rela
+#define ELF_R_TYPE(X) ELF32_R_TYPE(X)
+#define ELF_R_SYM(X) ELF32_R_SYM(X)
#endif /* _ASM_M32R_MODULE_H */
diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-m68k/module.h linux-905/include/asm-m68k/module.h
--- linux-904/include/asm-m68k/module.h
+++ linux-905/include/asm-m68k/module.h
@@ -1,7 +1,12 @@
#ifndef _ASM_M68K_MODULE_H
#define _ASM_M68K_MODULE_H
struct mod_arch_specific { };
+#define MODULES_ARE_ELF32
#define Elf_Shdr Elf32_Shdr
#define Elf_Sym Elf32_Sym
#define Elf_Ehdr Elf32_Ehdr
+#define Elf_Rel Elf32_Rel
+#define Elf_Rela Elf32_Rela
+#define ELF_R_TYPE(X) ELF32_R_TYPE(X)
+#define ELF_R_SYM(X) ELF32_R_SYM(X)
#endif /* _ASM_M68K_MODULE_H */
--- linux-2.6.13/include/asm-mips/module.h~ 2005-09-05 17:18:22.000000000 -0400
+++ linux-2.6.13/include/asm-mips/module.h 2005-09-05 17:20:33.000000000 -0400
@@ -26,19 +26,26 @@ typedef struct
} Elf64_Mips_Rela;
#ifdef CONFIG_32BIT
-
+#define MODULES_ARE_ELF32
#define Elf_Shdr Elf32_Shdr
#define Elf_Sym Elf32_Sym
#define Elf_Ehdr Elf32_Ehdr
+#define Elf_Rel Elf32_Rel
+#define Elf_Rela Elf32_Rela
+#define ELF_R_TYPE(X) ELF32_R_TYPE(X)
+#define ELF_R_SYM(X) ELF32_R_SYM(X)
#endif
#ifdef CONFIG_64BIT
-
+#define MODULES_ARE_ELF64
#define Elf_Shdr Elf64_Shdr
#define Elf_Sym Elf64_Sym
#define Elf_Ehdr Elf64_Ehdr
-
+#define Elf_Rel Elf64_Rel
+#define Elf_Rela Elf64_Rela
+#define ELF_R_TYPE(X) ELF64_R_TYPE(X)
+#define ELF_R_SYM(X) ELF64_R_SYM(X)
#endif
#ifdef CONFIG_MODULES
diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-parisc/module.h linux-905/include/asm-parisc/module.h
--- linux-904/include/asm-parisc/module.h
+++ linux-905/include/asm-parisc/module.h
@@ -4,17 +4,25 @@
* This file contains the parisc architecture specific module code.
*/
#ifdef __LP64__
+#define MODULES_ARE_ELF64
#define Elf_Shdr Elf64_Shdr
#define Elf_Sym Elf64_Sym
#define Elf_Ehdr Elf64_Ehdr
#define Elf_Addr Elf64_Addr
+#define Elf_Rel Elf64_Rel
#define Elf_Rela Elf64_Rela
+#define ELF_R_TYPE(X) ELF64_R_TYPE(X)
+#define ELF_R_SYM(X) ELF64_R_SYM(X)
#else
+#define MODULES_ARE_ELF32
#define Elf_Shdr Elf32_Shdr
#define Elf_Sym Elf32_Sym
#define Elf_Ehdr Elf32_Ehdr
#define Elf_Addr Elf32_Addr
+#define Elf_Rel Elf32_Rel
#define Elf_Rela Elf32_Rela
+#define ELF_R_TYPE(X) ELF32_R_TYPE(X)
+#define ELF_R_SYM(X) ELF32_R_SYM(X)
#endif
struct unwind_table;
--- linux-2.6.13/include/asm-powerpc/module.h~ 2005-09-08 01:05:31.000000000 -0400
+++ linux-2.6.13/include/asm-powerpc/module.h 2005-09-08 01:11:30.000000000 -0400
@@ -53,16 +53,26 @@ extern struct bug_entry *module_find_bug
*/
#ifdef __powerpc64__
+# define MODULES_ARE_ELF64
# define Elf_Shdr Elf64_Shdr
# define Elf_Sym Elf64_Sym
# define Elf_Ehdr Elf64_Ehdr
+# define Elf_Rel Elf64_Rel
+# define Elf_Rela Elf64_Rela
+# define ELF_R_TYPE(X) ELF64_R_TYPE(X)
+# define ELF_R_SYM(X) ELF64_R_SYM(X)
# ifdef MODULE
asm(".section .stubs,\"ax\", at nobits; .align 3; .previous");
# endif
#else
+# define MODULES_ARE_ELF32
# define Elf_Shdr Elf32_Shdr
# define Elf_Sym Elf32_Sym
# define Elf_Ehdr Elf32_Ehdr
+# define Elf_Rel Elf32_Rel
+# define Elf_Rela Elf32_Rela
+# define ELF_R_TYPE(X) ELF32_R_TYPE(X)
+# define ELF_R_SYM(X) ELF32_R_SYM(X)
# ifdef MODULE
asm(".section .plt,\"ax\", at nobits; .align 3; .previous");
asm(".section .init.plt,\"ax\", at nobits; .align 3; .previous");
diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-s390/module.h linux-905/include/asm-s390/module.h
--- linux-904/include/asm-s390/module.h
+++ linux-905/include/asm-s390/module.h
@@ -29,14 +29,17 @@ struct mod_arch_specific
};
#ifdef __s390x__
+#define MODULES_ARE_ELF64
#define ElfW(x) Elf64_ ## x
#define ELFW(x) ELF64_ ## x
#else
+#define MODULES_ARE_ELF32
#define ElfW(x) Elf32_ ## x
#define ELFW(x) ELF32_ ## x
#endif
#define Elf_Addr ElfW(Addr)
+#define Elf_Rel ElfW(Rel)
#define Elf_Rela ElfW(Rela)
#define Elf_Shdr ElfW(Shdr)
#define Elf_Sym ElfW(Sym)
diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-sh/module.h linux-905/include/asm-sh/module.h
--- linux-904/include/asm-sh/module.h
+++ linux-905/include/asm-sh/module.h
@@ -9,9 +9,14 @@ struct mod_arch_specific {
/* Nothing to see here .. */
};
+#define MODULES_ARE_ELF32
#define Elf_Shdr Elf32_Shdr
#define Elf_Sym Elf32_Sym
#define Elf_Ehdr Elf32_Ehdr
+#define Elf_Rel Elf32_Rel
+#define Elf_Rela Elf32_Rela
+#define ELF_R_TYPE(X) ELF32_R_TYPE(X)
+#define ELF_R_SYM(X) ELF32_R_SYM(X)
#ifdef CONFIG_CPU_LITTLE_ENDIAN
# ifdef CONFIG_CPU_SH2
diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-sparc/module.h linux-905/include/asm-sparc/module.h
--- linux-904/include/asm-sparc/module.h
+++ linux-905/include/asm-sparc/module.h
@@ -1,7 +1,12 @@
#ifndef _ASM_SPARC_MODULE_H
#define _ASM_SPARC_MODULE_H
struct mod_arch_specific { };
+#define MODULES_ARE_ELF32
#define Elf_Shdr Elf32_Shdr
#define Elf_Sym Elf32_Sym
#define Elf_Ehdr Elf32_Ehdr
+#define Elf_Rel Elf32_Rel
+#define Elf_Rela Elf32_Rela
+#define ELF_R_TYPE(X) ELF32_R_TYPE(X)
+#define ELF_R_SYM(X) ELF32_R_SYM(X)
#endif /* _ASM_SPARC_MODULE_H */
diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-sparc64/module.h linux-905/include/asm-sparc64/module.h
--- linux-904/include/asm-sparc64/module.h
+++ linux-905/include/asm-sparc64/module.h
@@ -1,7 +1,12 @@
#ifndef _ASM_SPARC64_MODULE_H
#define _ASM_SPARC64_MODULE_H
struct mod_arch_specific { };
+#define MODULES_ARE_ELF64
#define Elf_Shdr Elf64_Shdr
#define Elf_Sym Elf64_Sym
#define Elf_Ehdr Elf64_Ehdr
+#define Elf_Rel Elf64_Rel
+#define Elf_Rela Elf64_Rela
+#define ELF_R_TYPE(X) ELF64_R_TYPE(X)
+#define ELF_R_SYM(X) ELF64_R_SYM(X)
#endif /* _ASM_SPARC64_MODULE_H */
diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-um/module-i386.h linux-905/include/asm-um/module-i386.h
--- linux-904/include/asm-um/module-i386.h
+++ linux-905/include/asm-um/module-i386.h
@@ -9,5 +9,9 @@ struct mod_arch_specific
#define Elf_Shdr Elf32_Shdr
#define Elf_Sym Elf32_Sym
#define Elf_Ehdr Elf32_Ehdr
+#define Elf_Rel Elf32_Rel
+#define Elf_Rela Elf32_Rela
+#define ELF_R_TYPE(X) ELF32_R_TYPE(X)
+#define ELF_R_SYM(X) ELF32_R_SYM(X)
#endif
diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-v850/module.h linux-905/include/asm-v850/module.h
--- linux-904/include/asm-v850/module.h
+++ linux-905/include/asm-v850/module.h
@@ -31,9 +31,14 @@ struct mod_arch_specific
unsigned int core_plt_section, init_plt_section;
};
+#define MODULES_ARE_ELF32
#define Elf_Shdr Elf32_Shdr
#define Elf_Sym Elf32_Sym
#define Elf_Ehdr Elf32_Ehdr
+#define Elf_Rel Elf32_Rel
+#define Elf_Rela Elf32_Rela
+#define ELF_R_TYPE(X) ELF32_R_TYPE(X)
+#define ELF_R_SYM(X) ELF32_R_SYM(X)
/* Make empty sections for module_frob_arch_sections to expand. */
#ifdef MODULE
diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-x86_64/module.h linux-905/include/asm-x86_64/module.h
--- linux-904/include/asm-x86_64/module.h
+++ linux-905/include/asm-x86_64/module.h
@@ -3,8 +3,13 @@
struct mod_arch_specific {};
+#define MODULES_ARE_ELF64
#define Elf_Shdr Elf64_Shdr
#define Elf_Sym Elf64_Sym
#define Elf_Ehdr Elf64_Ehdr
+#define Elf_Rel Elf64_Rel
+#define Elf_Rela Elf64_Rela
+#define ELF_R_TYPE(X) ELF64_R_TYPE(X)
+#define ELF_R_SYM(X) ELF64_R_SYM(X)
#endif
linux-2.6-modsign-ksign.patch:
crypto/digest.c | 8
crypto/signature/Makefile | 10
crypto/signature/dsa.c | 98 +++++
crypto/signature/key.h | 7
crypto/signature/ksign-keyring.c | 112 ++++++
crypto/signature/ksign-parse.c | 609 +++++++++++++++++++++++++++++++++++++
crypto/signature/ksign-publickey.c | 19 +
crypto/signature/ksign.c | 179 ++++++++++
crypto/signature/local.h | 163 +++++++++
include/linux/crypto.h | 10
include/linux/crypto/ksign.h | 22 +
11 files changed, 1237 insertions(+)
--- NEW FILE linux-2.6-modsign-ksign.patch ---
diff -urNp --exclude-from=/home/davej/.exclude linux-901/crypto/digest.c linux-902/crypto/digest.c
--- linux-901/crypto/digest.c
+++ linux-902/crypto/digest.c
@@ -52,6 +52,13 @@ static void update(struct crypto_tfm *tf
}
}
+static void update_kernel(struct crypto_tfm *tfm,
+ const void *data, size_t count)
+{
+ tfm->__crt_alg->cra_digest.dia_update(crypto_tfm_ctx(tfm), data, count);
+ crypto_yield(tfm);
+}
+
static void final(struct crypto_tfm *tfm, u8 *out)
{
tfm->__crt_alg->cra_digest.dia_final(crypto_tfm_ctx(tfm), out);
@@ -94,6 +101,7 @@ int crypto_init_digest_ops(struct crypto
ops->dit_init = init;
ops->dit_update = update;
+ ops->dit_update_kernel = update_kernel;
ops->dit_final = final;
ops->dit_digest = digest;
ops->dit_setkey = setkey;
diff -urNp --exclude-from=/home/davej/.exclude linux-901/crypto/signature/dsa.c linux-902/crypto/signature/dsa.c
--- linux-901/crypto/signature/dsa.c
+++ linux-902/crypto/signature/dsa.c
@@ -0,0 +1,98 @@
+/* dsa.c - DSA signature algorithm
+ * Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/crypto/mpi.h>
+#include <asm/errno.h>
+#include "local.h"
+
+/*****************************************************************************/
+/*
+ * perform DSA algorithm signature verification
+ */
+int DSA_verify(const MPI datahash, const MPI sig[], const MPI pkey[])
+{
+ MPI p, q, g, y, r, s;
+ MPI w = NULL, u1 = NULL, u2 = NULL, v = NULL;
+ MPI base[3];
+ MPI exp[3];
+ int rc;
+
+ if (!datahash ||
+ !sig[0] || !sig[1] ||
+ !pkey[0] || !pkey[1] || !pkey[2] || !pkey[3]
+ )
+ return -EINVAL;
+
+ p = pkey[0]; /* prime */
+ q = pkey[1]; /* group order */
+ g = pkey[2]; /* group generator */
+ y = pkey[3]; /* g^x mod p */
+ r = sig[0];
+ s = sig[1];
+
+ if (!(mpi_cmp_ui(r, 0) > 0 && mpi_cmp(r, q) < 0)) {
+ printk("DSA_verify assertion failed [0 < r < q]\n");
+ return -EPERM;
+ }
+
+ if (!(mpi_cmp_ui(s, 0) > 0 && mpi_cmp(s, q) < 0)) {
+ printk("DSA_verify assertion failed [0 < s < q]\n");
+ return -EPERM;
+ }
+
+ rc = -ENOMEM;
+ w = mpi_alloc(mpi_get_nlimbs(q)); if (!w ) goto cleanup;
+ u1 = mpi_alloc(mpi_get_nlimbs(q)); if (!u1) goto cleanup;
+ u2 = mpi_alloc(mpi_get_nlimbs(q)); if (!u2) goto cleanup;
+ v = mpi_alloc(mpi_get_nlimbs(p)); if (!v ) goto cleanup;
+
+ /* w = s^(-1) mod q */
+ if (mpi_invm(w, s, q) < 0)
+ goto cleanup;
+
+ /* u1 = (datahash * w) mod q */
+ if (mpi_mulm(u1, datahash, w, q) < 0)
+ goto cleanup;
+
+ /* u2 = r * w mod q */
+ if (mpi_mulm(u2, r, w, q) < 0)
+ goto cleanup;
+
+ /* v = g^u1 * y^u2 mod p mod q */
+ base[0] = g; exp[0] = u1;
+ base[1] = y; exp[1] = u2;
+ base[2] = NULL; exp[2] = NULL;
+
+ if (mpi_mulpowm(v, base, exp, p) < 0)
+ goto cleanup;
+
+ if (mpi_fdiv_r(v, v, q) < 0)
+ goto cleanup;
+
+ rc = mpi_cmp(v, r) == 0 ? 0 : -EPERM;
+
+ cleanup:
+ mpi_free(w);
+ mpi_free(u1);
+ mpi_free(u2);
+ mpi_free(v);
+ return rc;
+} /* end DSA_verify() */
diff -urNp --exclude-from=/home/davej/.exclude linux-901/crypto/signature/key.h linux-902/crypto/signature/key.h
--- linux-901/crypto/signature/key.h
+++ linux-902/crypto/signature/key.h
@@ -0,0 +1,7 @@
+const int ksign_def_public_key_size = 0;
+/* automatically generated by bin2hex */
+static unsigned char ksign_def_public_key[] __initdata =
+{
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
diff -urNp --exclude-from=/home/davej/.exclude linux-901/crypto/signature/ksign.c linux-902/crypto/signature/ksign.c
--- linux-901/crypto/signature/ksign.c
+++ linux-902/crypto/signature/ksign.c
@@ -0,0 +1,179 @@
+/* ksign.c: signature checker
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells at redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <asm/errno.h>
+#include "local.h"
+
+#if 0
+#define _debug(FMT, ...) printk(KERN_DEBUG FMT, ##__VA_ARGS__)
+#else
+#define _debug(FMT, ...) do { ; } while (0)
+#endif
+
+/*****************************************************************************/
+/*
+ * check the signature which is contained in SIG.
+ */
+static int ksign_signature_check(const struct ksign_signature *sig,
+ struct crypto_tfm *sha1_tfm)
+{
+ struct ksign_public_key *pk;
+ uint8_t sha1[SHA1_DIGEST_SIZE];
+ MPI result = NULL;
+ int rc = 0;
+
+ pk = ksign_get_public_key(sig->keyid);
+ if (!pk) {
+ printk("ksign: module signed with unknown public key\n");
+ printk("- signature keyid: %08x%08x ver=%u\n",
+ sig->keyid[0], sig->keyid[1], sig->version);
+ return -EPERM;
+ }
+
+ if (pk->timestamp > sig->timestamp)
+ printk("ksign:"
+ " public key is %lu seconds newer than the signature\n",
+ pk->timestamp - sig->timestamp);
+
+ /* complete the digest */
+ if (sig->version >= 4)
+ SHA1_putc(sha1_tfm, sig->version);
+ SHA1_putc(sha1_tfm, sig->sig_class);
+
+ if (sig->version < 4) {
+ u32 a = sig->timestamp;
+ SHA1_putc(sha1_tfm, (a >> 24) & 0xff);
+ SHA1_putc(sha1_tfm, (a >> 16) & 0xff);
+ SHA1_putc(sha1_tfm, (a >> 8) & 0xff);
+ SHA1_putc(sha1_tfm, (a >> 0) & 0xff);
+ }
+ else {
+ uint8_t buf[6];
+ size_t n;
+ SHA1_putc(sha1_tfm, PUBKEY_ALGO_DSA);
+ SHA1_putc(sha1_tfm, DIGEST_ALGO_SHA1);
+ if (sig->hashed_data) {
+ n = (sig->hashed_data[0] << 8) | sig->hashed_data[1];
+ SHA1_write(sha1_tfm, sig->hashed_data, n + 2);
+ n += 6;
+ }
+ else {
+ n = 6;
+ }
+
+ /* add some magic */
+ buf[0] = sig->version;
+ buf[1] = 0xff;
+ buf[2] = n >> 24;
+ buf[3] = n >> 16;
+ buf[4] = n >> 8;
+ buf[5] = n;
+ SHA1_write(sha1_tfm, buf, 6);
+ }
+
+ crypto_digest_final(sha1_tfm, sha1);
+ crypto_free_tfm(sha1_tfm);
+
+
+
+
+
+
+ rc = -ENOMEM;
+ result = mpi_alloc((SHA1_DIGEST_SIZE + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB);
+ if (!result)
+ goto cleanup;
+
+ rc = mpi_set_buffer(result, sha1, SHA1_DIGEST_SIZE, 0);
+ if (rc < 0)
+ goto cleanup;
+
+ rc = DSA_verify(result, sig->data, pk->pkey);
+
+ cleanup:
+ mpi_free(result);
+ ksign_put_public_key(pk);
+
+ return rc;
+} /* end ksign_signature_check() */
+
+/*****************************************************************************/
+/*
+ * examine the signatures that are parsed out of the signature data - we keep
+ * the first one that's appropriate and ignore the rest
+ * - return 0 if signature of interest (sig not freed by caller)
+ * - return 1 if no interest (caller frees)
+ */
+static int ksign_grab_signature(struct ksign_signature *sig, void *fnxdata)
+{
+ struct ksign_signature **_sig = fnxdata;
+
+ if (sig->sig_class != 0x00) {
+ _debug("ksign: standalone signature of class 0x%02x\n",
+ sig->sig_class);
+ return 1;
+ }
+
+ if (*_sig)
+ return 1;
+
+ *_sig = sig;
+ return 0;
+} /* end ksign_grab_signature() */
+
+/*****************************************************************************/
+/*
+ * verify the signature of some data with one of the kernel's known public keys
+ * - the SHA1 context should be currently open with the signed data digested
+ * into it so that more data can be appended
+ * - the SHA1 context is finalised and freed before returning
+ */
+int ksign_verify_signature(const char *sigdata, unsigned sig_size,
+ struct crypto_tfm *sha1)
+{
+ struct ksign_signature *sig = NULL;
+ int retval;
+
+ /* parse the signature data to get the actual signature */
+ retval = ksign_parse_packets(sigdata, sig_size,
+ &ksign_grab_signature, NULL, NULL,
+ &sig);
+ if (retval < 0)
+ goto cleanup;
+
+ if (!sig) {
+ printk("Couldn't find valid DSA signature in module\n");
+ return -ENOENT;
+ }
+
+ _debug("signature keyid: %08x%08x ver=%u\n",
+ sig->keyid[0], sig->keyid[1], sig->version);
+
+ /* check the data SHA1 transformation against the public key */
+ retval = ksign_signature_check(sig, sha1);
+ if (retval == 0) {
+ _debug("ksign: Signature check succeeded\n");
+ }
+ else if (retval != -ENOMEM) {
+ _debug("ksign: Signature check failed\n");
+ retval = -EPERM;
+ }
+ else {
+ _debug("ksign: Signature check ENOMEM\n");
+ }
+
+ cleanup:
+ if (sig)
+ ksign_free_signature(sig);
+
+ return retval;
+} /* end ksign_verify_signature() */
diff -urNp --exclude-from=/home/davej/.exclude linux-901/crypto/signature/ksign-keyring.c linux-902/crypto/signature/ksign-keyring.c
--- linux-901/crypto/signature/ksign-keyring.c
+++ linux-902/crypto/signature/ksign-keyring.c
@@ -0,0 +1,112 @@
+/* ksign-keyring.c: public key cache
+ *
+ * Copyright (C) 2001 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells at redhat.com)
+ *
+ * This file is derived from part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <linux/rwsem.h>
+#include "local.h"
+
+static LIST_HEAD(keyring);
+static DECLARE_RWSEM(keyring_sem);
+
+static int add_keyblock_key(struct ksign_public_key *pk, void *data)
+{
+ printk("- Added public key %X%X\n", pk->keyid[0], pk->keyid[1]);
+
+ if (pk->expiredate && pk->expiredate < xtime.tv_sec)
+ printk(" - public key has expired\n");
+
+ if (pk->timestamp > xtime.tv_sec )
+ printk(" - key was been created %lu seconds in future\n",
+ pk->timestamp - xtime.tv_sec);
+
+ atomic_inc(&pk->count);
+
+ down_write(&keyring_sem);
+ list_add_tail(&pk->link, &keyring);
+ up_write(&keyring_sem);
+
+ return 0;
+}
+
+static int add_keyblock_uid(struct ksign_user_id *uid, void *data)
+{
+ printk("- User ID: %s\n", uid->name);
+ return 1;
+}
+
+/*****************************************************************************/
+/*
+ *
+ */
+int ksign_load_keyring_from_buffer(const void *buffer, size_t size)
+{
+ printk("Loading keyring\n");
+
+ return ksign_parse_packets((const uint8_t *) buffer,
+ size,
+ NULL,
+ add_keyblock_key,
+ add_keyblock_uid,
+ NULL);
+} /* end ksign_load_keyring_from_buffer() */
+
+/*****************************************************************************/
+/*
+ *
+ */
+struct ksign_public_key *ksign_get_public_key(const uint32_t *keyid)
+{
+ struct ksign_public_key *pk;
+
+ down_read(&keyring_sem);
+
+ list_for_each_entry(pk, &keyring, link) {
+ if (memcmp(pk->keyid, keyid, sizeof(pk->keyid)) == 0) {
+ atomic_inc(&pk->count);
+ goto found;
+ }
+ }
+
+ found:
+ up_read(&keyring_sem);
+
+ return pk;
+} /* end ksign_get_public_key() */
+
+/*****************************************************************************/
+/*
+ * clear the public key keyring
+ */
+void ksign_clear_keyring(void)
+{
+ struct ksign_public_key *pk;
+
+ down_write(&keyring_sem);
+
+ while (!list_empty(&keyring)) {
+ pk = list_entry(keyring.next, struct ksign_public_key, link);
+ list_del(&pk->link);
+
+ ksign_put_public_key(pk);
+ }
+
+ up_write(&keyring_sem);
+} /* end ksign_clear_keyring() */
diff -urNp --exclude-from=/home/davej/.exclude linux-901/crypto/signature/ksign-parse.c linux-902/crypto/signature/ksign-parse.c
--- linux-901/crypto/signature/ksign-parse.c
+++ linux-902/crypto/signature/ksign-parse.c
@@ -0,0 +1,609 @@
+/* parse-packet.c - read packets
+ * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <asm/errno.h>
+#include "local.h"
+
+static inline uint32_t buffer_to_u32(const uint8_t *buffer)
+{
+ uint32_t a;
+ a = *buffer << 24;
+ a |= buffer[1] << 16;
+ a |= buffer[2] << 8;
+ a |= buffer[3];
+ return a;
+}
+
+static inline uint16_t read_16(const uint8_t **datap)
+{
+ uint16_t a;
+ a = *(*datap)++ << 8;
+ a |= *(*datap)++;
+ return a;
+}
+
+static inline uint32_t read_32(const uint8_t **datap)
+{
+ uint32_t a;
+ a = *(*datap)++ << 24;
+ a |= *(*datap)++ << 16;
+ a |= *(*datap)++ << 8;
+ a |= *(*datap)++;
+ return a;
+}
+
+void ksign_free_signature(struct ksign_signature *sig)
+{
+ int i;
+
+ if (!sig)
+ return;
+
+ for (i = 0; i < DSA_NSIG; i++)
+ mpi_free(sig->data[i]);
+ kfree(sig->hashed_data);
+ kfree(sig->unhashed_data);
+ kfree(sig);
+}
+
+void ksign_free_public_key(struct ksign_public_key *pk)
+{
+ int i;
+
+ if (pk) {
+ for (i = 0; i < DSA_NPKEY; i++)
+ mpi_free(pk->pkey[i]);
+ kfree(pk);
+ }
+}
+
+void ksign_free_user_id(struct ksign_user_id *uid)
+{
+ if (uid)
+ kfree(uid);
+}
+
+/*****************************************************************************/
+/*
+ *
+ */
+static void ksign_calc_pk_keyid(struct crypto_tfm *sha1,
+ struct ksign_public_key *pk)
+{
+ unsigned n;
+ unsigned nb[DSA_NPKEY];
+ unsigned nn[DSA_NPKEY];
+ uint8_t *pp[DSA_NPKEY];
+ uint32_t a32;
+ int i;
+ int npkey = DSA_NPKEY;
+
+ crypto_digest_init(sha1);
+
+ n = pk->version < 4 ? 8 : 6;
+ for (i = 0; i < npkey; i++) {
+ nb[i] = mpi_get_nbits(pk->pkey[i]);
+ pp[i] = mpi_get_buffer( pk->pkey[i], nn + i, NULL);
+ n += 2 + nn[i];
+ }
+
+ SHA1_putc(sha1, 0x99); /* ctb */
+ SHA1_putc(sha1, n >> 8); /* 2 uint8_t length header */
+ SHA1_putc(sha1, n);
+
+ if( pk->version < 4)
+ SHA1_putc(sha1, 3);
+ else
+ SHA1_putc(sha1, 4);
+
+ a32 = pk->timestamp;
+ SHA1_putc(sha1, a32 >> 24 );
+ SHA1_putc(sha1, a32 >> 16 );
+ SHA1_putc(sha1, a32 >> 8 );
+ SHA1_putc(sha1, a32 >> 0 );
+
+ if (pk->version < 4) {
+ uint16_t a16;
+
+ if( pk->expiredate )
+ a16 = (uint16_t) ((pk->expiredate - pk->timestamp) / 86400L);
+ else
+ a16 = 0;
+ SHA1_putc(sha1, a16 >> 8);
+ SHA1_putc(sha1, a16 >> 0);
+ }
+
+ SHA1_putc(sha1, PUBKEY_ALGO_DSA);
+
+ for (i = 0; i < npkey; i++) {
+ SHA1_putc(sha1, nb[i] >> 8);
+ SHA1_putc(sha1, nb[i]);
+ SHA1_write(sha1, pp[i], nn[i]);
+ kfree(pp[i]);
+ }
+
+} /* end ksign_calc_pk_keyid() */
+
+/*****************************************************************************/
+/*
+ * parse a user ID embedded in a signature
+ */
+static int ksign_parse_user_id(const uint8_t *datap, const uint8_t *endp,
+ ksign_user_id_actor_t uidfnx, void *fnxdata)
+{
+ struct ksign_user_id *uid;
+ int rc = 0;
+ int n;
+
+ if (!uidfnx)
+ return 0;
+
+ n = endp - datap;
+ uid = kmalloc(sizeof(*uid) + n + 1, GFP_KERNEL);
+ if (!uid)
+ return -ENOMEM;
+ uid->len = n;
+
+ memcpy(uid->name, datap, n);
+ uid->name[n] = 0;
+
+ rc = uidfnx(uid, fnxdata);
+ if (rc == 0)
+ return rc; /* uidfnx keeps the record */
+ if (rc == 1)
+ rc = 0;
+
+ ksign_free_user_id(uid);
+ return rc;
+} /* end ksign_parse_user_id() */
+
+/*****************************************************************************/
+/*
+ * extract a public key embedded in a signature
+ */
+static int ksign_parse_key(const uint8_t *datap, const uint8_t *endp,
+ uint8_t *hdr, int hdrlen,
+ ksign_public_key_actor_t pkfnx, void *fnxdata)
+{
+ struct ksign_public_key *pk;
+ struct crypto_tfm *sha1_tfm;
+ unsigned long timestamp, expiredate;
+ uint8_t sha1[SHA1_DIGEST_SIZE];
+ int i, version;
+ int is_v4 = 0;
+ int rc = 0;
+
+ if (endp - datap < 12) {
+ printk("ksign: public key packet too short\n");
+ return -EBADMSG;
+ }
+
+ version = *datap++;
+ switch (version) {
+ case 4:
+ is_v4 = 1;
+ case 2:
+ case 3:
+ break;
+ default:
+ printk("ksign: public key packet with unknown version %d\n",
+ version);
+ return -EBADMSG;
+ }
+
+ timestamp = read_32(&datap);
+ if (is_v4)
+ expiredate = 0; /* have to get it from the selfsignature */
+ else {
+ unsigned short ndays;
+ ndays = read_16(&datap);
+ if (ndays)
+ expiredate = timestamp + ndays * 86400L;
+ else
+ expiredate = 0;
+ }
+
+ if (*datap++ != PUBKEY_ALGO_DSA) {
+ printk("ksign: public key packet with unknown version %d\n",
+ version);
+ return 0;
+ }
+
+ /* extract the stuff from the DSA public key */
+ pk = kmalloc(sizeof(struct ksign_public_key), GFP_KERNEL);
+ if (!pk)
+ return -ENOMEM;
+
+ memset(pk, 0, sizeof(struct ksign_public_key));
+ atomic_set(&pk->count, 1);
+ pk->timestamp = timestamp;
+ pk->expiredate = expiredate;
+ pk->hdrbytes = hdrlen;
+ pk->version = version;
+
+ for (i = 0; i < DSA_NPKEY; i++) {
+ unsigned int remaining = endp - datap;
+ pk->pkey[i] = mpi_read_from_buffer(datap, &remaining);
+ datap += remaining;
+ }
+
+ rc = -ENOMEM;
+
+ sha1_tfm = crypto_alloc_tfm2("sha1", 0, 1);
+ if (!sha1_tfm)
+ goto cleanup;
+
+ ksign_calc_pk_keyid(sha1_tfm, pk);
+ crypto_digest_final(sha1_tfm, sha1);
+ crypto_free_tfm(sha1_tfm);
+
+ pk->keyid[0] = sha1[12] << 24 | sha1[13] << 16 | sha1[14] << 8 | sha1[15];
+ pk->keyid[1] = sha1[16] << 24 | sha1[17] << 16 | sha1[18] << 8 | sha1[19];
+
+ rc = 0;
+ if (pkfnx)
+ rc = pkfnx(pk, fnxdata);
+
+ cleanup:
+ ksign_put_public_key(pk);
+ return rc;
+} /* end ksign_parse_key() */
+
+/*****************************************************************************/
+/*
+ *
+ */
+static const uint8_t *ksign_find_sig_issuer(const uint8_t *buffer)
+{
+ size_t buflen;
+ size_t n;
+ int type;
+ int seq = 0;
+
+ if (!buffer)
+ return NULL;
+
+ buflen = read_16(&buffer);
+ while (buflen) {
+ n = *buffer++; buflen--;
+ if (n == 255) {
+ if (buflen < 4)
+ goto too_short;
+ n = read_32(&buffer);
+ buflen -= 4;
+ }
+ else if (n >= 192) {
+ if(buflen < 2)
+ goto too_short;
+ n = ((n - 192) << 8) + *buffer + 192;
+ buffer++;
+ buflen--;
+ }
+
+ if (buflen < n)
+ goto too_short;
+
+ type = *buffer & 0x7f;
+ if (!(++seq > 0))
+ ;
+ else if (type == SIGSUBPKT_ISSUER) { /* found */
+ buffer++;
+ n--;
+ if (n > buflen || n < 8)
+ goto too_short;
+ return buffer;
+ }
+
+ buffer += n;
+ buflen -= n;
+ }
+
+ too_short:
+ return NULL; /* end of subpackets; not found */
+} /* end ksign_find_sig_issuer() */
+
+/*****************************************************************************/
+/*
+ * extract signature data embedded in a signature
+ */
+static int ksign_parse_signature(const uint8_t *datap, const uint8_t *endp,
+ ksign_signature_actor_t sigfnx, void *fnxdata)
+{
+ struct ksign_signature *sig;
+ size_t n;
+ int version, is_v4 = 0;
+ int rc;
+ int i;
+
+ if (endp - datap < 16) {
+ printk("ksign: signature packet too short\n");
+ return -EBADMSG;
+ }
+
+ version = *datap++;
+ switch (version) {
+ case 4:
+ is_v4 = 1;
+ case 3:
+ case 2:
+ break;
+ default:
+ printk("ksign: signature packet with unknown version %d\n", version);
+ return 0;
+ }
+
+ /* store information */
+ sig = kmalloc(sizeof(*sig), GFP_KERNEL);
+ if (!sig)
+ return -ENOMEM;
+
+ memset(sig, 0, sizeof(*sig));
+ sig->version = version;
+
+ if (!is_v4)
+ datap++; /* ignore md5 length */
+
+ sig->sig_class = *datap++;
+ if (!is_v4) {
+ sig->timestamp = read_32(&datap);
+ sig->keyid[0] = read_32(&datap);
+ sig->keyid[1] = read_32(&datap);
+ }
+
+ rc = 0;
+ if (*datap++ != PUBKEY_ALGO_DSA) {
+ printk("ksign: ignoring non-DSA signature\n");
+ goto leave;
+ }
+ if (*datap++ != DIGEST_ALGO_SHA1) {
+ printk("ksign: ignoring non-SHA1 signature\n");
+ goto leave;
+ }
+
+ rc = -EBADMSG;
+ if (is_v4) { /* read subpackets */
+ n = read_16(&datap); /* length of hashed data */
+ if (n > 10000) {
+ printk("ksign: signature packet: hashed data too long\n");
+ goto leave;
+ }
+ if (n) {
+ if ((size_t)(endp - datap) < n) {
+ printk("ksign: signature packet: available data too short\n");
+ goto leave;
+ }
+ sig->hashed_data = kmalloc(n + 2, GFP_KERNEL);
+ if (!sig->hashed_data) {
+ rc = -ENOMEM;
+ goto leave;
+ }
+ sig->hashed_data[0] = n >> 8;
+ sig->hashed_data[1] = n;
+ memcpy(sig->hashed_data + 2, datap, n);
+ datap += n;
+ }
+
+ n = read_16(&datap); /* length of unhashed data */
+ if (n > 10000) {
+ printk("ksign: signature packet: unhashed data too long\n");
+ goto leave;
+ }
+ if (n) {
+ if ((size_t) (endp - datap) < n) {
+ printk("ksign: signature packet: available data too short\n");
+ goto leave;
+ }
+ sig->unhashed_data = kmalloc(n + 2, GFP_KERNEL);
+ if (!sig->unhashed_data) {
+ rc = -ENOMEM;
+ goto leave;
+ }
+ sig->unhashed_data[0] = n >> 8;
+ sig->unhashed_data[1] = n;
+ memcpy(sig->unhashed_data + 2, datap, n);
+ datap += n;
+ }
+ }
+
+ if (endp - datap < 5) { /* sanity check */
+ printk("ksign: signature packet too short\n");
+ goto leave;
+ }
+
+ sig->digest_start[0] = *datap++;
+ sig->digest_start[1] = *datap++;
+
+ if (is_v4) {
+ const uint8_t *p;
+
+ p = ksign_find_sig_issuer(sig->hashed_data);
+ if (!p)
+ p = ksign_find_sig_issuer(sig->unhashed_data);
+ if (!p)
+ printk("ksign: signature packet without issuer\n");
+ else {
+ sig->keyid[0] = buffer_to_u32(p);
+ sig->keyid[1] = buffer_to_u32(p + 4);
+ }
+ }
+
+ for (i = 0; i < DSA_NSIG; i++) {
+ unsigned remaining = endp - datap;
+ sig->data[i] = mpi_read_from_buffer(datap, &remaining);
+ datap += remaining;
+ }
+
+ rc = 0;
+ if (sigfnx) {
+ rc = sigfnx(sig, fnxdata);
+ if (rc == 0)
+ return rc; /* sigfnx keeps the signature */
+ if (rc == 1)
+ rc = 0;
+ }
+
+ leave:
+ ksign_free_signature(sig);
+ return rc;
+} /* end ksign_parse_signature() */
+
+/*****************************************************************************/
+/*
+ * parse the next packet and call appropriate handler function for known types
+ * - returns:
+ * 0 on EOF
+ * 1 if there might be more packets
+ * -EBADMSG if the packet is in an invalid format
+ * -ve on other error
+ */
+static int ksign_parse_one_packet(const uint8_t **datap,
+ const uint8_t *endp,
+ ksign_signature_actor_t sigfnx,
+ ksign_public_key_actor_t pkfnx,
+ ksign_user_id_actor_t uidfnx,
+ void *data)
+{
+ int rc, c, ctb, pkttype, lenuint8_ts;
+ unsigned long pktlen;
+ uint8_t hdr[8];
+ int hdrlen;
+
+ /* extract the next packet and dispatch it */
+ rc = 0;
+ if (*datap >= endp)
+ goto leave;
+ ctb = *(*datap)++;
+
+ rc = -EBADMSG;
+
+ hdrlen = 0;
+ hdr[hdrlen++] = ctb;
+ if (!(ctb & 0x80)) {
+ printk("ksign: invalid packet (ctb=%02x)\n", ctb);
+ goto leave;
+ }
+
+ pktlen = 0;
+ if (ctb & 0x40) {
+ pkttype = ctb & 0x3f;
+ if (*datap >= endp) {
+ printk("ksign: 1st length byte missing\n");
+ goto leave;
+ }
+ c = *(*datap)++;
+ hdr[hdrlen++] = c;
+
+ if (c < 192) {
+ pktlen = c;
+ }
+ else if (c < 224) {
+ pktlen = (c - 192) * 256;
+ if (*datap >= endp) {
+ printk("ksign: 2nd length uint8_t missing\n");
+ goto leave;
+ }
+ c = *(*datap)++;
+ hdr[hdrlen++] = c;
+ pktlen += c + 192;
+ }
+ else if (c == 255) {
+ if (*datap + 3 >= endp) {
+ printk("ksign: 4 uint8_t length invalid\n");
+ goto leave;
+ }
+ pktlen = (hdr[hdrlen++] = *(*datap)++ << 24 );
+ pktlen |= (hdr[hdrlen++] = *(*datap)++ << 16 );
+ pktlen |= (hdr[hdrlen++] = *(*datap)++ << 8 );
+ pktlen |= (hdr[hdrlen++] = *(*datap)++ << 0 );
+ }
+ else {
+ pktlen = 0;/* to indicate partial length */
+ }
+ }
+ else {
+ pkttype = (ctb >> 2) & 0xf;
+ lenuint8_ts = ((ctb & 3) == 3) ? 0 : (1 << (ctb & 3));
+ if( !lenuint8_ts ) {
+ pktlen = 0; /* don't know the value */
+ }
+ else {
+ if (*datap + lenuint8_ts > endp) {
+ printk("ksign: length uint8_ts missing\n");
+ goto leave;
+ }
+ for( ; lenuint8_ts; lenuint8_ts-- ) {
+ pktlen <<= 8;
+ pktlen |= hdr[hdrlen++] = *(*datap)++;
+ }
+ }
+ }
+
+ if (*datap + pktlen > endp) {
+ printk("ksign: packet length longer than available data\n");
+ goto leave;
+ }
+
+ /* deal with the next packet appropriately */
+ switch (pkttype) {
+ case PKT_PUBLIC_KEY:
+ rc = ksign_parse_key(*datap, *datap + pktlen, hdr, hdrlen, pkfnx, data);
+ break;
+ case PKT_SIGNATURE:
+ rc = ksign_parse_signature(*datap, *datap + pktlen, sigfnx, data);
+ break;
+ case PKT_USER_ID:
+ rc = ksign_parse_user_id(*datap, *datap + pktlen, uidfnx, data);
+ break;
+ default:
+ rc = 0; /* unknown packet */
+ break;
+ }
+
+ *datap += pktlen;
+ leave:
+ return rc;
+} /* end ksign_parse_one_packet() */
+
+/*****************************************************************************/
+/*
+ * parse the contents of a packet buffer, passing the signature, public key and
+ * user ID to the caller's callback functions
+ */
+int ksign_parse_packets(const uint8_t *buf,
+ size_t size,
+ ksign_signature_actor_t sigfnx,
+ ksign_public_key_actor_t pkfnx,
+ ksign_user_id_actor_t uidfnx,
+ void *data)
+{
+ const uint8_t *datap, *endp;
+ int rc;
+
+ datap = buf;
+ endp = buf + size;
+ do {
+ rc = ksign_parse_one_packet(&datap, endp,
+ sigfnx, pkfnx, uidfnx, data);
+ } while (rc == 0 && datap < endp);
+
+ return rc;
+} /* end ksign_parse_packets() */
diff -urNp --exclude-from=/home/davej/.exclude linux-901/crypto/signature/ksign-publickey.c linux-902/crypto/signature/ksign-publickey.c
--- linux-901/crypto/signature/ksign-publickey.c
+++ linux-902/crypto/signature/ksign-publickey.c
@@ -0,0 +1,19 @@
+#include "local.h"
+
+#include "key.h"
+
+static int __init ksign_init(void)
+{
+ int rc;
+
+ printk("ksign: Installing public key data\n");
+
+ rc = ksign_load_keyring_from_buffer(ksign_def_public_key,
+ ksign_def_public_key_size);
+ if (rc < 0)
+ printk("Unable to load default keyring: error=%d\n", -rc);
+
+ return rc;
+}
+
+module_init(ksign_init)
diff -urNp --exclude-from=/home/davej/.exclude linux-901/crypto/signature/local.h linux-902/crypto/signature/local.h
--- linux-901/crypto/signature/local.h
+++ linux-902/crypto/signature/local.h
@@ -0,0 +1,163 @@
+/* local.h: kernel signature checker internal defs
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells at redhat.com)
+ * - Derived from GnuPG packet.h - packet definitions
+ * - Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <linux/list.h>
+#include <linux/crypto.h>
+#include <linux/crypto/ksign.h>
+#include <linux/crypto/mpi.h>
+#include <asm/atomic.h>
+
+#define SHA1_DIGEST_SIZE 20
+
+#define PUBKEY_USAGE_SIG 1 /* key is good for signatures */
+#define PUBKEY_USAGE_ENC 2 /* key is good for encryption */
+
+#define PUBKEY_ALGO_DSA 17
+#define DSA_NPKEY 4 /* number of MPI's in DSA public key */
+#define DSA_NSIG 2 /* number of MPI's in DSA signature */
+
+#define DIGEST_ALGO_SHA1 2
+
+typedef enum {
+ PKT_NONE = 0,
+ PKT_SIGNATURE = 2, /* secret key encrypted packet */
+ PKT_PUBLIC_KEY = 6, /* public key */
+ PKT_USER_ID = 13, /* user id packet */
+} pkttype_t;
+
+typedef enum {
+ SIGSUBPKT_TEST_CRITICAL = -3,
+ SIGSUBPKT_NONE = 0,
+ SIGSUBPKT_SIG_CREATED = 2, /* signature creation time */
+ SIGSUBPKT_SIG_EXPIRE = 3, /* signature expiration time */
+ SIGSUBPKT_EXPORTABLE = 4, /* exportable */
+ SIGSUBPKT_TRUST = 5, /* trust signature */
+ SIGSUBPKT_REGEXP = 6, /* regular expression */
+ SIGSUBPKT_REVOCABLE = 7, /* revocable */
+ SIGSUBPKT_KEY_EXPIRE = 9, /* key expiration time */
+ SIGSUBPKT_ARR = 10, /* additional recipient request */
+ SIGSUBPKT_PREF_SYM = 11, /* preferred symmetric algorithms */
+ SIGSUBPKT_REV_KEY = 12, /* revocation key */
+ SIGSUBPKT_ISSUER = 16, /* issuer key ID */
+ SIGSUBPKT_NOTATION = 20, /* notation data */
+ SIGSUBPKT_PREF_HASH = 21, /* preferred hash algorithms */
+ SIGSUBPKT_PREF_COMPR = 22, /* preferred compression algorithms */
+ SIGSUBPKT_KS_FLAGS = 23, /* key server preferences */
+ SIGSUBPKT_PREF_KS = 24, /* preferred key server */
+ SIGSUBPKT_PRIMARY_UID = 25, /* primary user id */
+ SIGSUBPKT_POLICY = 26, /* policy URL */
+ SIGSUBPKT_KEY_FLAGS = 27, /* key flags */
+ SIGSUBPKT_SIGNERS_UID = 28, /* signer's user id */
+ SIGSUBPKT_REVOC_REASON = 29, /* reason for revocation */
+ SIGSUBPKT_PRIV_VERIFY_CACHE = 101, /* cache verification result */
+
+ SIGSUBPKT_FLAG_CRITICAL = 128
+} sigsubpkttype_t;
+
+/*
+ * signature record
+ */
+struct ksign_signature
+{
+ uint32_t keyid[2]; /* 64 bit keyid */
+ time_t timestamp; /* signature made */
+ uint8_t version;
+ uint8_t sig_class; /* sig classification, append for MD calculation*/
+ uint8_t *hashed_data; /* all subpackets with hashed data (v4 only) */
+ uint8_t *unhashed_data; /* ditto for unhashed data */
+ uint8_t digest_start[2]; /* first 2 uint8_ts of the digest */
+ MPI data[DSA_NSIG];
+};
+
+extern void ksign_free_signature(struct ksign_signature *sig);
+
+/*
+ * public key record
+ */
+struct ksign_public_key
+{
+ struct list_head link;
+ atomic_t count; /* ref count */
+ time_t timestamp; /* key made */
+ time_t expiredate; /* expires at this date or 0 if not at all */
+ uint8_t hdrbytes; /* number of header bytes */
+ uint8_t version;
+ int is_valid; /* key (especially subkey) is valid */
+ unsigned long local_id; /* internal use, valid if > 0 */
+ uint32_t main_keyid[2]; /* keyid of the primary key */
+ uint32_t keyid[2]; /* calculated by keyid_from_pk() */
+ MPI pkey[DSA_NPKEY];
+};
+
+extern void ksign_free_public_key(struct ksign_public_key *pk);
+
+static inline void ksign_put_public_key(struct ksign_public_key *pk)
+{
+ if (atomic_dec_and_test(&pk->count))
+ ksign_free_public_key(pk);
+}
+
+extern int ksign_load_keyring_from_buffer(const void *buffer, size_t size);
+
+extern struct ksign_public_key *ksign_get_public_key(const uint32_t *keyid);
+
+/*
+ * user ID record
+ */
+struct ksign_user_id
+{
+ int len; /* length of the name */
+ char name[0];
+};
+
+extern void ksign_free_user_id(struct ksign_user_id *uid);
+
+/*
+ *
+ */
+typedef int (*ksign_signature_actor_t)(struct ksign_signature *, void *fnxdata);
+typedef int (*ksign_public_key_actor_t)(struct ksign_public_key *, void *fnxdata);
+typedef int (*ksign_user_id_actor_t)(struct ksign_user_id *, void *fnxdata);
+
+extern int ksign_parse_packets(const uint8_t *buf,
+ size_t size,
+ ksign_signature_actor_t sigfnx,
+ ksign_public_key_actor_t pkfnx,
+ ksign_user_id_actor_t uidfnx,
+ void *data);
+
+extern int DSA_verify(const MPI datahash, const MPI sig[], const MPI pkey[]);
+
+/*
+ * fast access to the digest
+ * - we _know_ the data is locked into kernel memory, so we don't want to have
+ * to kmap() it
+ */
+static inline void SHA1_putc(struct crypto_tfm *sha1, uint8_t ch)
+{
+ crypto_digest_update_kernel(sha1, &ch, 1);
+}
+
+static inline void SHA1_write(struct crypto_tfm *sha1, const void *s, size_t n)
+{
+ crypto_digest_update_kernel(sha1, s, n);
+}
diff -urNp --exclude-from=/home/davej/.exclude linux-901/crypto/signature/Makefile linux-902/crypto/signature/Makefile
--- linux-901/crypto/signature/Makefile
+++ linux-902/crypto/signature/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for the signature checker
+#
+
+obj-y := \
+ ksign.o \
+ ksign-parse.o \
+ ksign-keyring.o \
+ ksign-publickey.o \
+ dsa.o
diff -urNp --exclude-from=/home/davej/.exclude linux-901/include/linux/crypto/ksign.h linux-902/include/linux/crypto/ksign.h
--- linux-901/include/linux/crypto/ksign.h
+++ linux-902/include/linux/crypto/ksign.h
@@ -0,0 +1,22 @@
+/* ksign.h: in-kernel signature checker
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells at redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _LINUX_CRYPTO_KSIGN_H
+#define _LINUX_CRYPTO_KSIGN_H
+
+#include <linux/types.h>
+
+#ifdef CONFIG_CRYPTO_SIGNATURE
+extern int ksign_verify_signature(const char *sig, unsigned sig_size,
+ struct crypto_tfm *sha1);
+#endif
+
+#endif /* _LINUX_CRYPTO_KSIGN_H */
diff -urNp --exclude-from=/home/davej/.exclude linux-901/include/linux/crypto.h linux-902/include/linux/crypto.h
--- linux-901/include/linux/crypto.h
+++ linux-902/include/linux/crypto.h
@@ -167,6 +167,8 @@ struct digest_tfm {
void (*dit_init)(struct crypto_tfm *tfm);
void (*dit_update)(struct crypto_tfm *tfm,
struct scatterlist *sg, unsigned int nsg);
+ void (*dit_update_kernel)(struct crypto_tfm *tfm,
+ const void *data, size_t count);
void (*dit_final)(struct crypto_tfm *tfm, u8 *out);
void (*dit_digest)(struct crypto_tfm *tfm, struct scatterlist *sg,
unsigned int nsg, u8 *out);
@@ -287,6 +289,14 @@ static inline void crypto_digest_update(
tfm->crt_digest.dit_update(tfm, sg, nsg);
}
+static inline void crypto_digest_update_kernel(struct crypto_tfm *tfm,
+ const void *data,
+ size_t count)
+{
+ BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
+ tfm->crt_digest.dit_update_kernel(tfm, data, count);
+}
+
static inline void crypto_digest_final(struct crypto_tfm *tfm, u8 *out)
{
BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
linux-2.6-modsign-mpilib.patch:
crypto/mpi/Makefile | 30
crypto/mpi/generic_mpi-asm-defs.h | 10
crypto/mpi/generic_mpih-add1.c | 62 +
crypto/mpi/generic_mpih-lshift.c | 66 +
crypto/mpi/generic_mpih-mul1.c | 58 +
crypto/mpi/generic_mpih-mul2.c | 63 +
crypto/mpi/generic_mpih-mul3.c | 64 +
crypto/mpi/generic_mpih-rshift.c | 65 +
crypto/mpi/generic_mpih-sub1.c | 62 +
crypto/mpi/generic_udiv-w-sdiv.c | 130 +++
crypto/mpi/longlong.h | 1502 ++++++++++++++++++++++++++++++++++++++
crypto/mpi/mpi-add.c | 258 ++++++
crypto/mpi/mpi-bit.c | 245 ++++++
crypto/mpi/mpi-cmp.c | 71 +
crypto/mpi/mpi-div.c | 345 ++++++++
crypto/mpi/mpi-gcd.c | 60 +
crypto/mpi/mpi-inline.c | 33
crypto/mpi/mpi-inline.h | 128 +++
crypto/mpi/mpi-internal.h | 265 ++++++
crypto/mpi/mpi-inv.c | 148 +++
crypto/mpi/mpi-mpow.c | 113 ++
crypto/mpi/mpi-mul.c | 202 +++++
crypto/mpi/mpi-pow.c | 312 +++++++
crypto/mpi/mpi-scan.c | 129 +++
crypto/mpi/mpicoder.c | 359 +++++++++
crypto/mpi/mpih-cmp.c | 58 +
crypto/mpi/mpih-div.c | 534 +++++++++++++
crypto/mpi/mpih-mul.c | 547 +++++++++++++
crypto/mpi/mpiutil.c | 214 +++++
include/linux/crypto/mpi.h | 147 +++
30 files changed, 6280 insertions(+)
--- NEW FILE linux-2.6-modsign-mpilib.patch ---
diff -urNp --exclude-from=/home/davej/.exclude linux-902/crypto/mpi/generic_mpi-asm-defs.h linux-903/crypto/mpi/generic_mpi-asm-defs.h
--- linux-902/crypto/mpi/generic_mpi-asm-defs.h
+++ linux-903/crypto/mpi/generic_mpi-asm-defs.h
@@ -0,0 +1,10 @@
+/* This file defines some basic constants for the MPI machinery. We
+ * need to define the types on a per-CPU basis, so it is done with
+ * this file here. */
+#define BYTES_PER_MPI_LIMB (SIZEOF_UNSIGNED_LONG)
+
+
+
+
+
+
diff -urNp --exclude-from=/home/davej/.exclude linux-902/crypto/mpi/generic_mpih-add1.c linux-903/crypto/mpi/generic_mpih-add1.c
--- linux-902/crypto/mpi/generic_mpih-add1.c
+++ linux-903/crypto/mpi/generic_mpih-add1.c
@@ -0,0 +1,62 @@
+/* mpihelp-add_1.c - MPI helper functions
+ * Copyright (C) 1994, 1996, 1997, 1998,
+ * 2000 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ * The GNU MP Library itself is published under the LGPL;
+ * however I decided to publish this code under the plain GPL.
+ */
+
+#include "mpi-internal.h"
+#include "longlong.h"
+
+mpi_limb_t
+mpihelp_add_n( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_ptr_t s2_ptr, mpi_size_t size)
+{
+ mpi_limb_t x, y, cy;
+ mpi_size_t j;
+
+ /* The loop counter and index J goes from -SIZE to -1. This way
+ the loop becomes faster. */
+ j = -size;
+
+ /* Offset the base pointers to compensate for the negative indices. */
+ s1_ptr -= j;
+ s2_ptr -= j;
+ res_ptr -= j;
+
+ cy = 0;
+ do {
+ y = s2_ptr[j];
+ x = s1_ptr[j];
+ y += cy; /* add previous carry to one addend */
+ cy = y < cy; /* get out carry from that addition */
+ y += x; /* add other addend */
+ cy += y < x; /* get out carry from that add, combine */
+ res_ptr[j] = y;
+ } while( ++j );
+
+ return cy;
+}
+
diff -urNp --exclude-from=/home/davej/.exclude linux-902/crypto/mpi/generic_mpih-lshift.c linux-903/crypto/mpi/generic_mpih-lshift.c
--- linux-902/crypto/mpi/generic_mpih-lshift.c
+++ linux-903/crypto/mpi/generic_mpih-lshift.c
@@ -0,0 +1,66 @@
+/* mpihelp-lshift.c - MPI helper functions
+ * Copyright (C) 1994, 1996, 1998, 2001 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ * The GNU MP Library itself is published under the LGPL;
+ * however I decided to publish this code under the plain GPL.
+ */
+
+#include "mpi-internal.h"
+
+/* Shift U (pointed to by UP and USIZE digits long) CNT bits to the left
+ * and store the USIZE least significant digits of the result at WP.
+ * Return the bits shifted out from the most significant digit.
+ *
+ * Argument constraints:
+ * 1. 0 < CNT < BITS_PER_MP_LIMB
+ * 2. If the result is to be written over the input, WP must be >= UP.
+ */
+
+mpi_limb_t
+mpihelp_lshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize,
+ unsigned int cnt)
+{
+ mpi_limb_t high_limb, low_limb;
+ unsigned sh_1, sh_2;
+ mpi_size_t i;
+ mpi_limb_t retval;
+
+ sh_1 = cnt;
+ wp += 1;
+ sh_2 = BITS_PER_MPI_LIMB - sh_1;
+ i = usize - 1;
+ low_limb = up[i];
+ retval = low_limb >> sh_2;
+ high_limb = low_limb;
+ while( --i >= 0 ) {
+ low_limb = up[i];
+ wp[i] = (high_limb << sh_1) | (low_limb >> sh_2);
+ high_limb = low_limb;
+ }
+ wp[i] = high_limb << sh_1;
+
+ return retval;
+}
+
+
diff -urNp --exclude-from=/home/davej/.exclude linux-902/crypto/mpi/generic_mpih-mul1.c linux-903/crypto/mpi/generic_mpih-mul1.c
--- linux-902/crypto/mpi/generic_mpih-mul1.c
+++ linux-903/crypto/mpi/generic_mpih-mul1.c
@@ -0,0 +1,58 @@
+/* mpihelp-mul_1.c - MPI helper functions
+ * Copyright (C) 1994, 1996, 1997, 1998, 2001 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ * The GNU MP Library itself is published under the LGPL;
+ * however I decided to publish this code under the plain GPL.
+ */
+
+#include "mpi-internal.h"
+#include "longlong.h"
+
+mpi_limb_t
+mpihelp_mul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
+ mpi_limb_t s2_limb)
+{
+ mpi_limb_t cy_limb;
+ mpi_size_t j;
+ mpi_limb_t prod_high, prod_low;
+
+ /* The loop counter and index J goes from -S1_SIZE to -1. This way
+ * the loop becomes faster. */
+ j = -s1_size;
+
+ /* Offset the base pointers to compensate for the negative indices. */
+ s1_ptr -= j;
[...6001 lines suppressed...]
+ mpi_ptr_t wp, up;
+ mpi_size_t usize = u->nlimbs;
+ int usign = u->sign;
+
+ if (RESIZE_IF_NEEDED(w, (size_t) usize) < 0)
+ return -ENOMEM;
+
+ wp = w->d;
+ up = u->d;
+ MPN_COPY(wp, up, usize);
+ w->nlimbs = usize;
+ w->nbits = u->nbits;
+ w->flags = u->flags;
+ w->sign = usign;
+ return 0;
+}
+
+
+int mpi_set_ui(MPI w, unsigned long u)
+{
+ if (RESIZE_IF_NEEDED(w, 1) < 0)
+ return -ENOMEM;
+ w->d[0] = u;
+ w->nlimbs = u? 1:0;
+ w->sign = 0;
+ w->nbits = 0;
+ w->flags = 0;
+ return 0;
+}
+
+MPI mpi_alloc_set_ui(unsigned long u)
+{
+ MPI w = mpi_alloc(1);
+ if (!w)
+ return w;
+ w->d[0] = u;
+ w->nlimbs = u? 1:0;
+ w->sign = 0;
+ return w;
+}
+
+
+void mpi_swap(MPI a, MPI b)
+{
+ struct gcry_mpi tmp;
+
+ tmp = *a; *a = *b; *b = tmp;
+}
+
diff -urNp --exclude-from=/home/davej/.exclude linux-902/include/linux/crypto/mpi.h linux-903/include/linux/crypto/mpi.h
--- linux-902/include/linux/crypto/mpi.h
+++ linux-903/include/linux/crypto/mpi.h
@@ -0,0 +1,147 @@
+/* mpi.h - Multi Precision Integers
+ * Copyright (C) 1994, 1996, 1998, 1999,
+ * 2000, 2001 Free Software Foundation, Inc.
+ *
+ * This file is part of GNUPG.
+ *
+ * GNUPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GNUPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ * The GNU MP Library itself is published under the LGPL;
+ * however I decided to publish this code under the plain GPL.
+ */
+
+#ifndef G10_MPI_H
+#define G10_MPI_H
+
+#include <linux/types.h>
+
+/* DSI defines */
+
+#define SHA1_DIGEST_LENGTH 20
+
+/*end of DSI defines */
+
+#define BYTES_PER_MPI_LIMB (BITS_PER_LONG / 8)
+#define BITS_PER_MPI_LIMB BITS_PER_LONG
+
+typedef unsigned long int mpi_limb_t;
+typedef signed long int mpi_limb_signed_t;
+
+struct gcry_mpi {
+ int alloced; /* array size (# of allocated limbs) */
+ int nlimbs; /* number of valid limbs */
+ int nbits; /* the real number of valid bits (info only) */
+ int sign; /* indicates a negative number */
+ unsigned flags; /* bit 0: array must be allocated in secure memory space */
+ /* bit 1: not used */
+ /* bit 2: the limb is a pointer to some m_alloced data */
+ mpi_limb_t *d; /* array with the limbs */
+};
+
+typedef struct gcry_mpi *MPI;
+
+#define MPI_NULL NULL
+
+#define mpi_get_nlimbs(a) ((a)->nlimbs)
+#define mpi_is_neg(a) ((a)->sign)
+
+/*-- mpiutil.c --*/
+MPI mpi_alloc( unsigned nlimbs );
+MPI mpi_alloc_secure( unsigned nlimbs );
+MPI mpi_alloc_like( MPI a );
+void mpi_free( MPI a );
+int mpi_resize( MPI a, unsigned nlimbs );
+int mpi_copy( MPI *copy, const MPI a );
+void mpi_clear( MPI a );
+int mpi_set( MPI w, MPI u);
+int mpi_set_ui( MPI w, ulong u);
+MPI mpi_alloc_set_ui( unsigned long u);
+void mpi_m_check( MPI a );
+void mpi_swap( MPI a, MPI b);
+
+/*-- mpicoder.c --*/
+MPI do_encode_md(const void *sha_buffer, unsigned nbits);
+MPI mpi_read_from_buffer(const void *buffer, unsigned *ret_nread);
+int mpi_fromstr(MPI val, const char *str);
+u32 mpi_get_keyid( MPI a, u32 *keyid );
+void *mpi_get_buffer( MPI a, unsigned *nbytes, int *sign );
+void *mpi_get_secure_buffer( MPI a, unsigned *nbytes, int *sign );
+int mpi_set_buffer( MPI a, const void *buffer, unsigned nbytes, int sign );
+
+#define log_mpidump g10_log_mpidump
+
+/*-- mpi-add.c --*/
+int mpi_add_ui(MPI w, MPI u, ulong v );
+int mpi_add(MPI w, MPI u, MPI v);
+int mpi_addm(MPI w, MPI u, MPI v, MPI m);
+int mpi_sub_ui(MPI w, MPI u, ulong v );
+int mpi_sub( MPI w, MPI u, MPI v);
+int mpi_subm( MPI w, MPI u, MPI v, MPI m);
+
+/*-- mpi-mul.c --*/
+int mpi_mul_ui(MPI w, MPI u, ulong v );
+int mpi_mul_2exp( MPI w, MPI u, ulong cnt);
+int mpi_mul( MPI w, MPI u, MPI v);
+int mpi_mulm( MPI w, MPI u, MPI v, MPI m);
+
+/*-- mpi-div.c --*/
+ulong mpi_fdiv_r_ui( MPI rem, MPI dividend, ulong divisor );
+int mpi_fdiv_r( MPI rem, MPI dividend, MPI divisor );
+int mpi_fdiv_q( MPI quot, MPI dividend, MPI divisor );
+int mpi_fdiv_qr( MPI quot, MPI rem, MPI dividend, MPI divisor );
+int mpi_tdiv_r( MPI rem, MPI num, MPI den);
+int mpi_tdiv_qr( MPI quot, MPI rem, MPI num, MPI den);
+int mpi_tdiv_q_2exp( MPI w, MPI u, unsigned count );
+int mpi_divisible_ui(const MPI dividend, ulong divisor );
+
+/*-- mpi-gcd.c --*/
+int mpi_gcd( MPI g, const MPI a, const MPI b );
+
+/*-- mpi-pow.c --*/
+int mpi_pow( MPI w, MPI u, MPI v);
+int mpi_powm( MPI res, MPI base, MPI exp, MPI mod);
+
+/*-- mpi-mpow.c --*/
+int mpi_mulpowm( MPI res, MPI *basearray, MPI *exparray, MPI mod);
+
+/*-- mpi-cmp.c --*/
+int mpi_cmp_ui( MPI u, ulong v );
+int mpi_cmp( MPI u, MPI v );
+
+/*-- mpi-scan.c --*/
+int mpi_getbyte( MPI a, unsigned idx );
+void mpi_putbyte( MPI a, unsigned idx, int value );
+unsigned mpi_trailing_zeros( MPI a );
+
+/*-- mpi-bit.c --*/
+void mpi_normalize( MPI a );
+unsigned mpi_get_nbits( MPI a );
+int mpi_test_bit( MPI a, unsigned n );
+int mpi_set_bit( MPI a, unsigned n );
+int mpi_set_highbit( MPI a, unsigned n );
+void mpi_clear_highbit( MPI a, unsigned n );
+void mpi_clear_bit( MPI a, unsigned n );
+int mpi_rshift( MPI x, MPI a, unsigned n );
+
+/*-- mpi-inv.c --*/
+int mpi_invm( MPI x, MPI u, MPI v );
+
+
+#endif /*G10_MPI_H*/
linux-2.6-modsign-script.patch:
Makefile | 27 +
mod-extract.c | 900 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
modsign.sh | 57 +++
3 files changed, 984 insertions(+)
--- NEW FILE linux-2.6-modsign-script.patch ---
diff -urNp --exclude-from=/home/davej/.exclude linux-903/scripts/modsign/Makefile linux-904/scripts/modsign/Makefile
--- linux-903/scripts/modsign/Makefile
+++ linux-904/scripts/modsign/Makefile
@@ -0,0 +1,27 @@
+# Set the following to `true' to make a debuggable build.
+# Leave this set to `false' for production use.
+DEBUG = true
+
+
+ROOT = mod-extract
+VERSION = 0.1
+INSTALL_DIR = /usr/local/bin
+RELEASE_NAME = $(ROOT)-$(VERSION)
+
+CC = gcc
+
+INCLUDES =
+CFLAGS = -g -O -Wall
+
+OBJS = mod-extract.o
+
+all: $(ROOT)
+
+$(ROOT): $(OBJS)
+ $(CC) $(LDFLAGS) -o $(ROOT) $(OBJS) -lbfd -liberty $(LIB_OBJS) $(ARCH_LIB_OBJS)
+
+.c.o:
+ $(CC) $(INCLUDES) $(CFLAGS) -c $< -o $@
+
+clean:
+ -rm $(OBJS) $(ROOT)
diff -urNp --exclude-from=/home/davej/.exclude linux-903/scripts/modsign/mod-extract.c linux-904/scripts/modsign/mod-extract.c
--- linux-903/scripts/modsign/mod-extract.c
+++ linux-904/scripts/modsign/mod-extract.c
@@ -0,0 +1,900 @@
+/* mod-extract.c: module extractor for signing
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells at redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <elf.h>
+#include <asm/byteorder.h>
+
+void extract_elf64(void *buffer, size_t size, Elf64_Ehdr *hdr);
+void extract_elf32(void *buffer, size_t size, Elf32_Ehdr *hdr);
+
+struct byteorder {
+ uint16_t (*get16)(const uint16_t *);
+ uint32_t (*get32)(const uint32_t *);
+ uint64_t (*get64)(const uint64_t *);
+ void (*set16)(uint16_t *, uint16_t);
+ void (*set32)(uint32_t *, uint32_t);
+ void (*set64)(uint64_t *, uint64_t);
+};
+
+uint16_t get16_le(const uint16_t *p) { return __le16_to_cpu(*p); }
+uint32_t get32_le(const uint32_t *p) { return __le32_to_cpu(*p); }
+uint64_t get64_le(const uint64_t *p) { return __le64_to_cpu(*p); }
+uint16_t get16_be(const uint16_t *p) { return __be16_to_cpu(*p); }
+uint32_t get32_be(const uint32_t *p) { return __be32_to_cpu(*p); }
+uint64_t get64_be(const uint64_t *p) { return __be64_to_cpu(*p); }
+
+void set16_le(uint16_t *p, uint16_t n) { *p = __cpu_to_le16(n); }
+void set32_le(uint32_t *p, uint32_t n) { *p = __cpu_to_le32(n); }
+void set64_le(uint64_t *p, uint64_t n) { *p = __cpu_to_le64(n); }
+void set16_be(uint16_t *p, uint16_t n) { *p = __cpu_to_be16(n); }
+void set32_be(uint32_t *p, uint32_t n) { *p = __cpu_to_be32(n); }
+void set64_be(uint64_t *p, uint64_t n) { *p = __cpu_to_be64(n); }
+
+const struct byteorder byteorder_le = {
+ get16_le, get32_le, get64_le,
+ set16_le, set32_le, set64_le
+};
+const struct byteorder byteorder_be = {
+ get16_be, get32_be, get64_be,
+ set16_be, set32_be, set64_be
+};
+const struct byteorder *order;
+
+uint16_t get16(const uint16_t *p) { return order->get16(p); }
+uint32_t get32(const uint32_t *p) { return order->get32(p); }
+uint64_t get64(const uint64_t *p) { return order->get64(p); }
+void set16(uint16_t *p, uint16_t n) { order->set16(p, n); }
+void set32(uint32_t *p, uint32_t n) { order->set32(p, n); }
+void set64(uint64_t *p, uint64_t n) { order->set64(p, n); }
+
+FILE *outfd;
+uint8_t csum, xcsum;
+
+void write_out(const void *data, size_t size)
+{
+ const uint8_t *p = data;
+ size_t loop;
+
+ for (loop = 0; loop < size; loop++) {
+ csum += p[loop];
+ xcsum += p[loop];
+ }
+
+ if (fwrite(data, 1, size, outfd) != size) {
+ perror("write");
+ exit(1);
+ }
+}
+
+#define write_out_val(VAL) write_out(&(VAL), sizeof(VAL))
+
+int is_verbose;
+
+void verbose(const char *fmt, ...) __attribute__((format(printf,1,2)));
+void verbose(const char *fmt, ...)
+{
+ va_list va;
+
+ if (is_verbose) {
+ va_start(va, fmt);
+ vprintf(fmt, va);
+ va_end(va);
+ }
+}
+
+void usage(void) __attribute__((noreturn));
+void usage(void)
+{
+ fprintf(stderr, "Usage: mod-extract [-v] <modulefile> <extractfile>\n");
+ exit(2);
+}
+
+/*****************************************************************************/
+/*
+ *
+ */
+int main(int argc, char **argv)
+{
+ struct stat st;
+ Elf32_Ehdr *hdr32;
+ Elf64_Ehdr *hdr64;
+ size_t len;
+ void *buffer;
+ int fd, be, b64;
+
+ while (argc > 1 && strcmp("-v", argv[1]) == 0) {
+ argv++;
+ argc--;
+ is_verbose++;
+ }
+
+ if (argc != 3)
+ usage();
+
+ /* map the module into memory */
+ fd = open(argv[1], O_RDONLY);
+ if (fd < 0) {
+ perror("open input");
+ exit(1);
+ }
+
+ if (fstat(fd, &st) < 0) {
+ perror("fstat");
+ exit(1);
+ }
+
+ len = st.st_size;
+
+ buffer = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
+ if (buffer == MAP_FAILED) {
+ perror("mmap");
+ exit(1);
+ }
+
+ if (close(fd) < 0) {
+ perror("close input");
+ exit(1);
+ }
+
+ /* check it's an ELF object */
+ hdr32 = buffer;
+ hdr64 = buffer;
+
+ if (hdr32->e_ident[EI_MAG0] != ELFMAG0 ||
+ hdr32->e_ident[EI_MAG1] != ELFMAG1 ||
+ hdr32->e_ident[EI_MAG2] != ELFMAG2 ||
+ hdr32->e_ident[EI_MAG3] != ELFMAG3
+ ) {
+ fprintf(stderr, "Module does not appear to be ELF\n");
+ exit(3);
+ }
+
+ /* determine endianness and word size */
+ b64 = (hdr32->e_ident[EI_CLASS] == ELFCLASS64);
+ be = (hdr32->e_ident[EI_DATA] == ELFDATA2MSB);
+ order = be ? &byteorder_be : &byteorder_le;
+
+ verbose("Module is %s-bit %s-endian\n",
+ b64 ? "64" : "32",
+ be ? "big" : "little");
+
+ /* open the output file */
+ outfd = fopen(argv[2], "w");
+ if (!outfd) {
+ perror("open output");
+ exit(1);
+ }
+
+ /* perform the extraction */
+ if (b64)
+ extract_elf64(buffer, len, hdr64);
+ else
+ extract_elf32(buffer, len, hdr32);
+
+ /* done */
+ if (fclose(outfd) == EOF) {
+ perror("close output");
+ exit(1);
+ }
+
+ return 0;
+
+} /* end main() */
+
+/*****************************************************************************/
+/*
+ * extract a RELA table
+ * - need to canonicalise the entries in case section addition/removal has
+ * rearranged the symbol table and the section table
+ */
+void extract_elf64_rela(const void *buffer, int secix, int targetix,
+ const Elf64_Rela *relatab, size_t nrels,
+ const Elf64_Sym *symbols, size_t nsyms,
+ const Elf64_Shdr *sections, size_t nsects, int *canonmap,
+ const char *strings, size_t nstrings,
+ const char *sh_name)
+{
+ struct {
+ uint64_t r_offset;
+ uint64_t r_addend;
+ uint64_t st_value;
+ uint64_t st_size;
+ uint32_t r_type;
+ uint16_t st_shndx;
+ uint8_t st_info;
+ uint8_t st_other;
+
+ } __attribute__((packed)) relocation;
+
+ const Elf64_Sym *symbol;
+ size_t loop;
+
+ /* contribute the relevant bits from a join of { RELA, SYMBOL, SECTION } */
+ for (loop = 0; loop < nrels; loop++) {
+ Elf64_Section st_shndx;
+ Elf64_Xword r_info;
+
+ /* decode the relocation */
+ r_info = get64(&relatab[loop].r_info);
+ relocation.r_offset = relatab[loop].r_offset;
+ relocation.r_addend = relatab[loop].r_addend;
+ set32(&relocation.r_type, ELF64_R_TYPE(r_info));
+
+ if (ELF64_R_SYM(r_info) >= nsyms) {
+ fprintf(stderr, "Invalid symbol ID %lx in relocation %zu\n",
+ ELF64_R_SYM(r_info), loop);
+ exit(1);
+ }
+
+ /* decode the symbol referenced by the relocation */
+ symbol = &symbols[ELF64_R_SYM(r_info)];
+ relocation.st_info = symbol->st_info;
+ relocation.st_other = symbol->st_other;
+ relocation.st_value = symbol->st_value;
+ relocation.st_size = symbol->st_size;
+ relocation.st_shndx = symbol->st_shndx;
+ st_shndx = get16(&symbol->st_shndx);
+
+ /* canonicalise the section used by the symbol */
+ if (st_shndx > SHN_UNDEF && st_shndx < nsects)
+ set16(&relocation.st_shndx, canonmap[st_shndx]);
+
+ write_out_val(relocation);
+
+ /* undefined symbols must be named if referenced */
+ if (st_shndx == SHN_UNDEF) {
+ const char *name = strings + get32(&symbol->st_name);
+ write_out(name, strlen(name) + 1);
+ }
+ }
+
+ verbose("%02x %4d %s [canon]\n", csum, secix, sh_name);
+
+} /* end extract_elf64_rela() */
+
+/*****************************************************************************/
+/*
+ * extract a REL table
+ * - need to canonicalise the entries in case section addition/removal has
+ * rearranged the symbol table and the section table
+ */
+void extract_elf64_rel(const void *buffer, int secix, int targetix,
+ const Elf64_Rel *relatab, size_t nrels,
+ const Elf64_Sym *symbols, size_t nsyms,
+ const Elf64_Shdr *sections, size_t nsects, int *canonmap,
+ const char *strings, size_t nstrings,
+ const char *sh_name)
+{
+ struct {
+ uint64_t r_offset;
+ uint64_t st_value;
+ uint64_t st_size;
+ uint32_t r_type;
+ uint16_t st_shndx;
+ uint8_t st_info;
+ uint8_t st_other;
+
+ } __attribute__((packed)) relocation;
+
+ const Elf64_Sym *symbol;
+ size_t loop;
+
+ /* contribute the relevant bits from a join of { RELA, SYMBOL, SECTION } */
+ for (loop = 0; loop < nrels; loop++) {
+ Elf64_Section st_shndx;
+ Elf64_Xword r_info;
+
+ /* decode the relocation */
+ r_info = get64(&relatab[loop].r_info);
+ relocation.r_offset = relatab[loop].r_offset;
+ set32(&relocation.r_type, ELF64_R_TYPE(r_info));
+
+ if (ELF64_R_SYM(r_info) >= nsyms) {
+ fprintf(stderr, "Invalid symbol ID %lx in relocation %zi\n",
+ ELF64_R_SYM(r_info), loop);
+ exit(1);
+ }
+
+ /* decode the symbol referenced by the relocation */
+ symbol = &symbols[ELF64_R_SYM(r_info)];
+ relocation.st_info = symbol->st_info;
+ relocation.st_other = symbol->st_other;
+ relocation.st_value = symbol->st_value;
+ relocation.st_size = symbol->st_size;
+ relocation.st_shndx = symbol->st_shndx;
+ st_shndx = get16(&symbol->st_shndx);
+
+ /* canonicalise the section used by the symbol */
+ if (st_shndx > SHN_UNDEF && st_shndx < nsects)
+ set16(&relocation.st_shndx, canonmap[st_shndx]);
+
+ write_out_val(relocation);
+
+ /* undefined symbols must be named if referenced */
+ if (st_shndx == SHN_UNDEF) {
+ const char *name = strings + get32(&symbol->st_name);
+ write_out(name, strlen(name) + 1);
+ }
+ }
+
+ verbose("%02x %4d %s [canon]\n", csum, secix, sh_name);
+
+} /* end extract_elf64_rel() */
+
+/*****************************************************************************/
+/*
+ * extract the data from a 64-bit module
+ */
+void extract_elf64(void *buffer, size_t len, Elf64_Ehdr *hdr)
+{
+ const Elf64_Sym *symbols;
+ Elf64_Shdr *sections;
+ const char *secstrings, *strings;
+ size_t nsyms, nstrings;
+ int loop, shnum, *canonlist, *canonmap, canon, changed, tmp;
+
+ sections = buffer + get64(&hdr->e_shoff);
+ secstrings = buffer + get64(§ions[get16(&hdr->e_shstrndx)].sh_offset);
+ shnum = get16(&hdr->e_shnum);
+
+ /* find the symbol table and the string table and produce a list of
+ * index numbers of sections that contribute to the kernel's module
+ * image
+ */
+ canonlist = calloc(sizeof(int), shnum * 2);
+ if (!canonlist) {
+ perror("calloc");
+ exit(1);
+ }
+ canonmap = canonlist + shnum;
+ canon = 0;
+
+ symbols = NULL;
+ strings = NULL;
+
+ for (loop = 1; loop < shnum; loop++) {
+ const char *sh_name = secstrings + get32(§ions[loop].sh_name);
+ Elf64_Word sh_type = get32(§ions[loop].sh_type);
+ Elf64_Xword sh_size = get64(§ions[loop].sh_size);
+ Elf64_Xword sh_flags = get64(§ions[loop].sh_flags);
+ Elf64_Off sh_offset = get64(§ions[loop].sh_offset);
+ void *data = buffer + sh_offset;
+
+ /* quick sanity check */
+ if (sh_type != SHT_NOBITS && len < sh_offset + sh_size) {
+ fprintf(stderr, "Section goes beyond EOF\n");
+ exit(3);
+ }
+
+ /* we only need to canonicalise allocatable sections */
+ if (sh_flags & SHF_ALLOC)
+ canonlist[canon++] = loop;
+
+ /* keep track of certain special sections */
+ switch (sh_type) {
+ case SHT_SYMTAB:
+ if (strcmp(sh_name, ".symtab") == 0) {
+ symbols = data;
+ nsyms = sh_size / sizeof(Elf64_Sym);
+ }
+ break;
+
+ case SHT_STRTAB:
+ if (strcmp(sh_name, ".strtab") == 0) {
+ strings = data;
+ nstrings = sh_size;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (!symbols) {
+ fprintf(stderr, "Couldn't locate symbol table\n");
+ exit(3);
+ }
+
+ if (!strings) {
+ fprintf(stderr, "Couldn't locate strings table\n");
+ exit(3);
+ }
+
+ /* canonicalise the index numbers of the contributing section */
+ do {
+ changed = 0;
+
+ for (loop = 0; loop < canon - 1; loop++) {
+ const char *x = secstrings + get32(§ions[canonlist[loop + 0]].sh_name);
+ const char *y = secstrings + get32(§ions[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 = 1;
+ }
+ }
+
+ } while(changed);
+
+ for (loop = 0; loop < canon; loop++)
+ canonmap[canonlist[loop]] = loop + 1;
+
+ if (is_verbose > 1) {
+ printf("\nSection canonicalisation map:\n");
+ for (loop = 1; loop < shnum; loop++) {
+ const char *x = secstrings + get32(§ions[loop].sh_name);
+ printf("%4d %s\n", canonmap[loop], x);
+ }
+
+ printf("\nAllocated section list in canonical order:\n");
+ for (loop = 0; loop < canon; loop++) {
+ const char *x = secstrings + get32(§ions[canonlist[loop]].sh_name);
+ printf("%4d %s\n", canonlist[loop], x);
+ }
+ }
+
+ memset(canonlist, 0, sizeof(int) * shnum);
+
+ /* iterate through the section table looking for sections we want to
+ * contribute to the signature */
+ verbose("\n");
+ verbose("FILE POS CS SECT NAME\n");
+ verbose("======== == ==== ==============================\n");
+
+ for (loop = 1; loop < shnum; loop++) {
+ const char *sh_name = secstrings + get32(§ions[loop].sh_name);
+ Elf64_Word sh_type = get32(§ions[loop].sh_type);
+ Elf64_Xword sh_size = get64(§ions[loop].sh_size);
+ Elf64_Xword sh_flags = get64(§ions[loop].sh_flags);
+ Elf64_Word sh_info = get32(§ions[loop].sh_info);
+ Elf64_Off sh_offset = get64(§ions[loop].sh_offset);
+ void *data = buffer + sh_offset;
+
+ csum = 0;
+
+ /* include canonicalised relocation sections */
+ if (sh_type == SHT_REL || sh_type == SHT_RELA) {
+ if (sh_info <= 0 && sh_info >= hdr->e_shnum) {
+ fprintf(stderr,
+ "Invalid ELF - REL/RELA sh_info does"
+ " not refer to a valid section\n");
+ exit(3);
+ }
+
+ if (canonlist[sh_info]) {
+ Elf32_Word xsh_info;
+
+ verbose("%08lx ", ftell(outfd));
+
+ set32(&xsh_info, canonmap[sh_info]);
+
+ /* write out selected portions of the section
+ * header */
+ write_out(sh_name, strlen(sh_name));
+ write_out_val(sections[loop].sh_type);
+ write_out_val(sections[loop].sh_flags);
+ write_out_val(sections[loop].sh_size);
+ write_out_val(sections[loop].sh_addralign);
+ write_out_val(xsh_info);
+
+ if (sh_type == SHT_RELA)
+ extract_elf64_rela(buffer, loop, sh_info,
+ data, sh_size / sizeof(Elf64_Rela),
+ symbols, nsyms,
+ sections, shnum, canonmap,
+ strings, nstrings,
+ sh_name);
+ else
+ extract_elf64_rel(buffer, loop, sh_info,
+ data, sh_size / sizeof(Elf64_Rel),
+ symbols, nsyms,
+ sections, shnum, canonmap,
+ strings, nstrings,
+ sh_name);
+ }
+
+ continue;
+ }
+
+ /* include allocatable loadable sections */
+ if (sh_type != SHT_NOBITS && sh_flags & SHF_ALLOC)
+ goto include_section;
+
+ /* not this section */
+ continue;
+
+ include_section:
+ verbose("%08lx ", ftell(outfd));
+
+ /* write out selected portions of the section header */
+ write_out(sh_name, strlen(sh_name));
+ write_out_val(sections[loop].sh_type);
+ write_out_val(sections[loop].sh_flags);
+ write_out_val(sections[loop].sh_size);
+ write_out_val(sections[loop].sh_addralign);
+
+ /* write out the section data */
+ write_out(data, sh_size);
+
+ verbose("%02x %4d %s\n", csum, loop, sh_name);
+
+ /* note the section has been written */
+ canonlist[loop] = 1;
+ }
+
+ verbose("%08lx (%lu bytes csum 0x%02x)\n",
+ ftell(outfd), ftell(outfd), xcsum);
+
+} /* end extract_elf64() */
+
+/*****************************************************************************/
+/*
+ * extract a RELA table
+ * - need to canonicalise the entries in case section addition/removal has
+ * rearranged the symbol table and the section table
+ */
+void extract_elf32_rela(const void *buffer, int secix, int targetix,
+ const Elf32_Rela *relatab, size_t nrels,
+ const Elf32_Sym *symbols, size_t nsyms,
+ const Elf32_Shdr *sections, size_t nsects, int *canonmap,
+ const char *strings, size_t nstrings,
+ const char *sh_name)
+{
+ struct {
+ uint32_t r_offset;
+ uint32_t r_addend;
+ uint32_t st_value;
+ uint32_t st_size;
+ uint16_t st_shndx;
+ uint8_t r_type;
+ uint8_t st_info;
+ uint8_t st_other;
+
+ } __attribute__((packed)) relocation;
+
+ const Elf32_Sym *symbol;
+ size_t loop;
+
+ /* contribute the relevant bits from a join of { RELA, SYMBOL, SECTION } */
+ for (loop = 0; loop < nrels; loop++) {
+ Elf32_Section st_shndx;
+ Elf32_Word r_info;
+
+ /* decode the relocation */
+ r_info = get32(&relatab[loop].r_info);
+ relocation.r_offset = relatab[loop].r_offset;
+ relocation.r_addend = relatab[loop].r_addend;
+ relocation.r_type = ELF32_R_TYPE(r_info);
+
+ if (ELF32_R_SYM(r_info) >= nsyms) {
+ fprintf(stderr, "Invalid symbol ID %x in relocation %zu\n",
+ ELF32_R_SYM(r_info), loop);
+ exit(1);
+ }
+
+ /* decode the symbol referenced by the relocation */
+ symbol = &symbols[ELF32_R_SYM(r_info)];
+ relocation.st_info = symbol->st_info;
+ relocation.st_other = symbol->st_other;
+ relocation.st_value = symbol->st_value;
+ relocation.st_size = symbol->st_size;
+ relocation.st_shndx = symbol->st_shndx;
+ st_shndx = get16(&symbol->st_shndx);
+
+ /* canonicalise the section used by the symbol */
+ if (st_shndx > SHN_UNDEF && st_shndx < nsects)
+ set16(&relocation.st_shndx, canonmap[st_shndx]);
+
+ write_out_val(relocation);
+
+ /* undefined symbols must be named if referenced */
+ if (st_shndx == SHN_UNDEF) {
+ const char *name = strings + get32(&symbol->st_name);
+ write_out(name, strlen(name) + 1);
+ }
+ }
+
+ verbose("%02x %4d %s [canon]\n", csum, secix, sh_name);
+
+} /* end extract_elf32_rela() */
+
+/*****************************************************************************/
+/*
+ * extract a REL table
+ * - need to canonicalise the entries in case section addition/removal has
+ * rearranged the symbol table and the section table
+ */
+void extract_elf32_rel(const void *buffer, int secix, int targetix,
+ const Elf32_Rel *relatab, size_t nrels,
+ const Elf32_Sym *symbols, size_t nsyms,
+ const Elf32_Shdr *sections, size_t nsects, int *canonmap,
+ const char *strings, size_t nstrings,
+ const char *sh_name)
+{
+ struct {
+ uint32_t r_offset;
+ uint32_t st_value;
+ uint32_t st_size;
+ uint16_t st_shndx;
+ uint8_t r_type;
+ uint8_t st_info;
+ uint8_t st_other;
+
+ } __attribute__((packed)) relocation;
+
+ const Elf32_Sym *symbol;
+ size_t loop;
+
+ /* contribute the relevant bits from a join of { RELA, SYMBOL, SECTION } */
+ for (loop = 0; loop < nrels; loop++) {
+ Elf32_Section st_shndx;
+ Elf32_Word r_info;
+
+ /* decode the relocation */
+ r_info = get32(&relatab[loop].r_info);
+ relocation.r_offset = relatab[loop].r_offset;
+ relocation.r_type = ELF32_R_TYPE(r_info);
+
+ if (ELF32_R_SYM(r_info) >= nsyms) {
+ fprintf(stderr, "Invalid symbol ID %x in relocation %zu\n",
+ ELF32_R_SYM(r_info), loop);
+ exit(1);
+ }
+
+ /* decode the symbol referenced by the relocation */
+ symbol = &symbols[ELF32_R_SYM(r_info)];
+ relocation.st_info = symbol->st_info;
+ relocation.st_other = symbol->st_other;
+ relocation.st_value = symbol->st_value;
+ relocation.st_size = symbol->st_size;
+ relocation.st_shndx = symbol->st_shndx;
+ st_shndx = get16(&symbol->st_shndx);
+
+ /* canonicalise the section used by the symbol */
+ if (st_shndx > SHN_UNDEF && st_shndx < nsects)
+ set16(&relocation.st_shndx, canonmap[st_shndx]);
+
+ write_out_val(relocation);
+
+ /* undefined symbols must be named if referenced */
+ if (st_shndx == SHN_UNDEF) {
+ const char *name = strings + get32(&symbol->st_name);
+ write_out(name, strlen(name) + 1);
+ }
+ }
+
+ verbose("%02x %4d %s [canon]\n", csum, secix, sh_name);
+
+} /* end extract_elf32_rel() */
+
+/*****************************************************************************/
+/*
+ * extract the data from a 32-bit module
+ */
+void extract_elf32(void *buffer, size_t len, Elf32_Ehdr *hdr)
+{
+ const Elf32_Sym *symbols;
+ Elf32_Shdr *sections;
+ const char *secstrings, *strings;
+ size_t nsyms, nstrings;
+ int loop, shnum, *canonlist, *canonmap, canon, changed, tmp;
+
+ sections = buffer + get32(&hdr->e_shoff);
+ secstrings = buffer + get32(§ions[get16(&hdr->e_shstrndx)].sh_offset);
+ shnum = get16(&hdr->e_shnum);
+
+ /* find the symbol table and the string table and produce a list of
+ * index numbers of sections that contribute to the kernel's module
+ * image
+ */
+ canonlist = calloc(sizeof(int), shnum * 2);
+ if (!canonlist) {
+ perror("calloc");
+ exit(1);
+ }
+ canonmap = canonlist + shnum;
+ canon = 0;
+
+ symbols = NULL;
+ strings = NULL;
+
+ for (loop = 1; loop < shnum; loop++) {
+ const char *sh_name = secstrings + get32(§ions[loop].sh_name);
+ Elf32_Word sh_type = get32(§ions[loop].sh_type);
+ Elf32_Xword sh_size = get32(§ions[loop].sh_size);
+ Elf32_Xword sh_flags = get32(§ions[loop].sh_flags);
+ Elf32_Off sh_offset = get32(§ions[loop].sh_offset);
+ void *data = buffer + sh_offset;
+
+ /* quick sanity check */
+ if (sh_type != SHT_NOBITS && len < sh_offset + sh_size) {
+ fprintf(stderr, "Section goes beyond EOF\n");
+ exit(3);
+ }
+
+ /* we only need to canonicalise allocatable sections */
+ if (sh_flags & SHF_ALLOC)
+ canonlist[canon++] = loop;
+
+ /* keep track of certain special sections */
+ switch (sh_type) {
+ case SHT_SYMTAB:
+ if (strcmp(sh_name, ".symtab") == 0) {
+ symbols = data;
+ nsyms = sh_size / sizeof(Elf32_Sym);
+ }
+ break;
+
+ case SHT_STRTAB:
+ if (strcmp(sh_name, ".strtab") == 0) {
+ strings = data;
+ nstrings = sh_size;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (!symbols) {
+ fprintf(stderr, "Couldn't locate symbol table\n");
+ exit(3);
+ }
+
+ if (!strings) {
+ fprintf(stderr, "Couldn't locate strings table\n");
+ exit(3);
+ }
+
+ /* canonicalise the index numbers of the contributing section */
+ do {
+ changed = 0;
+
+ for (loop = 0; loop < canon - 1; loop++) {
+ const char *x = secstrings + get32(§ions[canonlist[loop + 0]].sh_name);
+ const char *y = secstrings + get32(§ions[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 = 1;
+ }
+ }
+
+ } while(changed);
+
+ for (loop = 0; loop < canon; loop++)
+ canonmap[canonlist[loop]] = loop + 1;
+
+ if (is_verbose > 1) {
+ printf("\nSection canonicalisation map:\n");
+ for (loop = 1; loop < shnum; loop++) {
+ const char *x = secstrings + get32(§ions[loop].sh_name);
+ printf("%4d %s\n", canonmap[loop], x);
+ }
+
+ printf("\nAllocated section list in canonical order:\n");
+ for (loop = 0; loop < canon; loop++) {
+ const char *x = secstrings + get32(§ions[canonlist[loop]].sh_name);
+ printf("%4d %s\n", canonlist[loop], x);
+ }
+ }
+
+ memset(canonlist, 0, sizeof(int) * shnum);
+
+ /* iterate through the section table looking for sections we want to
+ * contribute to the signature */
+ verbose("\n");
+ verbose("FILE POS CS SECT NAME\n");
+ verbose("======== == ==== ==============================\n");
+
+ for (loop = 1; loop < shnum; loop++) {
+ const char *sh_name = secstrings + get32(§ions[loop].sh_name);
+ Elf32_Word sh_type = get32(§ions[loop].sh_type);
+ Elf32_Xword sh_size = get32(§ions[loop].sh_size);
+ Elf32_Xword sh_flags = get32(§ions[loop].sh_flags);
+ Elf32_Word sh_info = get32(§ions[loop].sh_info);
+ Elf32_Off sh_offset = get32(§ions[loop].sh_offset);
+ void *data = buffer + sh_offset;
+
+ csum = 0;
+
+ /* quick sanity check */
+ if (sh_type != SHT_NOBITS && len < sh_offset + sh_size) {
+ fprintf(stderr, "section goes beyond EOF\n");
+ exit(3);
+ }
+
+ /* include canonicalised relocation sections */
+ if (sh_type == SHT_REL || sh_type == SHT_RELA) {
+ if (sh_info <= 0 && sh_info >= hdr->e_shnum) {
+ fprintf(stderr,
+ "Invalid ELF - REL/RELA sh_info does"
+ " not refer to a valid section\n");
+ exit(3);
+ }
+
+ if (canonlist[sh_info]) {
+ Elf32_Word xsh_info;
+
+ verbose("%08lx ", ftell(outfd));
+
+ set32(&xsh_info, canonmap[sh_info]);
+
+ /* write out selected portions of the section header */
+ write_out(sh_name, strlen(sh_name));
+ write_out_val(sections[loop].sh_type);
+ write_out_val(sections[loop].sh_flags);
+ write_out_val(sections[loop].sh_size);
+ write_out_val(sections[loop].sh_addralign);
+ write_out_val(xsh_info);
+
+ if (sh_type == SHT_RELA)
+ extract_elf32_rela(buffer, loop, sh_info,
+ data, sh_size / sizeof(Elf32_Rela),
+ symbols, nsyms,
+ sections, shnum, canonmap,
+ strings, nstrings,
+ sh_name);
+ else
+ extract_elf32_rel(buffer, loop, sh_info,
+ data, sh_size / sizeof(Elf32_Rel),
+ symbols, nsyms,
+ sections, shnum, canonmap,
+ strings, nstrings,
+ sh_name);
+ }
+
+ continue;
+ }
+
+ /* include allocatable loadable sections */
+ if (sh_type != SHT_NOBITS && sh_flags & SHF_ALLOC)
+ goto include_section;
+
+ /* not this section */
+ continue;
+
+ include_section:
+ verbose("%08lx ", ftell(outfd));
+
+ /* write out selected portions of the section header */
+ write_out(sh_name, strlen(sh_name));
+ write_out_val(sections[loop].sh_type);
+ write_out_val(sections[loop].sh_flags);
+ write_out_val(sections[loop].sh_size);
+ write_out_val(sections[loop].sh_addralign);
+
+ /* write out the section data */
+ write_out(data, sh_size);
+
+ verbose("%02x %4d %s\n", csum, loop, sh_name);
+
+ /* note the section has been written */
+ canonlist[loop] = 1;
+ }
+
+ verbose("%08lx (%lu bytes csum 0x%02x)\n",
+ ftell(outfd), ftell(outfd), xcsum);
+
+} /* end extract_elf32() */
diff -urNp --exclude-from=/home/davej/.exclude linux-903/scripts/modsign/modsign.sh linux-904/scripts/modsign/modsign.sh
--- linux-903/scripts/modsign/modsign.sh
+++ linux-904/scripts/modsign/modsign.sh
@@ -0,0 +1,57 @@
+#!/bin/bash
+###############################################################################
+#
+# Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+# Written by David Howells (dhowells at redhat.com)
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+###############################################################################
+
+verbose=
+
+if [ $# -gt 1 -a "x$1" = "x-v" ]
+ then
+ verbose=-v
+ shift
+fi
+
+if [ $# = 0 ]
+ then
+ echo
+ echo "usage: $0 [-v] <module_to_sign> [<key_name>]"
+ echo
+ exit 1
+fi
+
+module=$1
+
+if [ -z "$KEYFLAGS" ]
+ then
+ KEYFLAGS="--no-default-keyring --secret-keyring ../kernel.sec --keyring ../kernel.pub"
+fi
+
+if [ $# -eq 2 ]
+ then
+ KEYFLAGS="$KEYFLAGS --default-key $2"
+fi
+
+# strip out only the sections that we care about
+scripts/modsign/mod-extract $verbose $module $module.out || exit $?
+
+# sign the sections
+gpg --no-greeting $KEYFLAGS -b $module.out || exit $?
+
+# check the signature
+#gpg --verify rxrpc.ko.out.sig rxrpc.ko.out
+
+## sha1 the sections
+#sha1sum $module.out | awk "{print \$1}" > $module.sha1
+
+# add the encrypted data to the module
+objcopy --add-section .module_sig=$module.out.sig $module $module.signed || exit $?
+objcopy --set-section-flags .module_sig=alloc $module.signed || exit $?
+rm -f $module.out*
linux-2.6-module_version.patch:
linux-1720/drivers/block/DAC960.c | 1 +
linux-1720/drivers/block/cpqarray.c | 1 +
linux-1720/drivers/message/fusion/mptbase.c | 1 +
linux-1720/drivers/net/b44.c | 1 +
linux-1720/drivers/net/ns83820.c | 1 +
linux-1720/drivers/net/tg3.c | 1 +
linux-1720/drivers/scsi/gdth.c | 1 +
linux-2.6.13/drivers/block/cciss.c | 1 +
8 files changed, 8 insertions(+)
--- NEW FILE linux-2.6-module_version.patch ---
--- linux-2.6.13/drivers/block/cciss.c~ 2005-09-16 04:56:37.000000000 -0400
+++ linux-2.6.13/drivers/block/cciss.c 2005-09-16 04:56:47.000000000 -0400
@@ -56,6 +56,7 @@ MODULE_DESCRIPTION("Driver for HP Contro
MODULE_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400"
" SA6i P600 P800 P400 P400i E200 E200i");
MODULE_LICENSE("GPL");
+MODULE_VERSION("2.6.8");
#include "cciss_cmd.h"
#include "cciss.h"
diff -urNp --exclude-from=/home/davej/.exclude linux-1700/drivers/block/cpqarray.c linux-1720/drivers/block/cpqarray.c
--- linux-1700/drivers/block/cpqarray.c
+++ linux-1720/drivers/block/cpqarray.c
@@ -52,6 +52,7 @@
/* Original author Chris Frantz - Compaq Computer Corporation */
MODULE_AUTHOR("Compaq Computer Corporation");
MODULE_DESCRIPTION("Driver for Compaq Smart2 Array Controllers version 2.6.0");
+MODULE_VERSION("2.6.0");
MODULE_LICENSE("GPL");
#include "cpqarray.h"
diff -urNp --exclude-from=/home/davej/.exclude linux-1700/drivers/block/DAC960.c linux-1720/drivers/block/DAC960.c
--- linux-1700/drivers/block/DAC960.c
+++ linux-1720/drivers/block/DAC960.c
@@ -7109,3 +7109,4 @@ module_init(DAC960_init_module);
module_exit(DAC960_cleanup_module);
MODULE_LICENSE("GPL");
+MODULE_VERSION(DAC960_DriverVersion);
diff -urNp --exclude-from=/home/davej/.exclude linux-1700/drivers/message/fusion/mptbase.c linux-1720/drivers/message/fusion/mptbase.c
--- linux-1700/drivers/message/fusion/mptbase.c
+++ linux-1720/drivers/message/fusion/mptbase.c
@@ -119,6 +119,7 @@
MODULE_AUTHOR(MODULEAUTHOR);
MODULE_DESCRIPTION(my_NAME);
MODULE_LICENSE("GPL");
+MODULE_VERSION(MPT_LINUX_VERSION_COMMON);
/*
* cmd line parameters
diff -urNp --exclude-from=/home/davej/.exclude linux-1700/drivers/net/b44.c linux-1720/drivers/net/b44.c
--- linux-1700/drivers/net/b44.c
+++ linux-1720/drivers/net/b44.c
@@ -85,6 +85,7 @@ MODULE_VERSION(DRV_MODULE_VERSION);
static int b44_debug = -1; /* -1 == use B44_DEF_MSG_ENABLE as value */
module_param(b44_debug, int, 0);
MODULE_PARM_DESC(b44_debug, "B44 bitmapped debugging message enable value");
+MODULE_VERSION(DRV_MODULE_VERSION);
static struct pci_device_id b44_pci_tbl[] = {
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4401,
diff -urNp --exclude-from=/home/davej/.exclude linux-1700/drivers/net/ns83820.c linux-1720/drivers/net/ns83820.c
--- linux-1700/drivers/net/ns83820.c
+++ linux-1720/drivers/net/ns83820.c
@@ -2206,6 +2206,7 @@ static void __exit ns83820_exit(void)
MODULE_AUTHOR("Benjamin LaHaise <bcrl at kvack.org>");
MODULE_DESCRIPTION("National Semiconductor DP83820 10/100/1000 driver");
MODULE_LICENSE("GPL");
+MODULE_VERSION(VERSION);
MODULE_DEVICE_TABLE(pci, ns83820_pci_tbl);
diff -urNp --exclude-from=/home/davej/.exclude linux-1700/drivers/net/tg3.c linux-1720/drivers/net/tg3.c
--- linux-1700/drivers/net/tg3.c
+++ linux-1720/drivers/net/tg3.c
@@ -146,6 +146,7 @@ MODULE_VERSION(DRV_MODULE_VERSION);
static int tg3_debug = -1; /* -1 == use TG3_DEF_MSG_ENABLE as value */
module_param(tg3_debug, int, 0);
MODULE_PARM_DESC(tg3_debug, "Tigon3 bitmapped debugging message enable value");
+MODULE_VERSION(DRV_MODULE_VERSION);
static struct pci_device_id tg3_pci_tbl[] = {
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5700,
diff -urNp --exclude-from=/home/davej/.exclude linux-1700/drivers/scsi/gdth.c linux-1720/drivers/scsi/gdth.c
--- linux-1700/drivers/scsi/gdth.c
+++ linux-1720/drivers/scsi/gdth.c
@@ -656,6 +656,7 @@ module_param(probe_eisa_isa, int, 0);
module_param(force_dma32, int, 0);
MODULE_AUTHOR("Achim Leubner");
MODULE_LICENSE("GPL");
+MODULE_VERSION(GDTH_VERSION_STR);
/* ioctl interface */
static struct file_operations gdth_fops = {
linux-2.6-net-atm-lanai-nodev-rmmod.patch:
lanai.c | 1 +
1 files changed, 1 insertion(+)
--- NEW FILE linux-2.6-net-atm-lanai-nodev-rmmod.patch ---
--- linux-2.6.11/drivers/atm/lanai.c~ 2005-05-23 21:48:00.000000000 -0400
+++ linux-2.6.11/drivers/atm/lanai.c 2005-05-23 21:50:53.000000000 -0400
@@ -2760,6 +2760,7 @@ static void __exit lanai_module_exit(voi
* gone, so there isn't much to do
*/
DPRINTK("cleanup_module()\n");
+ pci_unregister_driver(&lanai_driver);
}
module_init(lanai_module_init);
linux-2.6-net-sundance-ip100A.patch:
sundance.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletion(-)
--- NEW FILE linux-2.6-net-sundance-ip100A.patch ---
--- linux-2.6.11/drivers/net/sundance.c~ 2005-05-06 15:11:22.000000000 -0400
+++ linux-2.6.11/drivers/net/sundance.c 2005-05-06 15:12:22.000000000 -0400
@@ -282,6 +282,7 @@ static struct pci_device_id sundance_pci
{0x1186, 0x1002, 0x1186, 0x1040, 0, 0, 3},
{0x1186, 0x1002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4},
{0x13F0, 0x0201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5},
+ {0x13F0, 0x0200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6},
{0,}
};
MODULE_DEVICE_TABLE(pci, sundance_pci_tbl);
@@ -299,7 +300,8 @@ static struct pci_id_info pci_id_tbl[] =
{"D-Link DFE-580TX 4 port Server Adapter"},
{"D-Link DFE-530TXS FAST Ethernet Adapter"},
{"D-Link DL10050-based FAST Ethernet Adapter"},
- {"Sundance Technology Alta"},
+ {"IC Plus IP100 Fast Ethernet Adapter"},
+ {"IC Plus IP100A Fast Ethernet Adapter" },
{NULL,}, /* 0 terminated list. */
};
linux-2.6-ppc64-build.patch:
Makefile | 2 ++
1 files changed, 2 insertions(+)
--- NEW FILE linux-2.6-ppc64-build.patch ---
diff -urNp --exclude-from=/home/davej/.exclude linux-212/arch/ppc64/Makefile linux-300/arch/ppc64/Makefile
--- linux-2.6.1/arch/ppc64/Makefile
+++ linux-2.6.1/arch/ppc64/Makefile
@@ -79,6 +79,8 @@ core-$(CONFIG_XMON) += arch/ppc64/xmon/
drivers-$(CONFIG_OPROFILE) += arch/ppc64/oprofile/
boot := arch/ppc64/boot
+bzImage: vmlinux
+ cp vmlinux arch/ppc64/boot/bzImage
boottarget-$(CONFIG_PPC_PSERIES) := zImage zImage.initrd
boottarget-$(CONFIG_PPC_MAPLE) := zImage zImage.initrd
linux-2.6-ppc64-eeh-panic.patch:
arch/ppc64/kernel/eeh.c | 3 ++-
include/asm-ppc64/eeh.h | 4 +++-
2 files changed, 5 insertions(+), 2 deletions(-)
--- NEW FILE linux-2.6-ppc64-eeh-panic.patch ---
--- linux-2.6.13/include/asm-ppc64/eeh.h~ 2005-09-21 16:36:23.000000000 +0100
+++ linux-2.6.13/include/asm-ppc64/eeh.h 2005-09-21 17:41:51.000000000 +0100
@@ -32,6 +32,8 @@ struct notifier_block;
#ifdef CONFIG_EEH
+extern int eeh_subsystem_enabled;
+
/* Values for eeh_mode bits in device_node */
#define EEH_MODE_SUPPORTED (1<<0)
#define EEH_MODE_NOCHECK (1<<1)
@@ -95,7 +97,7 @@ int eeh_unregister_notifier(struct notif
* If this macro yields TRUE, the caller relays to eeh_check_failure()
* which does further tests out of line.
*/
-#define EEH_POSSIBLE_ERROR(val, type) ((val) == (type)~0)
+#define EEH_POSSIBLE_ERROR(val, type) (eeh_subsystem_enabled && (val) == (type)~0)
/*
* Reads from a device which has been isolated by EEH will return
--- linux-2.6.13/arch/ppc64/kernel/eeh.c~ 2005-09-21 16:35:49.000000000 +0100
+++ linux-2.6.13/arch/ppc64/kernel/eeh.c 2005-09-21 17:40:41.000000000 +0100
@@ -99,7 +99,8 @@ static int ibm_read_slot_reset_state;
static int ibm_read_slot_reset_state2;
static int ibm_slot_error_detail;
-static int eeh_subsystem_enabled;
+int eeh_subsystem_enabled;
+EXPORT_SYMBOL(eeh_subsystem_enabled);
/* Buffer for reporting slot-error-detail rtas calls */
static unsigned char slot_errbuf[RTAS_ERROR_LOG_MAX];
linux-2.6-serial-tickle-nmi.patch:
8250.c | 7 +++++--
1 files changed, 5 insertions(+), 2 deletions(-)
--- NEW FILE linux-2.6-serial-tickle-nmi.patch ---
NMI Watchdog detected LOCKUP on CPU2CPU 2
Modules linked in: loop usb_storage md5 ipv6 parport_pc lp parport autofs4 i2c_dev i2c_core rfcomm l2cap bluetooth sunrpc pcdPid: 3138, comm: gpm Not tainted 2.6.11-1.1290_FC4smp
RIP: 0010:[<ffffffff80273b8a>] <ffffffff80273b8a>{serial_in+106}
RSP: 0018:ffff81003afc3d50 EFLAGS: 00000002
RAX: 0000000000000020 RBX: 0000000000000020 RCX: 0000000000000000
RDX: 00000000000003fd RSI: 0000000000000005 RDI: ffffffff804dcd60
RBP: 00000000000024fc R08: 000000000000000a R09: 0000000000000033
R10: ffff81001beb7c20 R11: 0000000000000020 R12: ffffffff804dcd60
R13: ffffffff804ade76 R14: 000000000000002b R15: 000000000000002c
FS: 00002aaaaaac4920(0000) GS:ffffffff804fca00(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
CR2: 00002aaaaabcb000 CR3: 000000003c0d0000 CR4: 00000000000006e0
Process gpm (pid: 3138, threadinfo ffff81003afc2000, task ffff81003eb63780)
Stack: ffffffff80275f2e 0000000000000000 ffffffff80448380 0000000000007d6b
000000000000002c fffffffffffffbbf 0000000000000292 0000000000008000
ffffffff80138e8c 0000000000007d97
Call Trace:<ffffffff80275f2e>{serial8250_console_write+270} <ffffffff80138e8c>{__call_console_drivers+76}
<ffffffff8013914b>{release_console_sem+315} <ffffffff80260325>{con_open+149}
<ffffffff80254e99>{tty_open+537} <ffffffff80192713>{chrdev_open+387}
<ffffffff80188824>{dentry_open+260} <ffffffff80188994>{filp_open+68}
<ffffffff80187b73>{get_unused_fd+227} <ffffffff80188a6c>{sys_open+76}
<ffffffff8010ebc6>{tracesys+209}
Code: 0f b6 c0 c3 66 90 41 57 49 89 f7 41 56 41 be 00 01 00 00 41
console shuts up ...
--- linux-2.6.11/drivers/serial/8250.c~ 2005-05-14 02:49:02.000000000 -0400
+++ linux-2.6.11/drivers/serial/8250.c 2005-05-14 02:54:30.000000000 -0400
@@ -40,6 +40,7 @@
#include <linux/serial_core.h>
#include <linux/serial.h>
#include <linux/serial_8250.h>
+#include <linux/nmi.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -2098,9 +2098,11 @@ static inline void wait_for_xmitr(struct
/* Wait up to 1s for flow control if necessary */
if (up->port.flags & UPF_CONS_FLOW) {
tmout = 1000000;
- while (--tmout &&
- ((serial_in(up, UART_MSR) & UART_MSR_CTS) == 0))
+ while (!(serial_in(up, UART_MSR) & UART_MSR_CTS) && --tmout) {
udelay(1);
+ if ((tmout % 1000) == 0)
+ touch_nmi_watchdog();
+ }
}
}
linux-2.6-x86-vga-vidfail.patch:
video.S | 4 ++++
1 files changed, 4 insertions(+)
--- NEW FILE linux-2.6-x86-vga-vidfail.patch ---
diff -urNp --exclude-from=/home/davej/.exclude linux-910/arch/i386/boot/video.S linux-1000/arch/i386/boot/video.S
--- linux-910/arch/i386/boot/video.S
+++ linux-1000/arch/i386/boot/video.S
@@ -126,8 +126,12 @@ video: pushw %ds # We use different seg
call mode_set # Set the mode
jc vid1
+#if 0
leaw badmdt, %si # Invalid mode ID
call prtstr
+#else
+ jmp vid1
+#endif /* CONFIG_VIDEO_IGNORE_BAD_MODE */
vid2: call mode_menu
vid1:
#ifdef CONFIG_VIDEO_RETAIN
Index: .cvsignore
===================================================================
RCS file: /cvs/dist/rpms/kernel/devel/.cvsignore,v
retrieving revision 1.249
retrieving revision 1.250
diff -u -r1.249 -r1.250
--- .cvsignore 15 Oct 2005 19:13:18 -0000 1.249
+++ .cvsignore 16 Oct 2005 22:23:45 -0000 1.250
@@ -3,8 +3,4 @@
kernel-2.6.13
linux-2.6.13.tar.bz2
patch-2.6.14-rc4.bz2
-patch-2.6.14-rc3-git7.bz2
-patch-2.6.14-rc4-git1.bz2
-patch-2.6.14-rc4-git2.bz2
-patch-2.6.14-rc4-git3.bz2
patch-2.6.14-rc4-git4.bz2
Index: kernel-2.6.spec
===================================================================
RCS file: /cvs/dist/rpms/kernel/devel/kernel-2.6.spec,v
retrieving revision 1.1611
retrieving revision 1.1612
diff -u -r1.1611 -r1.1612
--- kernel-2.6.spec 15 Oct 2005 19:13:18 -0000 1.1611
+++ kernel-2.6.spec 16 Oct 2005 22:23:45 -0000 1.1612
@@ -209,10 +209,11 @@
Patch200: linux-2.6-x86-tune-p4.patch
Patch201: linux-2.6-x86_64-disable-tlb-flush-filter.patch
Patch202: linux-2.6-x86-apic-off-by-default.patch
+Patch203: linux-2.6-x86-vga-vidfail.patch
# 300 - 399 ppc(64)
-Patch300: linux-2.6.2-ppc64-build.patch
-Patch301: linux-2.6.13-eeh-panic.patch
+Patch300: linux-2.6-ppc64-build.patch
+Patch301: linux-2.6-ppc64-eeh-panic.patch
# 400 - 499 ia64
# 500 - 599 s390(x)
@@ -232,18 +233,19 @@
Patch802: linux-2.6-build-qconfig-qt-lib64.patch
Patch803: linux-2.6-build-reference-discarded-opd.patch
+# Exec-shield.
Patch810: linux-2.6-execshield.patch
Patch811: linux-2.6-execshield-xen.patch
Patch812: linux-2.6-execshield-vdso.patch
Patch813: linux-2.6-xen-vdso-note.patch
# Module signing infrastructure.
-Patch900: linux-2.6.7-modsign-core.patch
-Patch901: linux-2.6.7-modsign-crypto.patch
-Patch902: linux-2.6.7-modsign-ksign.patch
-Patch903: linux-2.6.7-modsign-mpilib.patch
-Patch904: linux-2.6.7-modsign-script.patch
-Patch905: linux-2.6.7-modsign-include.patch
+Patch900: linux-2.6-modsign-core.patch
+Patch901: linux-2.6-modsign-crypto.patch
+Patch902: linux-2.6-modsign-ksign.patch
+Patch903: linux-2.6-modsign-mpilib.patch
+Patch904: linux-2.6-modsign-script.patch
+Patch905: linux-2.6-modsign-include.patch
# Tux http accelerator.
Patch910: linux-2.6-tux.patch
@@ -251,7 +253,6 @@
#
# Patches 1000 to 5000 are reserved for bugfixes to drivers and filesystems
#
-Patch1000: linux-2.4.0-test11-vidfail.patch
Patch1011: linux-2.6-debug-slab-backtrace.patch
Patch1012: linux-2.6-debug-list_head.patch
@@ -264,12 +265,16 @@
Patch1019: linux-2.6-debug-disable-builtins.patch
Patch1020: linux-2.6-debug-sleep-in-irq-warning.patch
Patch1021: linux-2.6-debug-reference-discarded-return-result.patch
+Patch1022: linux-2.6-debug-panic-stackdump.patch
+# Restrict /dev/mem usage.
Patch1050: linux-2.6-devmem.patch
Patch1051: linux-2.6-devmem-xen.patch
+# Provide read only /dev/crash driver.
Patch1060: linux-2.6-crash-driver.patch
Patch1061: linux-2.6-crash-xen.patch
+
Patch1070: linux-2.6-sleepon.patch
# Tweak some defaults.
@@ -283,11 +288,12 @@
Patch1103: linux-2.6-scsi-advansys-pcitable.patch
# NFS bits.
-Patch1200: linux-2.6.9-NFSD-non-null-getxattr.patch
+Patch1200: linux-2.6-NFSD-non-null-getxattr.patch
+Patch1201: linux-2.6-NFSD-ctlbits.patch
# NIC driver updates
-Patch1301: linux-2.6.12-net-sundance-ip100A.patch
-Patch1302: linux-2.6.12-net-atm-lanai-nodev-rmmod.patch
+Patch1301: linux-2.6-net-sundance-ip100A.patch
+Patch1302: linux-2.6-net-atm-lanai-nodev-rmmod.patch
Patch1303: linux-2.6-net-acenic-use-after-free.patch
# Netdump and Diskdump bits.
@@ -300,24 +306,19 @@
# Misc bits.
Patch1600: linux-2.6-procfs-i_nlink-miscalculate.patch
-Patch1610: linux-2.6.11-atkbd-dell-multimedia.patch
-Patch1620: linux-2.6.13-knfsd-ctlbits.patch
-Patch1630: linux-2.6.11-panic-stackdump.patch
-Patch1640: linux-2.6.11-acpi-thinkpad-c2c3.patch
-Patch1650: linux-2.6-mcs-canonicalise-getxattr.patch
-Patch1660: linux-2.6.9-module_version.patch
-Patch1670: linux-2.6-ide-floppy-eject.patch
-Patch1680: linux-2.6-sound-emu10k1-ac97.patch
-Patch1690: linux-2.6-cx88-silence-debug.patch
-Patch1700: linux-2.6-swsusp-nofreeze.patch
-
-Patch1730: linux-2.6.12-input-kill-stupid-messages.patch
-Patch1731: linux-2.6-input-usblegacy.patch
-Patch1750: linux-2.6.11-serial-tickle-nmi.patch
-Patch1760: linux-2.6.12-missing-exports.patch
-Patch1770: linux-2.6-radeon-backlight.patch
-
-Patch1800: linux-2.6-ide-tune-locking.patch
+Patch1610: linux-2.6-atkbd-dell-multimedia.patch
+Patch1620: linux-2.6-acpi-thinkpad-c2c3.patch
+Patch1630: linux-2.6-mcs-canonicalise-getxattr.patch
+Patch1640: linux-2.6-module_version.patch
+Patch1650: linux-2.6-ide-floppy-eject.patch
+Patch1660: linux-2.6-cx88-silence-debug.patch
+Patch1670: linux-2.6-swsusp-nofreeze.patch
+Patch1680: linux-2.6-input-kill-stupid-messages.patch
+Patch1690: linux-2.6-input-usblegacy.patch
+Patch1700: linux-2.6-serial-tickle-nmi.patch
+Patch1710: linux-2.6-missing-exports.patch
+Patch1720: linux-2.6-radeon-backlight.patch
+Patch1730: linux-2.6-ide-tune-locking.patch
# Warn about usage of various obsolete functionality that may go away.
Patch1900: linux-2.6-obsolete-idescsi-warning.patch
@@ -565,6 +566,12 @@
%patch201 -p1
# Keep UP APIC off by default.
%patch202 -p1
+# add vidfail capability;
+# without this patch specifying a framebuffer on the kernel prompt would
+# make the boot stop if there's no supported framebuffer device; this is bad
+# for the installer cd that wants to automatically fall back to textmode
+# in that case
+%patch203 -p1
#
# ppc64
@@ -634,12 +641,6 @@
#
-# add vidfail capability;
-# without this patch specifying a framebuffer on the kernel prompt would
-# make the boot stop if there's no supported framebuffer device; this is bad
-# for the installer cd that wants to automatically fall back to textmode
-# in that case
-%patch1000 -p1
# Various low-impact patches to aid debugging.
%patch1011 -p1
@@ -653,6 +654,7 @@
%patch1019 -p1
%patch1020 -p1
%patch1021 -p1
+%patch1022 -p1
#
# Make /dev/mem a need-to-know function
@@ -697,6 +699,8 @@
# Various upstream NFS/NFSD fixes.
#
%patch1200 -p1
+# kNFSD: fixed '-p port' arg to rpc.nfsd and enables the defining proto versions and transports
+%patch1201 -p1
# NIC driver fixes.
# New PCI ID for sundance driver.
@@ -723,35 +727,30 @@
%patch1600 -p1
# Make multimedia buttons on Dell Inspiron 8200 work.
%patch1610 -p1
-# kNFSD: fixed '-p port' arg to rpc.nfsd and enables the defining proto versions and transports
-%patch1620 -p1
-# Print stack trace when we panic.
-%patch1630 -p1
# Blacklist another 'No C2/C3 states' Thinkpad R40e BIOS.
-%patch1640 -p1
+%patch1620 -p1
# Canonicalise getxattr results.
-%patch1650 -p1
+%patch1630 -p1
# Add missing MODULE_VERSION tags to some modules.
-%patch1660 -p1
+%patch1640 -p1
# Fix eject on ide-floppy. (#158548)
-%patch1670 -p1
+%patch1650 -p1
# Silence silly debug message in cx88. (#168931)
-%patch1690 -p1
+%patch1660 -p1
# Fix suspend to sbp devices. (166452)
-%patch1700 -p1
-
+%patch1670 -p1
# The input layer spews crap no-one cares about.
-%patch1730 -p1
+%patch1680 -p1
# usb legacy workaround.
-%patch1731 -p1
+%patch1690 -p1
# Tickle the NMI whilst doing serial writes.
-%patch1750 -p1
+%patch1700 -p1
# Missing EXPORT_SYMBOL's
-%patch1760 -p1
+%patch1710 -p1
# Radeon on thinkpad backlight power-management goodness.
-%patch1770 -p1
+%patch1720 -p1
# Fix IDE locking bug.
-%patch1800 -p1
+%patch1730 -p1
# Warn about obsolete functionality usage.
%patch1900 -p1
--- linux-2.4.0-test11-vidfail.patch DELETED ---
--- linux-2.6.11-acpi-thinkpad-c2c3.patch DELETED ---
--- linux-2.6.11-atkbd-dell-multimedia.patch DELETED ---
--- linux-2.6.11-panic-stackdump.patch DELETED ---
--- linux-2.6.11-serial-tickle-nmi.patch DELETED ---
--- linux-2.6.12-input-kill-stupid-messages.patch DELETED ---
--- linux-2.6.12-missing-exports.patch DELETED ---
--- linux-2.6.12-net-atm-lanai-nodev-rmmod.patch DELETED ---
--- linux-2.6.12-net-sundance-ip100A.patch DELETED ---
--- linux-2.6.13-eeh-panic.patch DELETED ---
--- linux-2.6.13-knfsd-ctlbits.patch DELETED ---
--- linux-2.6.2-ppc64-build.patch DELETED ---
--- linux-2.6.7-modsign-core.patch DELETED ---
--- linux-2.6.7-modsign-crypto.patch DELETED ---
--- linux-2.6.7-modsign-include.patch DELETED ---
--- linux-2.6.7-modsign-ksign.patch DELETED ---
--- linux-2.6.7-modsign-mpilib.patch DELETED ---
--- linux-2.6.7-modsign-script.patch DELETED ---
--- linux-2.6.9-NFSD-non-null-getxattr.patch DELETED ---
--- linux-2.6.9-module_version.patch DELETED ---
More information about the fedora-cvs-commits
mailing list