Skip to content

Commit 6e04e7f

Browse files
committed
Merge branch 'coverity-fixes-overflow' into HEAD
2 parents a44dad8 + cfb1ac1 commit 6e04e7f

5 files changed

Lines changed: 55 additions & 2 deletions

File tree

archive-tar.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,8 @@ static size_t get_path_prefix(const char *path, size_t pathlen, size_t maxlen)
210210
i--;
211211
if (i > maxlen)
212212
i = maxlen;
213+
if (!i)
214+
return 0;
213215
do {
214216
i--;
215217
} while (i > 0 && path[i] != '/');

date.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1272,7 +1272,13 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm
12721272
while (tl->type) {
12731273
size_t len = strlen(tl->type);
12741274
if (match_string(date, tl->type) >= len-1) {
1275-
update_tm(tm, now, tl->length * *num);
1275+
time_t length = tl->length, num_t = *num;
1276+
time_t max_val = is_unsigned_type(length)
1277+
? maximum_unsigned_value_of_type(length)
1278+
: maximum_signed_value_of_type(length);
1279+
time_t seconds = mult_overflows(length, num_t)
1280+
? max_val : length * num_t;
1281+
update_tm(tm, now, seconds);
12761282
*num = 0;
12771283
*touched = 1;
12781284
return end;

git-compat-util.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ struct strbuf;
8585

8686
#define bitsizeof(x) (CHAR_BIT * sizeof(x))
8787

88+
#define is_unsigned_type(a) ((typeof(a))-1 >= 0)
89+
8890
#define maximum_signed_value_of_type(a) \
8991
(INTMAX_MAX >> (bitsizeof(intmax_t) - bitsizeof(a)))
9092

@@ -111,6 +113,28 @@ struct strbuf;
111113
#define unsigned_mult_overflows(a, b) \
112114
((a) && (b) > maximum_unsigned_value_of_type(a) / (a))
113115

116+
/*
117+
* Returns true if the multiplication of "a" and "b" will
118+
* overflow or underflow a signed type. The types of "a" and "b"
119+
* must match and must be signed. Note that this macro evaluates
120+
* both "a" and "b" twice!
121+
*/
122+
#define signed_mult_overflows(a, b) \
123+
(((a) > 0 && (b) > 0 && (a) > maximum_signed_value_of_type(a) / (b)) || \
124+
((a) < 0 && (b) < 0 && (a) < maximum_signed_value_of_type(a) / (b)) || \
125+
((a) > 0 && (b) < 0 && (b) < -(maximum_signed_value_of_type(a) / (a))) || \
126+
((a) < 0 && (b) > 0 && (a) < -(maximum_signed_value_of_type(b) / (b))))
127+
128+
/*
129+
* Returns true if the multiplication of "a" and "b" will overflow,
130+
* regardless of whether the type is signed or unsigned. Note that
131+
* this macro evaluates both "a" and "b" twice!
132+
*/
133+
#define mult_overflows(a, b) \
134+
(is_unsigned_type(a) \
135+
? unsigned_mult_overflows(a, b) \
136+
: signed_mult_overflows(a, b))
137+
114138
/*
115139
* Returns true if the left shift of "a" by "shift" bits will
116140
* overflow. The type of "a" must be unsigned.
@@ -502,8 +526,19 @@ void set_die_is_recursing_routine(int (*routine)(void));
502526
*
503527
* See the skip_prefix macro below for an example of use.
504528
*/
529+
/*
530+
* Coverity's EVALUATION_ORDER checker mistakes the dead ternary branch
531+
* for a live side effect: in skip_prefix(p, "x", &p) the expansion
532+
* contains *(out) = (in) in a 0-conditional, which Coverity reads as a
533+
* write to p while p is also read as the first argument. Simplify the
534+
* macro for Coverity to suppress 120+ false positives.
535+
*/
536+
#ifdef __COVERITY__
537+
#define CONST_OUTPARAM(in, out) (out)
538+
#else
505539
#define CONST_OUTPARAM(in, out) \
506540
((const char **)(0 ? ((*(out) = (in)),(out)) : (out)))
541+
#endif
507542

508543
/*
509544
* If the string "str" begins with the string found in "prefix", return true.

http.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2819,7 +2819,7 @@ static size_t fwrite_sha1_file(char *ptr, size_t eltsize, size_t nmemb,
28192819
{
28202820
unsigned char expn[4096];
28212821
size_t size = eltsize * nmemb;
2822-
int posn = 0;
2822+
size_t posn = 0;
28232823
struct http_object_request *freq = data;
28242824
struct active_request_slot *slot = freq->slot;
28252825

wrapper.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,11 @@ ssize_t read_in_full(int fd, void *buf, size_t count)
288288
char *p = buf;
289289
ssize_t total = 0;
290290

291+
if (count > SSIZE_MAX) {
292+
errno = EINVAL;
293+
return -1;
294+
}
295+
291296
while (count > 0) {
292297
ssize_t loaded = xread(fd, p, count);
293298
if (loaded < 0)
@@ -307,6 +312,11 @@ ssize_t write_in_full(int fd, const void *buf, size_t count)
307312
const char *p = buf;
308313
ssize_t total = 0;
309314

315+
if (count > SSIZE_MAX) {
316+
errno = EINVAL;
317+
return -1;
318+
}
319+
310320
while (count > 0) {
311321
ssize_t written = xwrite(fd, p, count);
312322
if (written < 0)

0 commit comments

Comments
 (0)