diff options
| author | Quentin Rameau <quinq@fifth.space> | 2018-04-01 19:49:58 +0200 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-04-01 19:51:14 +0200 |
| commit | e2afae6303e871a31a061d03359cfcd5dd86c088 (patch) | |
| tree | 40482184a4ff53ea4fd3439f96e0e7e967a075cc | |
| parent | 2da9724b56169f00bd7fb6b9a11c9409a7620981 (diff) | |
| download | busybox-w32-e2afae6303e871a31a061d03359cfcd5dd86c088.tar.gz busybox-w32-e2afae6303e871a31a061d03359cfcd5dd86c088.tar.bz2 busybox-w32-e2afae6303e871a31a061d03359cfcd5dd86c088.zip | |
sed: prevent overflow of length from bb_get_chunk_from_file
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>
| -rw-r--r-- | editors/sed.c | 2 | ||||
| -rw-r--r-- | include/libbb.h | 2 | ||||
| -rw-r--r-- | libbb/get_line_from_file.c | 11 |
3 files changed, 9 insertions, 6 deletions
diff --git a/editors/sed.c b/editors/sed.c index 9d800c2c3..470220859 100644 --- a/editors/sed.c +++ b/editors/sed.c | |||
| @@ -988,7 +988,7 @@ static void flush_append(char *last_puts_char) | |||
| 988 | static char *get_next_line(char *gets_char, char *last_puts_char) | 988 | static char *get_next_line(char *gets_char, char *last_puts_char) |
| 989 | { | 989 | { |
| 990 | char *temp = NULL; | 990 | char *temp = NULL; |
| 991 | int len; | 991 | size_t len; |
| 992 | char gc; | 992 | char gc; |
| 993 | 993 | ||
| 994 | flush_append(last_puts_char); | 994 | flush_append(last_puts_char); |
diff --git a/include/libbb.h b/include/libbb.h index fa878433e..309c58734 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
| @@ -911,7 +911,7 @@ extern void xprint_and_close_file(FILE *file) FAST_FUNC; | |||
| 911 | * end of line. If end isn't NULL, length of the chunk is stored in it. | 911 | * end of line. If end isn't NULL, length of the chunk is stored in it. |
| 912 | * Returns NULL if EOF/error. | 912 | * Returns NULL if EOF/error. |
| 913 | */ | 913 | */ |
| 914 | extern char *bb_get_chunk_from_file(FILE *file, int *end) FAST_FUNC; | 914 | extern char *bb_get_chunk_from_file(FILE *file, size_t *end) FAST_FUNC; |
| 915 | /* Reads up to (and including) TERMINATING_STRING: */ | 915 | /* Reads up to (and including) TERMINATING_STRING: */ |
| 916 | extern char *xmalloc_fgets_str(FILE *file, const char *terminating_string) FAST_FUNC RETURNS_MALLOC; | 916 | extern char *xmalloc_fgets_str(FILE *file, const char *terminating_string) FAST_FUNC RETURNS_MALLOC; |
| 917 | /* Same, with limited max size, and returns the length (excluding NUL): */ | 917 | /* Same, with limited max size, and returns the length (excluding NUL): */ |
diff --git a/libbb/get_line_from_file.c b/libbb/get_line_from_file.c index 941ea12b5..d10066937 100644 --- a/libbb/get_line_from_file.c +++ b/libbb/get_line_from_file.c | |||
| @@ -10,16 +10,19 @@ | |||
| 10 | */ | 10 | */ |
| 11 | #include "libbb.h" | 11 | #include "libbb.h" |
| 12 | 12 | ||
| 13 | char* FAST_FUNC bb_get_chunk_from_file(FILE *file, int *end) | 13 | char* FAST_FUNC bb_get_chunk_from_file(FILE *file, size_t *end) |
| 14 | { | 14 | { |
| 15 | int ch; | 15 | int ch; |
| 16 | unsigned idx = 0; | 16 | size_t idx = 0; |
| 17 | char *linebuf = NULL; | 17 | char *linebuf = NULL; |
| 18 | 18 | ||
| 19 | while ((ch = getc(file)) != EOF) { | 19 | while ((ch = getc(file)) != EOF) { |
| 20 | /* grow the line buffer as necessary */ | 20 | /* grow the line buffer as necessary */ |
| 21 | if (!(idx & 0xff)) | 21 | if (!(idx & 0xff)) { |
| 22 | if (idx == ((size_t)-1) - 0xff) | ||
| 23 | bb_error_msg_and_die(bb_msg_memory_exhausted); | ||
| 22 | linebuf = xrealloc(linebuf, idx + 0x100); | 24 | linebuf = xrealloc(linebuf, idx + 0x100); |
| 25 | } | ||
| 23 | linebuf[idx++] = (char) ch; | 26 | linebuf[idx++] = (char) ch; |
| 24 | if (ch == '\0') | 27 | if (ch == '\0') |
| 25 | break; | 28 | break; |
| @@ -49,7 +52,7 @@ char* FAST_FUNC xmalloc_fgets(FILE *file) | |||
| 49 | /* Get line. Remove trailing \n */ | 52 | /* Get line. Remove trailing \n */ |
| 50 | char* FAST_FUNC xmalloc_fgetline(FILE *file) | 53 | char* FAST_FUNC xmalloc_fgetline(FILE *file) |
| 51 | { | 54 | { |
| 52 | int i; | 55 | size_t i; |
| 53 | char *c = bb_get_chunk_from_file(file, &i); | 56 | char *c = bb_get_chunk_from_file(file, &i); |
| 54 | 57 | ||
| 55 | if (i && c[--i] == '\n') | 58 | if (i && c[--i] == '\n') |
