Fix sscanf vulnerability 69/133069/2
authorSunmin Lee <sunm.lee@samsung.com>
Thu, 8 Jun 2017 05:05:57 +0000 (14:05 +0900)
committerSunmin Lee <sunm.lee@samsung.com>
Fri, 9 Jun 2017 01:25:31 +0000 (10:25 +0900)
Specify a limit on the input string length
and keep the last byte for null character.

Change-Id: I717ac2ae565f2627e5de26426ec24c6ccf772c5e
Signed-off-by: Sunmin Lee <sunm.lee@samsung.com>
src/sys-assert/sys-assert.c

index 63f362e..275653d 100644 (file)
 
 #define HEXA 16
 #define PERM_LEN 5
+#define PERM_LEN_DEC 4
 #ifdef ARCH_64
 #define ADDR_LEN 10
+#define ADDR_LEN_DOUBLE 20
+#define ADDR_LEN_DOUBLE_DEC 19
 #else
 #define ADDR_LEN 8
+#define ADDR_LEN_DOUBLE 16
+#define ADDR_LEN_DOUBLE_DEC 15
 #endif
 #define INFO_LEN 20
+#define INFO_LEN_DEC 19
 #define VALUE_LEN 24
+#define VALUE_LEN_DEC 23
 #define TIME_MAX_LEN 64
 #define FILE_LEN 255
 #define BUF_SIZE (BUFSIZ)
@@ -79,6 +86,9 @@
 #define FUNC_NAME_MAX_LEN 128
 #define PATH_LEN (FILE_LEN + NAME_MAX)
 
+#define STRING_FORMAT_SPECIFIER_WITH_MACRO(macro) "%"#macro"s"
+#define STR_FS(macro) STRING_FORMAT_SPECIFIER_WITH_MACRO(macro)
+
 #define KB(bytes)       ((bytes)/1024)
 
 /* permission for open file */
@@ -322,7 +332,7 @@ static struct addr_node *get_addr_list_from_maps(int fd)
        long *saddr;
        long *eaddr;
        char perm[PERM_LEN];
-       char path[PATH_LEN];
+       char path[PATH_MAX + 1];
        char addr[ADDR_LEN * 2];
        char linebuf[BUF_SIZE];
        struct addr_node *head = NULL;
@@ -331,8 +341,11 @@ static struct addr_node *get_addr_list_from_maps(int fd)
 
        /* parsing the maps to get executable code address */
        while (fgets_fd(linebuf, BUF_SIZE, fd) != NULL) {
-               memset(path, 0, PATH_LEN);
-               result = sscanf(linebuf, "%s %s %*s %*s %*s %s ", addr, perm, path);
+               memset(path, 0, PATH_MAX + 1);
+               result = sscanf(linebuf, STR_FS(ADDR_LEN_DOUBLE_DEC)
+                               STR_FS(PERM_LEN_DEC)
+                               "%*s %*s %*s"
+                               STR_FS(PATH_MAX), addr, perm, path);
                if (result < 0)
                        continue;
                perm[PERM_LEN - 1] = 0;
@@ -599,7 +612,7 @@ void sighandler(int signum, siginfo_t *info, void *context)
        pid_t pid;
        pid_t tid;
        DIR *dir;
-       struct dirent *dentry=NULL;
+       struct dirent *dentry = NULL;
        char timestr[TIME_MAX_LEN];
        char processname[NAME_MAX] = {0,};
        char exepath[PATH_LEN] = {0,};
@@ -707,7 +720,9 @@ void sighandler(int signum, siginfo_t *info, void *context)
                fprintf(stderr, "[sys-assert]can't open %s\n", MEMINFO_PATH);
        } else {
                while (fgets_fd(linebuf, BUF_SIZE, fd) != NULL) {
-                       sscanf(linebuf, "%s %s %*s", infoname, value);
+                       sscanf(linebuf, STR_FS(INFO_LEN_DEC)
+                                       STR_FS(VALUE_LEN_DEC)
+                                       "%*s", infoname, value);
                        if (strcmp("Cached:", infoname) == 0) {
                                fprintf_fd(fd_cs, "%s   %8s KB\n", infoname, value);
                                break;
@@ -721,7 +736,9 @@ void sighandler(int signum, siginfo_t *info, void *context)
                fprintf(stderr, "[sys-assert]can't open %s\n", STATUS_PATH);
        } else {
                while (fgets_fd(linebuf, BUF_SIZE, fd) != NULL) {
-                       sscanf(linebuf, "%s %s %*s", infoname, value);
+                       sscanf(linebuf, STR_FS(INFO_LEN_DEC)
+                                       STR_FS(VALUE_LEN_DEC)
+                                       "%*s", infoname, value);
                        if (strcmp("VmPeak:", infoname) == 0) {
                                fprintf_fd(fd_cs, "%s   %8s KB\n", infoname,
                                                value);