sed: prevent overflow of length from bb_get_chunk_from_file
authorQuentin Rameau <quinq@fifth.space>
Sun, 1 Apr 2018 17:49:58 +0000 (19:49 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Sun, 1 Apr 2018 17:51:14 +0000 (19:51 +0200)
This fragment did not work right:

                temp = bb_get_chunk_from_file(fp, &len);
                if (temp) {
                        /* len > 0 here, it's ok to do temp[len-1] */
                        char c = temp[len-1];

With "int len" _sign-extending_, temp[len-1] can refer to a wrong location
if len > 0x7fffffff.

Signed-off-by: Quentin Rameau <quinq@fifth.space>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
editors/sed.c
include/libbb.h
libbb/get_line_from_file.c

index 9d800c2c398533055064ccaa5b68818dafc65030..47022085949ab0c0520a3791025f39c15725b2b0 100644 (file)
@@ -988,7 +988,7 @@ static void flush_append(char *last_puts_char)
 static char *get_next_line(char *gets_char, char *last_puts_char)
 {
        char *temp = NULL;
-       int len;
+       size_t len;
        char gc;
 
        flush_append(last_puts_char);
index fa878433eb15d208dd610c7cb8d77949cc80444c..309c58734dab4e550aa995f1e09c00b4cca26a67 100644 (file)
@@ -911,7 +911,7 @@ extern void xprint_and_close_file(FILE *file) FAST_FUNC;
  * end of line. If end isn't NULL, length of the chunk is stored in it.
  * Returns NULL if EOF/error.
  */
-extern char *bb_get_chunk_from_file(FILE *file, int *end) FAST_FUNC;
+extern char *bb_get_chunk_from_file(FILE *file, size_t *end) FAST_FUNC;
 /* Reads up to (and including) TERMINATING_STRING: */
 extern char *xmalloc_fgets_str(FILE *file, const char *terminating_string) FAST_FUNC RETURNS_MALLOC;
 /* Same, with limited max size, and returns the length (excluding NUL): */
index 941ea12b585727c9d305476a6fa2d2208299b98b..d100669379b770fb0c202997b699cf4bca57766d 100644 (file)
  */
 #include "libbb.h"
 
-char* FAST_FUNC bb_get_chunk_from_file(FILE *file, int *end)
+char* FAST_FUNC bb_get_chunk_from_file(FILE *file, size_t *end)
 {
        int ch;
-       unsigned idx = 0;
+       size_t idx = 0;
        char *linebuf = NULL;
 
        while ((ch = getc(file)) != EOF) {
                /* grow the line buffer as necessary */
-               if (!(idx & 0xff))
+               if (!(idx & 0xff)) {
+                       if (idx == ((size_t)-1) - 0xff)
+                               bb_error_msg_and_die(bb_msg_memory_exhausted);
                        linebuf = xrealloc(linebuf, idx + 0x100);
+               }
                linebuf[idx++] = (char) ch;
                if (ch == '\0')
                        break;
@@ -49,7 +52,7 @@ char* FAST_FUNC xmalloc_fgets(FILE *file)
 /* Get line.  Remove trailing \n */
 char* FAST_FUNC xmalloc_fgetline(FILE *file)
 {
-       int i;
+       size_t i;
        char *c = bb_get_chunk_from_file(file, &i);
 
        if (i && c[--i] == '\n')