Date: Tue, 21 Oct 2025 19:59:52 +0000 From: bugzilla-noreply@freebsd.org To: bugs@FreeBSD.org Subject: [Bug 290409] DD integer and Heap Overflow Message-ID: <bug-290409-227@https.bugs.freebsd.org/bugzilla/>
index | next in thread | raw e-mail
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=290409 Bug ID: 290409 Summary: DD integer and Heap Overflow Product: Base System Version: 14.3-RELEASE Hardware: amd64 OS: Any Status: New Severity: Affects Many People Priority: --- Component: bin Assignee: bugs@FreeBSD.org Reporter: igor@bsdtrust.com Where the bug is: - https://github.com/freebsd/freebsd-src/blob/main/bin/dd/dd.c The vulnerable point is inside the `setup()` function: ```c if (!(ddflags & (C_BLOCK | C_UNBLOCK))) { if ((in.db = malloc((size_t)out.dbsz + in.dbsz - 1)) == NULL) err(1, "input buffer"); out.db = in.db; } ``` Problem: The values `in.dbsz` and `out.dbsz` come from command-line arguments (`ibs=`, `obs=`, or `bs=`). Both are `size_t`, but they can be assigned from an integer without validation, coming from argv parsing. The calculation `(size_t)out.dbsz + in.dbsz - 1` can exceed `SIZE_MAX`, which causes an arithmetic overflow and the result wraps to a small value — `malloc()` then allocates less memory than the code expects. Later the program writes `in.dbsz` bytes into the buffer that, in theory, should have at least `out.dbsz + in.dbsz` bytes → real heap overflow. How to reproduce (trigger) Scenario: You want `(out.dbsz + in.dbsz - 1) > SIZE_MAX`. On FreeBSD amd64, `size_t` is 64 bits (`SIZE_MAX = 0xffffffffffffffff`). So, to overflow: ``` in.dbsz + out.dbsz - 1 > 2^64 - 1 ``` But you don't need to reach `2^64` exactly. If parsing in `jcl()` uses an intermediate `unsigned int` (32 bits), the overflow happens much earlier. The `jcl()` parser (in `args.c`) converts arguments like `ibs=1024` using `strtoumax()`, but there are older builds where it stores the value into `u_int`. Even on 64-bit builds, the sum can overflow on the cast if `in.dbsz` and `out.dbsz` come close to `SIZE_MAX`. Safe execution (VM) 1. Create a small test file: ``` dd if=/dev/zero of=infile bs=1M count=1 ``` 2. Run `dd` with absurdly large buffers: ``` /usr/bin/dd if=infile of=outfile ibs=9223372036854775800 obs=9223372036854775800 ``` (≈ 9.22e18 bytes, or `0x7ffffffffffffff8`) This makes the calculation overflow and `malloc()` receives a small value, e.g. `0xFFFFFFFFFFFFFFEF`, depending on the cast. 3. Run inside a VM with Valgrind: ``` valgrind ./dd if=infile of=outfile ibs=9223372036854775800 obs=9223372036854775800 ``` You should see something like: ``` root@igor:~ # valgrind dd if=infile of=outfile ibs=9223372036854775800 obs=9223372036854775800 ==951== Memcheck, a memory error detector ==951== Copyright (C) 2002-2024, and GNU GPL'd, by Julian Seward et al. ==951== Using Valgrind-3.25.1 and LibVEX; rerun with -h for copyright info ==951== Command: dd if=infile of=outfile ibs=9223372036854775800 obs=9223372036854775800 ==951== ==951== Argument 'size' of function malloc has a fishy (possibly negative) value: -17 ==951== at 0x4859304: malloc (vg_replace_malloc.c:450) ==951== by 0x4005C99: ??? (in /bin/dd) ==951== by 0x4907E33: __libc_start1 (in /lib/libc.so.7) ==951== by 0x40045B0: ??? (in /bin/dd) ==951== by 0x482F007: ??? ==951== dd: input buffer: Cannot allocate memory ==951== ==951== HEAP SUMMARY: ==951== in use at exit: 104,220 bytes in 8 blocks ==951== total heap usage: 11 allocs, 3 frees, 104,454 bytes allocated ==951== ==951== LEAK SUMMARY: ==951== definitely lost: 48 bytes in 2 blocks ==951== indirectly lost: 0 bytes in 0 blocks ==951== possibly lost: 21 bytes in 2 blocks ==951== still reachable: 104,151 bytes in 4 blocks ==951== suppressed: 0 bytes in 0 blocks ==951== Rerun with --leak-check=full to see details of leaked memory ==951== ==951== For lists of detected and suppressed errors, rerun with: -s ==951== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) ``` This confirms heap corruption. ``` dd if=infile of=outfile ibs=9223372036854775800 obs=9223372036854775800 ``` Author: Igor Gabriel Sousa e Souza Email: igor@bsdtrust.com LinkedIn: https://www.linkedin.com/in/igo0r Best Regards! -- You are receiving this mail because: You are the assignee for the bug.home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-290409-227>
