[S390] early: Fix possible overlapping data buffer
authorChen Liu <chenliu@asset.uwaterloo.ca>
Wed, 23 Mar 2011 09:14:58 +0000 (10:14 +0100)
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>
Wed, 23 Mar 2011 09:15:14 +0000 (10:15 +0100)
This patch fixed bugzilla #12965:
https://bugzilla.kernel.org/show_bug.cgi?id=12965

The original code contains some inproper use of sprintf
function where a buffer is used both as input string
as well as output string. It should remember the written
bytes in the previous and use that as the offset for
later writing. Also replace sprintf with snprintf.

Signed-off-by: Chen Liu <chenliu@asset.uwaterloo.ca>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
arch/s390/kernel/early.c

index 3b7e7dd..668138e 100644 (file)
@@ -94,6 +94,7 @@ static noinline __init void create_kernel_nss(void)
        unsigned int sinitrd_pfn, einitrd_pfn;
 #endif
        int response;
+       int hlen;
        size_t len;
        char *savesys_ptr;
        char defsys_cmd[DEFSYS_CMD_SIZE];
@@ -124,22 +125,24 @@ static noinline __init void create_kernel_nss(void)
        end_pfn = PFN_UP(__pa(&_end));
        min_size = end_pfn << 2;
 
-       sprintf(defsys_cmd, "DEFSYS %s 00000-%.5X EW %.5X-%.5X SR %.5X-%.5X",
-               kernel_nss_name, stext_pfn - 1, stext_pfn, eshared_pfn - 1,
-               eshared_pfn, end_pfn);
+       hlen = snprintf(defsys_cmd, DEFSYS_CMD_SIZE,
+                       "DEFSYS %s 00000-%.5X EW %.5X-%.5X SR %.5X-%.5X",
+                       kernel_nss_name, stext_pfn - 1, stext_pfn,
+                       eshared_pfn - 1, eshared_pfn, end_pfn);
 
 #ifdef CONFIG_BLK_DEV_INITRD
        if (INITRD_START && INITRD_SIZE) {
                sinitrd_pfn = PFN_DOWN(__pa(INITRD_START));
                einitrd_pfn = PFN_UP(__pa(INITRD_START + INITRD_SIZE));
                min_size = einitrd_pfn << 2;
-               sprintf(defsys_cmd, "%s EW %.5X-%.5X", defsys_cmd,
-               sinitrd_pfn, einitrd_pfn);
+               hlen += snprintf(defsys_cmd + hlen, DEFSYS_CMD_SIZE - hlen,
+                                " EW %.5X-%.5X", sinitrd_pfn, einitrd_pfn);
        }
 #endif
 
-       sprintf(defsys_cmd, "%s EW MINSIZE=%.7iK PARMREGS=0-13",
-               defsys_cmd, min_size);
+       snprintf(defsys_cmd + hlen, DEFSYS_CMD_SIZE - hlen,
+                " EW MINSIZE=%.7iK PARMREGS=0-13", min_size);
+       defsys_cmd[DEFSYS_CMD_SIZE - 1] = '\0';
        sprintf(savesys_cmd, "SAVESYS %s \n IPL %s",
                kernel_nss_name, kernel_nss_name);