Skip to content

Commit cd5de67

Browse files
committed
Merge branch 'coverity-fixes-overflow' into HEAD
2 parents 696e889 + 6899b3d commit cd5de67

5 files changed

Lines changed: 69 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
@@ -1298,7 +1298,13 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm
12981298
while (tl->type) {
12991299
size_t len = strlen(tl->type);
13001300
if (match_string(date, tl->type) >= len-1) {
1301-
update_tm(tm, now, tl->length * *num);
1301+
time_t length = tl->length, num_t = *num;
1302+
time_t max_val = is_unsigned_type(length)
1303+
? maximum_unsigned_value_of_type(length)
1304+
: maximum_signed_value_of_type(length);
1305+
time_t seconds = mult_overflows(length, num_t)
1306+
? max_val : length * num_t;
1307+
update_tm(tm, now, seconds);
13021308
*num = 0;
13031309
*touched = 1;
13041310
return end;

git-compat-util.h

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

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

88+
#if GIT_GNUC_PREREQ(3, 1)
89+
#define is_unsigned_type(a) ((__typeof__(a))-1 >= 0)
90+
#else
91+
/*
92+
* Without __typeof__, we cannot portably determine signedness from a
93+
* value alone. Fall back to assuming signed, which is correct for all
94+
* current callers (time_t, off_t, ssize_t are signed on all platforms
95+
* Git targets).
96+
*/
97+
#define is_unsigned_type(a) 0
98+
#endif
99+
88100
#define maximum_signed_value_of_type(a) \
89101
(INTMAX_MAX >> (bitsizeof(intmax_t) - bitsizeof(a)))
90102

@@ -111,6 +123,28 @@ struct strbuf;
111123
#define unsigned_mult_overflows(a, b) \
112124
((a) && (b) > maximum_unsigned_value_of_type(a) / (a))
113125

126+
/*
127+
* Returns true if the multiplication of "a" and "b" will
128+
* overflow or underflow a signed type. The types of "a" and "b"
129+
* must match and must be signed. Note that this macro evaluates
130+
* both "a" and "b" twice!
131+
*/
132+
#define signed_mult_overflows(a, b) \
133+
(((a) > 0 && (b) > 0 && (a) > maximum_signed_value_of_type(a) / (b)) || \
134+
((a) < 0 && (b) < 0 && (a) < maximum_signed_value_of_type(a) / (b)) || \
135+
((a) > 0 && (b) < 0 && (b) < -(maximum_signed_value_of_type(a) / (a))) || \
136+
((a) < 0 && (b) > 0 && (a) < -(maximum_signed_value_of_type(b) / (b))))
137+
138+
/*
139+
* Returns true if the multiplication of "a" and "b" will overflow,
140+
* regardless of whether the type is signed or unsigned. Note that
141+
* this macro evaluates both "a" and "b" twice!
142+
*/
143+
#define mult_overflows(a, b) \
144+
(is_unsigned_type(a) \
145+
? unsigned_mult_overflows(a, b) \
146+
: signed_mult_overflows(a, b))
147+
114148
/*
115149
* Returns true if the left shift of "a" by "shift" bits will
116150
* overflow. The type of "a" must be unsigned.
@@ -502,8 +536,19 @@ void set_die_is_recursing_routine(int (*routine)(void));
502536
*
503537
* See the skip_prefix macro below for an example of use.
504538
*/
539+
/*
540+
* Coverity's EVALUATION_ORDER checker mistakes the dead ternary branch
541+
* for a live side effect: in skip_prefix(p, "x", &p) the expansion
542+
* contains *(out) = (in) in a 0-conditional, which Coverity reads as a
543+
* write to p while p is also read as the first argument. Simplify the
544+
* macro for Coverity to suppress 120+ false positives.
545+
*/
546+
#ifdef __COVERITY__
547+
#define CONST_OUTPARAM(in, out) (out)
548+
#else
505549
#define CONST_OUTPARAM(in, out) \
506550
((const char **)(0 ? ((*(out) = (in)),(out)) : (out)))
551+
#endif
507552

508553
/*
509554
* If the string "str" begins with the string found in "prefix", return true.
@@ -760,6 +805,10 @@ static inline uint64_t u64_add(uint64_t a, uint64_t b)
760805
*/
761806
#define DEFAULT_IO_BUFFER_SIZE (128 * 1024)
762807

808+
#ifndef SSIZE_MAX
809+
# define SSIZE_MAX ((ssize_t)(((size_t)-1) >> 1))
810+
#endif
811+
763812
#ifdef HAVE_ALLOCA_H
764813
# include <alloca.h>
765814
# define xalloca(size) (alloca(size))

http.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2862,7 +2862,7 @@ static size_t fwrite_sha1_file(char *ptr, size_t eltsize, size_t nmemb,
28622862
{
28632863
unsigned char expn[4096];
28642864
size_t size = eltsize * nmemb;
2865-
int posn = 0;
2865+
size_t posn = 0;
28662866
struct http_object_request *freq = data;
28672867
struct active_request_slot *slot = freq->slot;
28682868

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)