From: Xi Wang Date: Fri, 28 Sep 2012 07:04:42 +0000 (-0400) Subject: Fix signed integer overflow in safe_fprintf() X-Git-Tag: v3.1.0~43 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fpull%2F27%2Fhead;p=thirdparty%2Flibarchive.git Fix signed integer overflow in safe_fprintf() The following "overflow" check in safe_fprintf() invokes undefined behavior (signed integer overflow), which is incorrect. Clang will optimize it away. int old_length = fmtbuff_length; fmtbuff_length += fmtbuff_length / 4; if (old_length > fmtbuff_length) { ... } The check is in the form: x > x + x / 4. As per the C standard, the check is equivalent to: 0 > x / 4, since x + x / 4 is assumed to not overflow (otherwise undefined). An earlier check ensures x >= 8192, so this check is always false, and Clang doesn't emit code for it. This patch uses unsigned integers to avoid undefined behavior. --- diff --git a/tar/util.c b/tar/util.c index 92b2804ae..4ed2901d5 100644 --- a/tar/util.c +++ b/tar/util.c @@ -122,7 +122,9 @@ safe_fprintf(FILE *f, const char *fmt, ...) fmtbuff_length *= 2; else { int old_length = fmtbuff_length; - fmtbuff_length += fmtbuff_length / 4; + /* Convert to unsigned to avoid signed overflow, + * otherwise the check may be optimized away. */ + fmtbuff_length += (unsigned)fmtbuff_length / 4; if (old_length > fmtbuff_length) { length = old_length; fmtbuff_heap[length-1] = '\0';