chiark / gitweb /
[PATCH] fix klibc's broken strlcpy/strlcat
authorkay.sievers@vrfy.org <kay.sievers@vrfy.org>
Sun, 27 Mar 2005 10:39:12 +0000 (12:39 +0200)
committerGreg KH <gregkh@suse.de>
Wed, 27 Apr 2005 06:54:59 +0000 (23:54 -0700)
udevinfo segfaults cause klibc's strlcpy writes behind the specified
size of the destination string. strlcat truncates the destination
string which is also not what you expect from a concatenation function.

klibc/klibc/strlcat.c
klibc/klibc/strlcpy.c
udev_config.c
udev_db.c
udev_libc_wrapper.c

index 6111445f0629948c738ecd91b2cd2fe54a86c5db..f397857e76362f3badc9763f14aa06ba3779a677 100644 (file)
@@ -16,9 +16,11 @@ size_t strlcat(char *dst, const char *src, size_t size)
     q++;
     bytes++;
   }
     q++;
     bytes++;
   }
+  if (bytes == size)
+    return (bytes + strlen(src));
 
   while ( (ch = *p++) ) {
 
   while ( (ch = *p++) ) {
-    if ( bytes < size )
+    if ( bytes+1 < size )
       *q++ = ch;
 
     bytes++;
       *q++ = ch;
 
     bytes++;
index eb384c9885d2a3710c007375376903f4b1732788..8b36c43c00cc10e31810fd0a864b25131b370c99 100644 (file)
@@ -13,7 +13,7 @@ size_t strlcpy(char *dst, const char *src, size_t size)
   char ch;
 
   while ( (ch = *p++) ) {
   char ch;
 
   while ( (ch = *p++) ) {
-    if ( bytes < size )
+    if ( bytes+1 < size )
       *q++ = ch;
 
     bytes++;
       *q++ = ch;
 
     bytes++;
index 7d6bb77e5bd7a1b28cbd09c9c5fe92615388b3f0..b6f578b27dfb0169ff00d5fb9b0a110b64ad1868 100644 (file)
@@ -171,7 +171,7 @@ static int parse_config_file(void)
                if (bufline[0] == COMMENT_CHARACTER)
                        continue;
 
                if (bufline[0] == COMMENT_CHARACTER)
                        continue;
 
-               strlcpy(line, bufline, count);
+               strlcpy(line, bufline, count+1);
 
                linepos = line;
                retval = get_key(&linepos, &variable, &value);
 
                linepos = line;
                retval = get_key(&linepos, &variable, &value);
index f606b5e05c7eddd570ca9b3f11cff8a5ae768315..afbd50e50fc00fdfb9fa1948a209f0d8ec2893b4 100644 (file)
--- a/udev_db.c
+++ b/udev_db.c
@@ -116,37 +116,37 @@ static int parse_db_file(struct udevice *udev, const char *filename)
                switch(bufline[0]) {
                case 'P':
                        if (count > sizeof(udev->devpath))
                switch(bufline[0]) {
                case 'P':
                        if (count > sizeof(udev->devpath))
-                               count = sizeof(udev->devpath)-1;
-                       strlcpy(udev->devpath, &bufline[2], count-2);
+                               count = sizeof(udev->devpath);
+                       strlcpy(udev->devpath, &bufline[2], count-1);
                        break;
                case 'N':
                        if (count > sizeof(udev->name))
                        break;
                case 'N':
                        if (count > sizeof(udev->name))
-                               count = sizeof(udev->name)-1;
-                       strlcpy(udev->name, &bufline[2], count-2);
+                               count = sizeof(udev->name);
+                       strlcpy(udev->name, &bufline[2], count-1);
                        break;
                case 'M':
                        if (count > sizeof(line))
                        break;
                case 'M':
                        if (count > sizeof(line))
-                               count = sizeof(line)-1;
-                       strlcpy(line, &bufline[2], count-2);
+                               count = sizeof(line);
+                       strlcpy(line, &bufline[2], count-1);
                        sscanf(line, "%u:%u", &major, &minor);
                        udev->devt = makedev(major, minor);
                        break;
                case 'S':
                        sscanf(line, "%u:%u", &major, &minor);
                        udev->devt = makedev(major, minor);
                        break;
                case 'S':
-                       if (count >  sizeof(line))
-                               count =  sizeof(line)-1;
-                       strlcpy(line, &bufline[2], count-2);
+                       if (count > sizeof(line))
+                               count =  sizeof(line);
+                       strlcpy(line, &bufline[2], count-1);
                        name_list_add(&udev->symlink_list, line, 0);
                        break;
                case 'A':
                        name_list_add(&udev->symlink_list, line, 0);
                        break;
                case 'A':
-                       if (count >  sizeof(line))
-                               count =  sizeof(line)-1;
-                       strlcpy(line, &bufline[2], count-2);
+                       if (count > sizeof(line))
+                               count =  sizeof(line);
+                       strlcpy(line, &bufline[2], count-1);
                        udev->partitions = atoi(line);
                        break;
                case 'R':
                        udev->partitions = atoi(line);
                        break;
                case 'R':
-                       if (count >  sizeof(line))
-                               count =  sizeof(line)-1;
-                       strlcpy(line, &bufline[2], count-2);
+                       if (count > sizeof(line))
+                               count =  sizeof(line);
+                       strlcpy(line, &bufline[2], count-1);
                        udev->ignore_remove = atoi(line);
                        break;
                }
                        udev->ignore_remove = atoi(line);
                        break;
                }
@@ -227,14 +227,14 @@ int udev_db_search_name(char *devpath, size_t len, const char *name)
                        switch(bufline[0]) {
                        case 'P':
                                if (count > sizeof(path))
                        switch(bufline[0]) {
                        case 'P':
                                if (count > sizeof(path))
-                                       count = sizeof(path)-1;
-                               strlcpy(path, &bufline[2], count-2);
+                                       count = sizeof(path);
+                               strlcpy(path, &bufline[2], count-1);
                                break;
                        case 'N':
                        case 'S':
                                if (count > sizeof(nodename))
                                break;
                        case 'N':
                        case 'S':
                                if (count > sizeof(nodename))
-                                       count = sizeof(nodename)-1;
-                               strlcpy(nodename, &bufline[2], count-2);
+                                       count = sizeof(nodename);
+                               strlcpy(nodename, &bufline[2], count-1);
                                dbg("compare '%s' '%s'", nodename, name);
                                if (strcmp(nodename, name) == 0) {
                                        strlcpy(devpath, path, len);
                                dbg("compare '%s' '%s'", nodename, name);
                                if (strcmp(nodename, name) == 0) {
                                        strlcpy(devpath, path, len);
@@ -302,13 +302,13 @@ int udev_db_dump_names(int (*handler_function)(const char *path, const char *nam
                        switch(bufline[0]) {
                        case 'P':
                                if (count > sizeof(path))
                        switch(bufline[0]) {
                        case 'P':
                                if (count > sizeof(path))
-                                       count = sizeof(path)-1;
-                               strlcpy(path, &bufline[2], count-2);
+                                       count = sizeof(path);
+                               strlcpy(path, &bufline[2], count-1);
                                break;
                        case 'N':
                                if (count > sizeof(nodename))
                                break;
                        case 'N':
                                if (count > sizeof(nodename))
-                               count = sizeof(nodename)-1;
-                               strlcpy(nodename, &bufline[2], count-2);
+                                       count = sizeof(nodename);
+                               strlcpy(nodename, &bufline[2], count-1);
                                break;
                        default:
                                continue;
                                break;
                        default:
                                continue;
index 16d90913cf84606d38cf5ac794cd391b957f29d7..23cb7b43168bc9ff7c3619bcf1440627f67f8b42 100644 (file)
 #define __OWN_USERDB_PARSER__
 #endif
 
 #define __OWN_USERDB_PARSER__
 #endif
 
+#ifdef __GLIBC__
+#define __OWN_STRLCPYCAT__
+#endif
+
 #ifdef USE_STATIC
 #define __OWN_USERDB_PARSER__
 #endif
 
 #ifdef USE_STATIC
 #define __OWN_USERDB_PARSER__
 #endif
 
-#ifndef strlcpy
+#ifdef __OWN_STRLCPYCAT__
 size_t strlcpy(char *dst, const char *src, size_t size)
 {
        size_t bytes = 0;
 size_t strlcpy(char *dst, const char *src, size_t size)
 {
        size_t bytes = 0;
@@ -49,7 +53,7 @@ size_t strlcpy(char *dst, const char *src, size_t size)
        char ch;
 
        while ((ch = *p++)) {
        char ch;
 
        while ((ch = *p++)) {
-               if (bytes < size)
+               if (bytes+1 < size)
                        *q++ = ch;
                bytes++;
        }
                        *q++ = ch;
                bytes++;
        }
@@ -57,9 +61,7 @@ size_t strlcpy(char *dst, const char *src, size_t size)
        *q = '\0';
        return bytes;
 }
        *q = '\0';
        return bytes;
 }
-#endif
 
 
-#ifndef strlcat
 size_t strlcat(char *dst, const char *src, size_t size)
 {
        size_t bytes = 0;
 size_t strlcat(char *dst, const char *src, size_t size)
 {
        size_t bytes = 0;
@@ -71,9 +73,11 @@ size_t strlcat(char *dst, const char *src, size_t size)
                q++;
                bytes++;
        }
                q++;
                bytes++;
        }
+       if (bytes == size)
+               return (bytes + strlen(src));
 
        while ((ch = *p++)) {
 
        while ((ch = *p++)) {
-               if (bytes < size)
+               if (bytes+1 < size)
                *q++ = ch;
                bytes++;
        }
                *q++ = ch;
                bytes++;
        }
@@ -81,7 +85,7 @@ size_t strlcat(char *dst, const char *src, size_t size)
        *q = '\0';
        return bytes;
 }
        *q = '\0';
        return bytes;
 }
-#endif
+#endif /* __OWN_STRLCPYCAT__ */
 
 #ifndef __OWN_USERDB_PARSER__
 #include <sys/types.h>
 
 #ifndef __OWN_USERDB_PARSER__
 #include <sys/types.h>