uclinux: fix gzip header parsing in binfmt_flat.c
Subsystems (2)
PATCH 1/1 uclinux: fix gzip header parsing in binfmt_flat.c
There are off-by-one errors in decompress_exec() when calculating the length of optional "original file name" and "comment" fields: the "ret" index is not incremented when terminating '\0' character is reached. The check of the buffer overflow (after an "extra-field" length was taken into account) is also fixed.
---
I've encountered this off-by-one error when tried to reuse gzip-header-parsing part of the decompress_exec() function. There was an "original file name" field in the payload (with miscalculated length) and zlib_inflate() returned Z_DATA_ERROR. But after the fix similar to this one all worked fine.
WARNING: the proposed patch wasn't properly tested.
[1mdiff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c[m [1mindex dfc0197..ccb781a 100644[m
[1m--- a/fs/binfmt_flat.c[m
[1m+++ b/fs/binfmt_flat.c[m
[36m@@ -229,13 +229,13 @@ static int decompress_exec(
[m ret = 10;
[m if (buf[3] & EXTRA_FIELD) {
[m ret += 2 + buf[10] + (buf[11] << 8);
[m[31m- if (unlikely(LBUFSIZE == ret)) {
[m[32m+[m [32mif (unlikely(LBUFSIZE <= ret)) {[m
DBG_FLT("binfmt_flat: buffer overflow (EXTRA)?\n");
[m goto out_free_buf;
[m }
[m }
[m if (buf[3] & ORIG_NAME) {
[m[31m- for (; ret < LBUFSIZE && (buf[ret] != 0); ret++)
[m[32m+[m [32mwhile (ret < LBUFSIZE && buf[ret++] != 0)[m
;
[m if (unlikely(LBUFSIZE == ret)) {
[m DBG_FLT("binfmt_flat: buffer overflow (ORIG_NAME)?\n");
[m[36m@@ -243,7 +243,7 @@ static int decompress_exec(
[m }
[m }
[m if (buf[3] & COMMENT) {
[m[31m- for (; ret < LBUFSIZE && (buf[ret] != 0); ret++)
[m[32m+[m [32mwhile (ret < LBUFSIZE && buf[ret++] != 0)[m
;
[m if (unlikely(LBUFSIZE == ret)) {
[m DBG_FLT("binfmt_flat: buffer overflow (COMMENT)?\n");
[m
There are off-by-one errors in decompress_exec() when calculating the length of optional "original file name" and "comment" fields: the "ret" index is not incremented when terminating '\0' character is reached. The check of the buffer overflow (after an "extra-field" length was taken into account) is also fixed.
---
Sorry for repost, looks like I forgot to remove "--color" when saved diff attached to the previous e-mail.
I've encountered this off-by-one error when tried to reuse gzip-header-parsing part of the decompress_exec() function. There was an "original file name" field in the payload (with miscalculated length) and zlib_inflate() returned Z_DATA_ERROR. But after the fix similar to this one all worked fine.
WARNING: the proposed patch wasn't properly tested.
fs/binfmt_flat.c +3 -3
@@ -229,13 +229,13 @@ static int decompress_exec( ret =10 ;if (buf[3 ] &EXTRA_FIELD ) { ret +=2 + buf[10 ] + (buf[11 ] <<8 ); -if (unlikely (LBUFSIZE == ret)) { +if (unlikely (LBUFSIZE <= ret)) {DBG_FLT ("binfmt_flat: buffer overflow (EXTRA)?\n" ); goto out_free_buf; } }if (buf[3 ] &ORIG_NAME ) { -for (; ret <LBUFSIZE && (buf[ret] !=0 ); ret++) +while (ret <LBUFSIZE && buf[ret++] !=0 ) ;if (unlikely (LBUFSIZE == ret)) {DBG_FLT ("binfmt_flat: buffer overflow (ORIG_NAME)?\n" );
@@ -243,7 +243,7 @@ static int decompress_exec( } }if (buf[3 ] &COMMENT ) { -for (; ret <LBUFSIZE && (buf[ret] !=0 ); ret++) +while (ret <LBUFSIZE && buf[ret++] !=0 ) ;if (unlikely (LBUFSIZE == ret)) {DBG_FLT ("binfmt_flat: buffer overflow (COMMENT)?\n" );