aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQuentin Rameau <quinq@fifth.space>2018-04-01 19:49:58 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2018-04-01 19:51:14 +0200
commite2afae6303e871a31a061d03359cfcd5dd86c088 (patch)
tree40482184a4ff53ea4fd3439f96e0e7e967a075cc
parent2da9724b56169f00bd7fb6b9a11c9409a7620981 (diff)
downloadbusybox-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.c2
-rw-r--r--include/libbb.h2
-rw-r--r--libbb/get_line_from_file.c11
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)
988static char *get_next_line(char *gets_char, char *last_puts_char) 988static 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 */
914extern char *bb_get_chunk_from_file(FILE *file, int *end) FAST_FUNC; 914extern 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: */
916extern char *xmalloc_fgets_str(FILE *file, const char *terminating_string) FAST_FUNC RETURNS_MALLOC; 916extern 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
13char* FAST_FUNC bb_get_chunk_from_file(FILE *file, int *end) 13char* 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 */
50char* FAST_FUNC xmalloc_fgetline(FILE *file) 53char* 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')