]> granicus.if.org Git - procps-ng/commitdiff
pmap: Prevent buffer overflow in sscanf().
authorQualys Security Advisory <qsa@qualys.com>
Thu, 1 Jan 1970 00:00:00 +0000 (00:00 +0000)
committerCraig Small <csmall@enc.com.au>
Fri, 18 May 2018 21:32:22 +0000 (07:32 +1000)
vmflags[] is a 27*(2+1)=81 char array, but there are 30 flags now (not
27), and even with 27 flags this was an off-by-one overflow (the kernel
always outputs a flag with "%c%c ", so the last +1 is for a space, not
for the terminating null byte). Protect vmflags[] with a maximum field
width, as in the surrounding sscanf() calls.

pmap.c

diff --git a/pmap.c b/pmap.c
index 42a866763637fd50aa643204cc1ef2cfbe1d70ee..719f3aa67ed0eff51fdff14abfd145864bc568b9 100644 (file)
--- a/pmap.c
+++ b/pmap.c
@@ -247,7 +247,8 @@ static char *mapping_name(proc_t * p, unsigned KLONG addr,
 #define DETL "31"              /* for format strings */
 #define NUM_LENGTH 21          /* python says: len(str(2**64)) == 20 */
 #define NUML "20"              /* for format strings */
-#define VMFLAGS_LENGTH 81 /* There are 27 posible 2 character vmflags as of this patch */
+#define VMFLAGS_LENGTH 128     /* 30 2-char space-separated flags == 90+1, but be safe */
+#define VMFL "127"             /* for format strings */
 
 struct listnode {
        char description[DETAIL_LENGTH];
@@ -389,7 +390,7 @@ loop_end:
                }
 
                /* === GET VMFLAGS === */
-               nfields = ret ? sscanf(mapbuf, "VmFlags: %[a-z ]", vmflags) : 0;
+               nfields = ret ? sscanf(mapbuf, "VmFlags: %"VMFL"[a-z ]", vmflags) : 0;
                if (nfields == 1) {
                        if (! has_vmflags) has_vmflags = 1;
                        ret = fgets(mapbuf, sizeof mapbuf, f);