A heap buffer overflow vulnerability was found in wget. Upstream patch: https://git.busybox.net/busybox/commit/?id=8e2174e9bd836e53c8b9c6e00d1bc6e2a718686e
Created wget tracking bugs for this issue: Affects: fedora-all [bug 1595596]
(In reply to Andrej Nemec from comment #0) > A heap buffer overflow vulnerability was found in wget. > > Upstream patch: > > https://git.busybox.net/busybox/commit/ > ?id=8e2174e9bd836e53c8b9c6e00d1bc6e2a718686e That is definitely not an upstream git and that file does not exist in wget. It is probably some "custom" busybox implementation of "wget" command, but it does not seem to have much in common with GNU wget we ship in RHEL and Fedora.
Yep, this is not upstream wget but a busybox wget. I'm changing the whiteboard to reflect this. Thanks!
Created busybox tracking bugs for this issue: Affects: fedora-all [bug 1595679]
The flaw appears to be that when HTTP chunks are sent, the chunk size is implicitly trusted and cast to off_t, which is signed. A specific range of values can bypass multiple checks and get a large, attacker-controlled value to a fread which can result in a heap buffer overflow. The reason for the newer build crash is as follows: if (G.got_clen) { if (G.content_len < (off_t)sizeof(G.wget_buf)) { if ((int)G.content_len <= 0) break; rdsz = (unsigned)G.content_len; } } G.content_len is attacker-controlled. got_clen is set after we control content_len. content_len is a off_t, so it can be negative. If an attacker makes it negative, we bypass the first check (<= sizeof(G.wget_buf)). The second check casts an off_t to an int, which is a truncation. You'd see this warning without the explicit cast: implicit conversion loses integer precision: 'off_t' (aka 'long') to 'int' [-Wshorten-64-to-32] Thus, if it truncates to become a positive value, we bypass the next check (<= 0) and now control rdsz. This then buffer overflows char wget_buf[CONFIG_FEATURE_COPYBUF_KB*1024]; CONFIG_FEATURE_COPYBUF_KB seems to usually between 4 and 8 based on build options. So if we pass in 0xffffffff0001f400, it truncates to 0x0001f400, which is roughly 128KB. Heap overflow. In RHEL6 we don't do the truncation: unsigned rdsz = sizeof(buf); if (content_len < sizeof(buf) && (G.chunked || G.got_clen)) rdsz = (unsigned)content_len; n = safe_fread(buf, rdsz, dfp); content_len (signed long) will be converted to an unsigned long. If content_len was negative, this would result in a large positive value, and the < sizeof(buf) check will capture this edge case and prevent attacker control of rdsz. Furthermore, several lines up, there is the following line: while (content_len > 0 || !G.got_clen) { This will prevent content_len from being negative unless !G.got_clen is true. The vulnerable code can only be hit during chunked transmission. However, G.got_clen is set when chunked is enabled. As such, this does not appear to affect RHEL6. The RHEL5 anaylsis follows from the above.