From 26a9a418237c0b06528941bca693c49c8d97edbe Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 19 May 2009 11:25:35 -0700 Subject: Avoid ICE in get_random_int() with gcc-3.4.5 Martin Knoblauch reports that trying to build 2.6.30-rc6-git3 with RHEL4.3 userspace (gcc (GCC) 3.4.5 20051201 (Red Hat 3.4.5-2)) causes an internal compiler error (ICE): drivers/char/random.c: In function `get_random_int': drivers/char/random.c:1672: error: unrecognizable insn: (insn 202 148 150 0 /scratch/build/linux-2.6.30-rc6-git3/arch/x86/include/asm/tsc.h:23 (set (reg:SI 0 ax [91]) (subreg:SI (plus:DI (plus:DI (reg:DI 0 ax [88]) (subreg:DI (reg:SI 6 bp) 0)) (const_int -4 [0xfffffffffffffffc])) 0)) -1 (nil) (nil)) drivers/char/random.c:1672: internal compiler error: in extract_insn, at recog.c:2083 and after some debugging it turns out that it's due to the code trying to figure out the rough value of the current stack pointer by taking an address of an uninitialized variable and casting that to an integer. This is clearly a compiler bug, but it's not worth fighting - while the current stack kernel pointer might be somewhat hard to predict in user space, it's also not generally going to change for a lot of the call chains for a particular process. So just drop it, and mumble some incoherent curses at the compiler. Tested-by: Martin Knoblauch Cc: Matt Mackall Cc: Ingo Molnar Signed-off-by: Linus Torvalds --- drivers/char/random.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/char') diff --git a/drivers/char/random.c b/drivers/char/random.c index b2ced39d76b..8c7444857a4 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -1673,7 +1673,7 @@ unsigned int get_random_int(void) int ret; keyptr = get_keyptr(); - hash[0] += current->pid + jiffies + get_cycles() + (int)(long)&ret; + hash[0] += current->pid + jiffies + get_cycles(); ret = half_md4_transform(hash, keyptr->secret); put_cpu_var(get_random_int_hash); -- cgit v1.2.3 From fbaa58696cef848de818768783ef185bd3f05158 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Wed, 13 May 2009 12:50:40 -0400 Subject: TPM: get_event_name stack corruption get_event_name uses sprintf to fill a buffer declared on the stack. It fills the buffer 2 bytes at a time. What the code doesn't take into account is that sprintf(buf, "%02x", data) actually writes 3 bytes. 2 bytes for the data and then it nul terminates the string. Since we declare buf to be 40 characters long and then we write 40 bytes of data into buf sprintf is going to write 41 characters. The fix is to leave room in buf for the nul terminator. Signed-off-by: Eric Paris Signed-off-by: James Morris --- drivers/char/tpm/tpm_bios.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/char') diff --git a/drivers/char/tpm/tpm_bios.c b/drivers/char/tpm/tpm_bios.c index ed306eb1057..0c2f55a38b9 100644 --- a/drivers/char/tpm/tpm_bios.c +++ b/drivers/char/tpm/tpm_bios.c @@ -212,7 +212,8 @@ static int get_event_name(char *dest, struct tcpa_event *event, unsigned char * event_entry) { const char *name = ""; - char data[40] = ""; + /* 41 so there is room for 40 data and 1 nul */ + char data[41] = ""; int i, n_len = 0, d_len = 0; struct tcpa_pc_event *pc_event; -- cgit v1.2.3 From 9a2845c453d170e4e9b1437fa671dbf39b0e7bd8 Mon Sep 17 00:00:00 2001 From: Corey Minyard Date: Wed, 20 May 2009 13:36:17 -0500 Subject: ipmi: fix ipmi_si modprobe hang Instead of queuing IPMB messages before channel initialization, just throw them away. Nobody will be listening for them at this point, anyway, and they will clog up the queue and nothing will be delivered if we queue them. Also set the current channel to the number of channels, as this value is used to tell if the channel information has been initialized. Signed-off-by: Corey Minyard Cc: Ferenc Wagner Cc: Dan Frazier Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_msghandler.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers/char') diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index aa83a0865ec..09050797c76 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -2856,6 +2856,7 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers, /* Assume a single IPMB channel at zero. */ intf->channels[0].medium = IPMI_CHANNEL_MEDIUM_IPMB; intf->channels[0].protocol = IPMI_CHANNEL_PROTOCOL_IPMB; + intf->curr_channel = IPMI_MAX_CHANNELS; } if (rv == 0) @@ -3648,13 +3649,13 @@ static int handle_new_recv_msg(ipmi_smi_t intf, } /* - ** We need to make sure the channels have been initialized. - ** The channel_handler routine will set the "curr_channel" - ** equal to or greater than IPMI_MAX_CHANNELS when all the - ** channels for this interface have been initialized. - */ + * We need to make sure the channels have been initialized. + * The channel_handler routine will set the "curr_channel" + * equal to or greater than IPMI_MAX_CHANNELS when all the + * channels for this interface have been initialized. + */ if (intf->curr_channel < IPMI_MAX_CHANNELS) { - requeue = 1; /* Just put the message back for now */ + requeue = 0; /* Throw the message away */ goto out; } -- cgit v1.2.3