OSDN Git Service

of: fix CONFIG_CMDLINE_EXTEND
authorColin Cross <ccross@android.com>
Thu, 7 Mar 2013 03:10:29 +0000 (19:10 -0800)
committerChih-Wei Huang <cwhuang@linux.org.tw>
Sat, 13 Dec 2014 15:14:15 +0000 (23:14 +0800)
strlcat takes the size of the buffer, not the number of characters
to concatenate.  If the size of the device tree command line p is
larger than the CONFIG_CMDLINE string data, then strcat(data, p, l)
will hit a BUG_ON because strlen(data) > l.

Replace the second strlcat with a strncpy plus a manual null
termination.

Also rearrange the code to reduce indent depth to make it more
readable, and replace data with a char *cmdline to avoid extra
casts.

Signed-off-by: Colin Cross <ccross@android.com>
drivers/of/fdt.c

index b48e285..af3b783 100644 (file)
@@ -911,32 +911,38 @@ static const char *config_cmdline = "";
 int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
                                     int depth, void *data)
 {
-       int l;
-       const char *p;
+       unsigned long l = 0;
+       char *p = NULL;
+       char *cmdline = data;
 
        pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
 
-       if (depth != 1 || !data ||
+       if (depth != 1 || !cmdline ||
            (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0))
                return 0;
 
        early_init_dt_check_for_initrd(node);
 
        /* Put CONFIG_CMDLINE in if forced or if data had nothing in it to start */
-       if (overwrite_incoming_cmdline || !((char *)data)[0])
-               strlcpy(data, config_cmdline, COMMAND_LINE_SIZE);
+       if (overwrite_incoming_cmdline || !cmdline[0])
+               strlcpy(cmdline, config_cmdline, COMMAND_LINE_SIZE);
 
        /* Retrieve command line unless forcing */
-       if (read_dt_cmdline) {
+       if (read_dt_cmdline)
                p = of_get_flat_dt_prop(node, "bootargs", &l);
-               if (p != NULL && l > 0) {
-                       if (concat_cmdline) {
-                               strlcat(data, " ", COMMAND_LINE_SIZE);
-                               strlcat(data, p, min_t(int, (int)l,
-                                                      COMMAND_LINE_SIZE));
-                       } else
-                               strlcpy(data, p, min_t(int, (int)l,
-                                                      COMMAND_LINE_SIZE));
+
+       if (p != NULL && l > 0) {
+               if (concat_cmdline) {
+                       int cmdline_len;
+                       int copy_len;
+                       strlcat(cmdline, " ", COMMAND_LINE_SIZE);
+                       cmdline_len = strlen(cmdline);
+                       copy_len = COMMAND_LINE_SIZE - cmdline_len - 1;
+                       copy_len = min((int)l, copy_len);
+                       strncpy(cmdline + cmdline_len, p, copy_len);
+                       cmdline[cmdline_len + copy_len] = '\0';
+               } else {
+                       strlcpy(cmdline, p, min((int)l, COMMAND_LINE_SIZE));
                }
        }