]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
split: fix memory corruption during chunk extraction
authorPádraig Brady <P@draigBrady.com>
Thu, 24 Nov 2016 00:03:16 +0000 (00:03 +0000)
committerPádraig Brady <P@draigBrady.com>
Thu, 24 Nov 2016 00:24:58 +0000 (00:24 +0000)
ASAN reported this error for: split -n2/3 /dev/null
  ERROR: AddressSanitizer: negative-size-param: (size=-1)
  #0 0x7f0d4c36951d in __asan_memmove (/lib64/libasan.so.2+0x8d51d)
  #1 0x404e06 in memmove /usr/include/bits/string3.h:59
  #2 0x404e06 in bytes_chunk_extract src/split.c:988
  #3 0x404e06 in main src/split.c:1626

Specifically there would be invalid memory access
and subsequent processing if the chunk to be extracted
was beyond the initial amount read from file (which is
currently capped at 128KiB).  This issue is not in a
released version, only being introduced in commit v8.25-4-g62e7af0

* src/split.c (bytes_chunk_extract): The initial_read != SIZE_MAX
should have been combined with && rather than ||, but also this
condition is always true in this function so remove entirely.
* tests/split/b-chunk.sh: Add a test case.

Fixes http://bugs.gnu.org/25003

src/split.c
tests/split/b-chunk.sh

index f9c99db43f9bcdc3ef38b7c80008635b5b7eadf1..9a0704c2618498889ac422d58a988b5118847cd5 100644 (file)
@@ -982,7 +982,7 @@ bytes_chunk_extract (uintmax_t k, uintmax_t n, char *buf, size_t bufsize,
   start = (k - 1) * (file_size / n);
   end = (k == n) ? file_size : k * (file_size / n);
 
-  if (initial_read != SIZE_MAX || start < initial_read)
+  if (start < initial_read)
     {
       memmove (buf, buf + start, initial_read - start);
       initial_read -= start;
index 8475f967906548cea0b01b82c53e58970f291afe..c6619a2c7ca7b9ed2367d88c26a0730a34eee644 100755 (executable)
@@ -25,9 +25,14 @@ split -n 10 /dev/null || fail=1
 test "$(stat -c %s x* | uniq -c | sed 's/^ *//; s/ /x/')" = "10x0" || fail=1
 rm -f x??
 
+# When extracting K of N where N > file size
+# no data is extracted, and no files are written
+split -n 2/3 /dev/null || fail=1
+returns_ 1 stat x?? 2>/dev/null || fail=1
+
 # Ensure --elide-empty-files is honored
 split -e -n 10 /dev/null || fail=1
-stat x?? 2>/dev/null && fail=1
+returns_ 1 stat x?? 2>/dev/null || fail=1
 
 printf '1\n2\n3\n4\n5\n' > input || framework_failure_