[S390] call home: fix string length handling
authorHeiko Carstens <heiko.carstens@de.ibm.com>
Thu, 29 Oct 2009 14:04:11 +0000 (15:04 +0100)
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>
Thu, 29 Oct 2009 14:05:12 +0000 (15:05 +0100)
After copying uts->nodename to the static nodename array the static
version isn't necessarily zero termininated, since the size of the
array is one byte too short.
Afterwards doing strncat(data, nodename, strlen(nodename)); may copy
an arbitrary large amount of bytes.
Fix this by getting rid of the static array and using strncat with
proper length limit.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
drivers/s390/char/sclp_async.c

index 3c20aa1..b44462a 100644 (file)
@@ -26,7 +26,6 @@ static struct sclp_async_sccb *sccb;
 static int sclp_async_send_wait(char *message);
 static struct ctl_table_header *callhome_sysctl_header;
 static DEFINE_SPINLOCK(sclp_async_lock);
-static char nodename[64];
 #define SCLP_NORMAL_WRITE      0x00
 
 struct async_evbuf {
@@ -52,9 +51,10 @@ static struct sclp_register sclp_async_register = {
 static int call_home_on_panic(struct notifier_block *self,
                              unsigned long event, void *data)
 {
-               strncat(data, nodename, strlen(nodename));
-               sclp_async_send_wait(data);
-               return NOTIFY_DONE;
+       strncat(data, init_utsname()->nodename,
+               sizeof(init_utsname()->nodename));
+       sclp_async_send_wait(data);
+       return NOTIFY_DONE;
 }
 
 static struct notifier_block call_home_panic_nb = {
@@ -183,10 +183,8 @@ static int __init sclp_async_init(void)
                goto out_mem;
        rc = atomic_notifier_chain_register(&panic_notifier_list,
                                            &call_home_panic_nb);
-       if (rc)
-               goto out_mem;
-       strncpy(nodename, init_utsname()->nodename, 64);
-       goto out;
+       if (!rc)
+               goto out;
 out_mem:
        kfree(request);
        free_page((unsigned long) sccb);