Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP4:GA
procps
CVE-2018-1124.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File CVE-2018-1124.patch of Package procps
--- proc/readproc.c | 63 +++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 23 deletions(-) --- proc/readproc.c +++ proc/readproc.c 2018-06-05 14:44:04.887873231 +0000 @@ -37,6 +37,7 @@ #include <sys/dir.h> #include <sys/types.h> #include <sys/stat.h> +#include <limits.h> // sometimes it's easier to do this manually, w/o gcc helping #ifdef PROF @@ -576,7 +577,7 @@ static void statm2proc(const char* s, pr static int file2str(const char *directory, const char *what, struct utlbuf_s *ub) { #define buffGRW 1024 char path[PROCPATHLEN]; - int fd, num, tot_read = 0; + int fd, num, tot_read = 0, len; /* on first use we preallocate a buffer of minimum size to emulate former 'local static' behavior -- even if this read fails, that @@ -584,11 +585,16 @@ static int file2str(const char *director ( besides, with this xcalloc we will never need to use memcpy ) */ if (ub->buf) ub->buf[0] = '\0'; else ub->buf = xcalloc((ub->siz = buffGRW)); - sprintf(path, "%s/%s", directory, what); + len = snprintf(path, sizeof path, "%s/%s", directory, what); + if (len <= 0 || (size_t)len >= sizeof path) return -1; if (-1 == (fd = open(path, O_RDONLY, 0))) return -1; while (0 < (num = read(fd, ub->buf + tot_read, ub->siz - tot_read))) { tot_read += num; if (tot_read < ub->siz) break; + if (ub->siz >= INT_MAX - buffGRW) { + tot_read--; + break; + } ub->buf = xrealloc(ub->buf, (ub->siz += buffGRW)); }; ub->buf[tot_read] = '\0'; @@ -600,11 +606,12 @@ static int file2str(const char *director static char** file2strvec(const char* directory, const char* what) { char buf[2048]; /* read buf bytes at a time */ - char *p, *rbuf = 0, *endbuf, **q, **ret; + char *p, *rbuf = 0, *endbuf, **q, **ret, *strp; int fd, tot = 0, n, c, end_of_file = 0; int align; - sprintf(buf, "%s/%s", directory, what); + const int len = snprintf(buf, sizeof buf, "%s/%s", directory, what); + if(len <= 0 || (size_t)len >= sizeof buf) return NULL; fd = open(buf, O_RDONLY, 0); if(fd==-1) return NULL; @@ -612,18 +619,23 @@ static char** file2strvec(const char* di while ((n = read(fd, buf, sizeof buf - 1)) >= 0) { if (n < (int)(sizeof buf - 1)) end_of_file = 1; - if (n == 0 && rbuf == 0) { - close(fd); - return NULL; /* process died between our open and read */ + if (n <= 0 && tot <= 0) { /* nothing read now, nothing read before */ + break; /* process died between our open and read */ } - if (n < 0) { - if (rbuf) - free(rbuf); - close(fd); - return NULL; /* read error */ + /* ARG_LEN is our guesstimated median length of a command-line argument + or environment variable (the minimum is 1, the maximum is 131072) */ + #define ARG_LEN 64 + if (tot >= INT_MAX / (ARG_LEN + (int)sizeof(char*)) * ARG_LEN - n) { + end_of_file = 1; /* integer overflow: null-terminate and break */ + n = 0; /* but tot > 0 */ } - if (end_of_file && (n == 0 || buf[n-1]))/* last read char not null */ + #undef ARG_LEN + if (end_of_file && + ((n > 0 && buf[n-1] != '\0') || /* last read char not null */ + (n <= 0 && rbuf[tot-1] != '\0'))) /* last read char not null */ buf[n++] = '\0'; /* so append null-terminator */ + + if (n <= 0) break; /* unneeded (end_of_file = 1) but avoid realloc */ rbuf = xrealloc(rbuf, tot + n); /* allocate more memory */ memcpy(rbuf + tot, buf, n); /* copy buffer into it */ tot += n; /* increment total byte ctr */ @@ -631,29 +643,34 @@ static char** file2strvec(const char* di break; } close(fd); - if (n <= 0 && !end_of_file) { + if (n < 0 || tot <= 0) { /* error, or nothing read */ if (rbuf) free(rbuf); return NULL; /* read error */ } + rbuf[tot-1] = '\0'; /* belt and suspenders (the while loop did it, too) */ endbuf = rbuf + tot; /* count space for pointers */ align = (sizeof(char*)-1) - ((tot + sizeof(char*)-1) & (sizeof(char*)-1)); - for (c = 0, p = rbuf; p < endbuf; p++) { - if (!*p || *p == '\n') + c = sizeof(char*); /* one extra for NULL term */ + for (p = rbuf; p < endbuf; p++) { + if (!*p || *p == '\n') { + if (c >= INT_MAX - (tot + (int)sizeof(char*) + align)) break; c += sizeof(char*); + } if (*p == '\n') *p = 0; } - c += sizeof(char*); /* one extra for NULL term */ rbuf = xrealloc(rbuf, tot + c + align); /* make room for ptrs AT END */ endbuf = rbuf + tot; /* addr just past data buf */ q = ret = (char**) (endbuf+align); /* ==> free(*ret) to dealloc */ - *q++ = p = rbuf; /* point ptrs to the strings */ - endbuf--; /* do not traverse final NUL */ - while (++p < endbuf) - if (!*p) /* NUL char implies that */ - *q++ = p+1; /* next string -> next char */ - + for (strp = p = rbuf; p < endbuf; p++) { + if (!*p) { /* NUL char implies that */ + if (c < 2 * (int)sizeof(char*)) break; + c -= sizeof(char*); + *q++ = strp; /* point ptrs to the strings */ + strp = p+1; /* next string -> next char */ + } + } *q = 0; /* null ptr list terminator */ return ret; }
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor