Skip to content

Commit 4fcf3a2

Browse files
committed
Watch out for wrapping arithmetics when calling malloc
1 parent 59169b7 commit 4fcf3a2

File tree

15 files changed

+59
-29
lines changed

15 files changed

+59
-29
lines changed

db.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -818,7 +818,7 @@ db_upgrade_schema(const char *schema_bundle)
818818
return -1;
819819
}
820820

821-
char *x = malloc(len + 1);
821+
char *x = malloc_add(len, 1);
822822
memcpy(x, q, len);
823823
filebundle_free(q);
824824
x[len] = 0;

htsbuf.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include <sys/param.h>
3131

3232
#include "htsbuf.h"
33+
#include "misc.h"
3334

3435
/**
3536
*
@@ -418,7 +419,7 @@ htsbuf_append_and_escape_jsonstr(htsbuf_queue_t *hq, const char *str)
418419
char *
419420
htsbuf_to_string(htsbuf_queue_t *hq)
420421
{
421-
char *r = malloc(hq->hq_size + 1);
422+
char *r = malloc_add(hq->hq_size, 1);
422423
r[hq->hq_size] = 0;
423424
htsbuf_read(hq, r, hq->hq_size);
424425
return r;

htsmsg_binary.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <string.h>
3030

3131
#include "htsmsg_binary.h"
32+
#include "misc.h"
3233

3334
/*
3435
*
@@ -62,7 +63,7 @@ htsmsg_binary_des0(htsmsg_t *msg, const uint8_t *buf, size_t len)
6263
f->hmf_type = type;
6364

6465
if(namelen > 0) {
65-
n = malloc(namelen + 1);
66+
n = malloc_add(namelen, 1);
6667
memcpy(n, buf, namelen);
6768
n[namelen] = 0;
6869

@@ -79,7 +80,7 @@ htsmsg_binary_des0(htsmsg_t *msg, const uint8_t *buf, size_t len)
7980

8081
switch(type) {
8182
case HMF_STR:
82-
f->hmf_str = n = malloc(datalen + 1);
83+
f->hmf_str = n = malloc_add(datalen, 1);
8384
memcpy(n, buf, datalen);
8485
n[datalen] = 0;
8586
f->hmf_flags |= HMF_ALLOCED;
@@ -274,7 +275,7 @@ htsmsg_binary_serialize(htsmsg_t *msg, void **datap, size_t *lenp, int maxlen)
274275
if(len + 4 > maxlen)
275276
return -1;
276277

277-
data = malloc(len + 4);
278+
data = malloc_add(len, 4);
278279

279280
data[0] = len >> 24;
280281
data[1] = len >> 16;

http.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -945,7 +945,7 @@ http_route_add(const char *path, http_callback2_t *callback, int flags)
945945
if(path[i] == '/')
946946
hr->hr_depth++;
947947

948-
char *p = malloc(len + 2);
948+
char *p = malloc_add(len, 2);
949949
p[0] = '^';
950950
strcpy(p+1, path);
951951

@@ -1192,7 +1192,7 @@ http_headers_complete(http_parser *p)
11921192
return -1;
11931193
}
11941194
assert(hc->hc_body == NULL);
1195-
hc->hc_body = malloc(p->content_length + 1);
1195+
hc->hc_body = malloc_add(p->content_length, 1);
11961196
if(hc->hc_body == NULL)
11971197
return -1;
11981198

@@ -1936,7 +1936,7 @@ ws_dispatch(void *aux)
19361936

19371937
size_t used = 0;
19381938
size_t bufsize = 1000;
1939-
char *buf = malloc(bufsize + 1);
1939+
char *buf = malloc_add(bufsize, 1);
19401940

19411941
while(1) {
19421942
z->next_out = (void *)buf + used;

irc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ irc_send(irc_client_t *ic, const char *fmt, ...)
190190
buf[l++] = '\r';
191191
buf[l++] = '\n';
192192

193-
irc_out_msg_t *iom = malloc(sizeof(irc_out_msg_t) + l);
193+
irc_out_msg_t *iom = malloc_add(sizeof(irc_out_msg_t), l);
194194
iom->iom_length = l;
195195
memcpy(iom->iom_data, buf, l);
196196
TAILQ_INSERT_TAIL(&ic->ic_cmdq, iom, iom_link);
@@ -1074,7 +1074,7 @@ irc_msg_channel(const char *url, const char *channel,
10741074

10751075
if(*str == '\n')
10761076
str++;
1077-
irc_out_msg_t *iom = malloc(sizeof(irc_out_msg_t) + len);
1077+
irc_out_msg_t *iom = malloc_add(sizeof(irc_out_msg_t), len);
10781078
iom->iom_length = len;
10791079
memcpy(iom->iom_data, buf, len);
10801080
iom->iom_expire = time(NULL) + ttl;

json.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "json.h"
2929
#include "utf8.h"
3030
#include "dbl.h"
31+
#include "misc.h"
3132

3233
#define NOT_THIS_TYPE ((void *)-1)
3334

@@ -108,7 +109,7 @@ json_parse_string(const char *s, const char **endp,
108109

109110
/* End */
110111
l = s - start;
111-
r = malloc(l + 1);
112+
r = malloc_add(l, 1);
112113
memcpy(r, start, l);
113114
r[l] = 0;
114115

misc.c

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ readfile(const char *path, time_t *tsp)
376376
if(tsp != NULL)
377377
*tsp = st.st_mtime;
378378

379-
char *mem = malloc(st.st_size + 1);
379+
char *mem = malloc_add(st.st_size, 1);
380380
mem[st.st_size] = 0;
381381
if(read(fd, mem, st.st_size) != st.st_size) {
382382
const int errsave = errno;
@@ -915,7 +915,7 @@ str_replace_tokens(char *str, const char *tokenprefix,
915915
int replacelen = strlen(tokens[i + 1]);
916916
int newlen = tlen - (d - a) + replacelen;
917917

918-
char *n = malloc(newlen + 1);
918+
char *n = malloc_add(newlen, 1);
919919
memcpy(n, str, a - str);
920920
memcpy(n + (a - str), tokens[i + 1], replacelen);
921921
memcpy(n + (a - str) + replacelen, d, tlen - (d - str));
@@ -933,9 +933,7 @@ str_replace_tokens(char *str, const char *tokenprefix,
933933
char *
934934
bin2str(const void *src, size_t len)
935935
{
936-
if(len > 1024L * 1024L * 1024L * 3L)
937-
return NULL;
938-
char *r = malloc(len + 1);
936+
char *r = malloc_add(len, 1);
939937
r[len] = 0;
940938
memcpy(r, src, len);
941939
return r;
@@ -1009,3 +1007,22 @@ get_ts_mono(void)
10091007
clock_gettime(CLOCK_MONOTONIC, &tv);
10101008
return (int64_t)tv.tv_sec * 1000000LL + (tv.tv_nsec / 1000);
10111009
}
1010+
1011+
1012+
void *
1013+
malloc_add(size_t a, size_t b)
1014+
{
1015+
size_t c;
1016+
if(__builtin_add_overflow(a, b, &c))
1017+
return NULL;
1018+
return malloc(c);
1019+
}
1020+
1021+
void *
1022+
malloc_mul(size_t a, size_t b)
1023+
{
1024+
size_t c;
1025+
if(__builtin_mul_overflow(a, b, &c))
1026+
return NULL;
1027+
return malloc(c);
1028+
}

misc.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,3 +149,7 @@ void freeuint8p(uint8_t **ptr);
149149
char *fmtv(const char *fmt, va_list ap);
150150

151151
char *fmt(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
152+
153+
void *malloc_add(size_t a, size_t b);
154+
155+
void *malloc_mul(size_t a, size_t b);

ntv.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
#include <inttypes.h>
3232
#include <sys/param.h>
3333
#include "ntv.h"
34+
#include "misc.h"
35+
3436

3537
ntv_t *
3638
ntv_create(ntv_type type)
@@ -589,8 +591,8 @@ ntv_cmp_map(const ntv_t *aa, const ntv_t *bb)
589591
if(num == 0)
590592
return 0;
591593

592-
av = malloc(num * sizeof(ntv_t *));
593-
bv = malloc(num * sizeof(ntv_t *));
594+
av = malloc_mul(num, sizeof(ntv_t *));
595+
bv = malloc_mul(num, sizeof(ntv_t *));
594596

595597
i = 0;
596598
NTV_FOREACH(a, aa)

ntv_binary.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727

2828
#include "ntv.h"
2929
#include "mbuf.h"
30-
30+
#include "misc.h"
3131

3232
// These values are selected based on bytes that must never occur in
3333
// UTF8 strings. Just to accidentally avoid parsing text as NTV for
@@ -195,7 +195,7 @@ ntv_read_string(const uint8_t *data, const uint8_t *dataend, char **res)
195195
if(data == NULL)
196196
return NULL;
197197

198-
char *r = *res = malloc(u64 + 1);
198+
char *r = *res = malloc_add(u64, 1);
199199
if(r == NULL)
200200
return NULL;
201201

ntv_msgpack.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "ntv.h"
2929
#include "mbuf.h"
3030
#include "bytestream.h"
31+
#include "misc.h"
3132

3233
static void
3334
msgpack_write_byte(mbuf_t *hq, uint8_t c)
@@ -247,7 +248,7 @@ msgpack_read_data(const uint8_t *data, const uint8_t *dataend, void *res,
247248
if(length > dataend - data)
248249
return msgpack_err(data, ec, "EOF, trying to read %d bytes", length);
249250

250-
char *r = malloc(length + 1);
251+
char *r = malloc_add(length, 1);
251252
if(r == NULL)
252253
return msgpack_err(data, ec, "Out of memory");
253254

strvec.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ strvec_push_alloced(strvec_t *vec, char *value)
3434
static void
3535
strvec_pushl(strvec_t *vec, const char *value, size_t len)
3636
{
37-
char *x = malloc(len + 1);
37+
char *x = malloc_add(len, 1);
3838
memcpy(x, value, len);
3939
x[len] = 0;
4040
strvec_push_alloced(vec, x);
@@ -142,7 +142,7 @@ strvec_copy(strvec_t *dst, const strvec_t *src)
142142
// We trim the capacity down to the actual size here
143143
dst->count = dst->capacity = src->count;
144144

145-
dst->v = malloc(dst->count * sizeof(dst->v[0]));
145+
dst->v = malloc_mul(dst->count, sizeof(dst->v[0]));
146146
for(int i = 0; i < dst->count; i++)
147147
dst->v[i] = src->v[i] ? strdup(src->v[i]) : NULL;
148148
}

talloc.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <stdarg.h>
2929

3030
#include "talloc.h"
31+
#include "misc.h"
3132

3233
typedef struct talloc_item {
3334
struct talloc_item *next;
@@ -111,7 +112,7 @@ talloc_insert(talloc_item_t *t)
111112
void *
112113
talloc_malloc(size_t s)
113114
{
114-
talloc_item_t *t = malloc(s + sizeof(talloc_item_t));
115+
talloc_item_t *t = malloc_add(s, sizeof(talloc_item_t));
115116
talloc_insert(t);
116117
return t + 1;
117118
}
@@ -123,9 +124,10 @@ talloc_malloc(size_t s)
123124
void *
124125
talloc_zalloc(size_t s)
125126
{
126-
talloc_item_t *t = calloc(1, s + sizeof(talloc_item_t));
127-
talloc_insert(t);
128-
return t + 1;
127+
void *x = talloc_malloc(s);
128+
if(x != NULL)
129+
memset(x, 0, s);
130+
return x;
129131
}
130132

131133

tcp.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include <openssl/x509v3.h>
4747

4848
#include "tcp.h"
49+
#include "misc.h"
4950

5051
static SSL_CTX *ssl_ctx;
5152
static pthread_mutex_t *ssl_locks;
@@ -788,7 +789,7 @@ tcp_init1(const char *extra_ca, int init_ssl)
788789
SSL_load_error_strings();
789790

790791
int i, n = CRYPTO_num_locks();
791-
ssl_locks = malloc(sizeof(pthread_mutex_t) * n);
792+
ssl_locks = malloc_mul(sizeof(pthread_mutex_t), n);
792793
for(i = 0; i < n; i++)
793794
pthread_mutex_init(&ssl_locks[i], NULL);
794795

websocket_client.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ wsc_read(ws_client_t *wsc, struct htsbuf_queue *hq)
148148

149149
if(hq->hq_size < hoff + len)
150150
return;
151-
uint8_t *d = malloc(len+1);
151+
uint8_t *d = malloc_add(len, 1);
152152
htsbuf_drop(hq, hoff);
153153
htsbuf_read(hq, d, len);
154154
d[len] = 0;

0 commit comments

Comments
 (0)