]> arthur.barton.de Git - netdata.git/commitdiff
resolved buffer overflow in snprintfz(); code cleanup;
authorCosta Tsaousis <costa@tsaousis.gr>
Fri, 13 May 2016 18:08:29 +0000 (21:08 +0300)
committerCosta Tsaousis <costa@tsaousis.gr>
Fri, 13 May 2016 18:08:29 +0000 (21:08 +0300)
src/common.c
src/common.h
src/web_buffer.c
src/web_buffer.h
src/web_server.c

index ea94ecc33baead4af53305c687ee01749dc96e45..a2b0d940fdfff6803bdad72ac02355528825067a 100644 (file)
@@ -796,31 +796,37 @@ char *fgets_trim_len(char *buf, size_t buf_size, FILE *fp, size_t *len) {
        return s;
 }
 
-char *strncpyz(char *dest, const char *src, size_t n)
-{
-  char *p = dest;
+char *strncpyz(char *dst, const char *src, size_t n) {
+       char *p = dst;
+
+       while(*src && n--)
+               *dst++ = *src++;
 
-       while (*src && n--)
-               *dest++ = *src++;
-  *dest = '\0';
+       *dst = '\0';
 
        return p;
 }
 
-int vsnprintfz(char *sout, size_t n, const char *fmt, va_list args)
-{
+int vsnprintfz(char *dst, size_t n, const char *fmt, va_list args) {
        int size;
 
-  size = vsnprintf(sout, n, fmt, args);
-  sout[size] = '\0';
-  return size;
+       size = vsnprintf(dst, n, fmt, args);
+
+       if(unlikely((size_t)size > n)) {
+               // there is bug in vsnprintf() and it returns
+               // a number higher to len, but it does not
+               // overflow the buffer.
+               size = n;
+       }
+
+       dst[size] = '\0';
+       return size;
 }
 
-int snprintfz(char *sout, size_t n, const char *fmt, ...)
-{
+int snprintfz(char *dst, size_t n, const char *fmt, ...) {
        va_list args;
 
        va_start(args, fmt);
-       return vsnprintfz(sout, n, fmt, args);
-  // args will vanish!
+       return vsnprintfz(dst, n, fmt, args);
+       va_end(args);
 }
index 1460d922314f9ce7a46be88298392296f3601680..c94f1cde5f56e5504d198e259335ecf9ecc2449e 100644 (file)
@@ -24,9 +24,10 @@ extern uint32_t simple_hash(const char *name);
 extern void strreverse(char* begin, char* end);
 extern char *mystrsep(char **ptr, char *s);
 extern char *trim(char *s);
-extern char *strncpyz(char *dest, const char *src, size_t n);
-extern int  vsnprintfz(char *sout, size_t n, const char *fmt, va_list args);
-extern int  snprintfz(char *sout, size_t n, const char *fmt, ...);
+
+extern char *strncpyz(char *dst, const char *src, size_t n);
+extern int  vsnprintfz(char *dst, size_t n, const char *fmt, va_list args);
+extern int  snprintfz(char *dst, size_t n, const char *fmt, ...);
 
 extern void *mymmap(const char *filename, size_t size, int flags, int ksm);
 extern int savememory(const char *filename, void *mem, unsigned long size);
index 1e7e2534f73ced3c094c24d1dda81deb26476a97..a0f1537219cfb580941124d83dabe1f7347e0d0d 100644 (file)
@@ -80,13 +80,14 @@ void buffer_strcat(BUFFER *wb, const char *txt)
 
        buffer_need_bytes(wb, 1);
 
-       char *s = &wb->buffer[wb->len], *end = &wb->buffer[wb->size];
+       char *s = &wb->buffer[wb->len], *start, *end = &wb->buffer[wb->size];
        long len = wb->len;
 
-       while(*txt && s != end) {
+       start = s;
+       while(*txt && s != end)
                *s++ = *txt++;
-               len++;
-       }
+
+       len += s - start;
 
        wb->len = len;
        buffer_overflow_check(wb);
@@ -110,7 +111,7 @@ void buffer_snprintf(BUFFER *wb, size_t len, const char *fmt, ...)
 {
        if(unlikely(!fmt || !*fmt)) return;
 
-       buffer_need_bytes(wb, len+1);
+       buffer_need_bytes(wb, len + 1);
 
        va_list args;
        va_start(args, fmt);
@@ -126,9 +127,9 @@ void buffer_vsprintf(BUFFER *wb, const char *fmt, va_list args)
 {
        if(unlikely(!fmt || !*fmt)) return;
 
-       buffer_need_bytes(wb, 1);
+       buffer_need_bytes(wb, 2);
 
-       size_t len = wb->size - wb->len;
+       size_t len = wb->size - wb->len - 1;
 
        wb->len += vsnprintfz(&wb->buffer[wb->len], len, fmt, args);
 
@@ -141,9 +142,10 @@ void buffer_sprintf(BUFFER *wb, const char *fmt, ...)
 {
        if(unlikely(!fmt || !*fmt)) return;
 
-       buffer_need_bytes(wb, 1);
+       buffer_need_bytes(wb, 2);
 
-       size_t len = wb->size - wb->len, wrote;
+       size_t len = wb->size - wb->len - 1;
+       size_t wrote;
 
        va_list args;
        va_start(args, fmt);
index 58dd9c094363a6569f021abec7f61842f4af242a..73533f499d8fe33dea9b12d18f42f49be8f9392a 100644 (file)
@@ -48,7 +48,7 @@ extern const char *buffer_tostring(BUFFER *wb);
 
 #define buffer_need_bytes(buffer, needed_free_size) do { if(unlikely((buffer)->size - (buffer)->len < (size_t)(needed_free_size))) buffer_increase((buffer), (size_t)(needed_free_size)); } while(0)
 
-#define buffer_flush(wb) wb->buffer[wb->len = 0] = '\0'
+#define buffer_flush(wb) wb->buffer[(wb)->len = 0] = '\0'
 extern void buffer_reset(BUFFER *wb);
 
 extern void buffer_strcat(BUFFER *wb, const char *txt);
index 3b3bb85a5d49bc3a57b6067d506d021452d0d2f2..0da72b5be3a7a4a909d30dbeffb12621d5f8563d 100644 (file)
@@ -79,7 +79,10 @@ int create_listen_socket4(const char *ip, int port, int listen_backlog)
        /* avoid "address already in use" */
        setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*)&sockopt, sizeof(sockopt));
 
-       struct sockaddr_in name = { .sin_family = AF_INET, .sin_port = htons(port) };
+       struct sockaddr_in name;
+       memset(&name, 0, sizeof(struct sockaddr_in));
+       name.sin_family = AF_INET;
+       name.sin_port = htons (port);
 
        if(is_ip_anything(ip)) {
                name.sin_addr.s_addr = htonl(INADDR_ANY);
@@ -127,7 +130,10 @@ int create_listen_socket6(const char *ip, int port, int listen_backlog)
        /* avoid "address already in use" */
        setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*)&sockopt, sizeof(sockopt));
 
-       struct sockaddr_in6 name = { .sin6_family = AF_INET6, .sin6_port = htons((uint16_t)port) };
+       struct sockaddr_in6 name;
+       memset(&name, 0, sizeof(struct sockaddr_in6));
+       name.sin6_family = AF_INET6;
+       name.sin6_port = htons ((uint16_t) port);
 
        if(is_ip_anything(ip)) {
                name.sin6_addr = in6addr_any;