Skip to content

Commit 11eb67e

Browse files
committed
Some memory allocation improvements
- All the memory-allocation macros now auto-check for failure and exit with a failure message that incudes the caller's file and lineno info. This includes strdup(). - Added the `--max-alloc=SIZE` option to be able to override the memory allocator's sanity-check limit. It defaults to 1G (as before). Fixes bugzilla bug 12769.
1 parent 39a083b commit 11eb67e

31 files changed

+239
-318
lines changed

NEWS.md

+12-1
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,22 @@ Protocol: 31 (unchanged)
2525
- Do not allow a negotiated checksum or compression choice of "none" unless
2626
the user authorized it via an environment variable or command-line option.
2727

28-
- Improved the man page a bit more.
28+
- Added the `--max-alloc=SIZE` option to be able to override the memory
29+
allocator's sanity-check limit. It defaults to 1G (as before) but the error
30+
message when exceeding it specifically mentions the new option so that you
31+
can differentiate an out-of-memory error from a failure of this limit. It
32+
also allows you to specify the value via the RSYNC_MAX_ALLOC environment
33+
variable.
34+
35+
- The memory allocation functions now automatically check for a failure and
36+
die when out of memory. This eliminated some caller-side check-and-die
37+
code and added some missing sanity-checking of allocations.
2938

3039
- Preparing for an upcoming xxHash release that provides new XXH3 & XXH128
3140
hashing routines (disabled until their code is finalized).
3241

42+
- Improved the man page a bit more.
43+
3344
------------------------------------------------------------------------------
3445
<a name="3.2.1"></a>
3546

access.c

+3-7
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
*/
2020

2121
#include "rsync.h"
22+
#include "ifuncs.h"
2223

2324
static int allow_forward_dns;
2425

@@ -52,10 +53,8 @@ static int match_hostname(const char **host_ptr, const char *addr, const char *t
5253
if (strcmp(addr, inet_ntoa(*(struct in_addr*)(hp->h_addr_list[i]))) == 0) {
5354
/* If reverse lookups are off, we'll use the conf-specified
5455
* hostname in preference to UNDETERMINED. */
55-
if (host == undetermined_hostname) {
56-
if (!(*host_ptr = strdup(tok)))
57-
*host_ptr = undetermined_hostname;
58-
}
56+
if (host == undetermined_hostname)
57+
*host_ptr = strdup(tok);
5958
return 1;
6059
}
6160
}
@@ -241,9 +240,6 @@ static int access_match(const char *list, const char *addr, const char **host_pt
241240
char *tok;
242241
char *list2 = strdup(list);
243242

244-
if (!list2)
245-
out_of_memory("access_match");
246-
247243
strlower(list2);
248244

249245
for (tok = strtok(list2, " ,\t"); tok; tok = strtok(NULL, " ,\t")) {

acls.c

+3-13
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,6 @@ static rsync_acl *create_racl(void)
168168
{
169169
rsync_acl *racl = new(rsync_acl);
170170

171-
if (!racl)
172-
out_of_memory("create_racl");
173171
*racl = empty_rsync_acl;
174172

175173
return racl;
@@ -335,8 +333,7 @@ static BOOL unpack_smb_acl(SMB_ACL_T sacl, rsync_acl *racl)
335333
qsort(temp_ida_list.items, temp_ida_list.count, sizeof (id_access), id_access_sorter);
336334
}
337335
#endif
338-
if (!(racl->names.idas = new_array(id_access, temp_ida_list.count)))
339-
out_of_memory("unpack_smb_acl");
336+
racl->names.idas = new_array(id_access, temp_ida_list.count);
340337
memcpy(racl->names.idas, temp_ida_list.items, temp_ida_list.count * sizeof (id_access));
341338
} else
342339
racl->names.idas = NULL;
@@ -505,9 +502,7 @@ static int get_rsync_acl(const char *fname, rsync_acl *racl,
505502

506503
if (cnt) {
507504
char *bp = buf + 4*4;
508-
id_access *ida;
509-
if (!(ida = racl->names.idas = new_array(id_access, cnt)))
510-
out_of_memory("get_rsync_acl");
505+
id_access *ida = racl->names.idas = new_array(id_access, cnt);
511506
racl->names.count = cnt;
512507
for ( ; cnt--; ida++, bp += 4+4) {
513508
ida->id = IVAL(bp, 0);
@@ -703,12 +698,7 @@ static uchar recv_ida_entries(int f, ida_entries *ent)
703698
uchar computed_mask_bits = 0;
704699
int i, count = read_varint(f);
705700

706-
if (count) {
707-
if (!(ent->idas = new_array(id_access, count)))
708-
out_of_memory("recv_ida_entries");
709-
} else
710-
ent->idas = NULL;
711-
701+
ent->idas = count ? new_array(id_access, count) : NULL;
712702
ent->count = count;
713703

714704
for (i = 0; i < count; i++) {

authenticate.c

+3-4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include "rsync.h"
2222
#include "itypes.h"
23+
#include "ifuncs.h"
2324

2425
extern int read_only;
2526
extern char *password_file;
@@ -250,8 +251,7 @@ char *auth_server(int f_in, int f_out, int module, const char *host,
250251
}
251252
*pass++ = '\0';
252253

253-
if (!(users = strdup(users)))
254-
out_of_memory("auth_server");
254+
users = strdup(users);
255255

256256
for (tok = strtok(users, " ,\t"); tok; tok = strtok(NULL, " ,\t")) {
257257
char *opts;
@@ -287,8 +287,7 @@ char *auth_server(int f_in, int f_out, int module, const char *host,
287287
else {
288288
gid_t *gid_array = gid_list.items;
289289
auth_uid_groups_cnt = gid_list.count;
290-
if ((auth_uid_groups = new_array(char *, auth_uid_groups_cnt)) == NULL)
291-
out_of_memory("auth_server");
290+
auth_uid_groups = new_array(char *, auth_uid_groups_cnt);
292291
for (j = 0; j < auth_uid_groups_cnt; j++)
293292
auth_uid_groups[j] = gid_to_group(gid_array[j]);
294293
}

checksum.c

-2
Original file line numberDiff line numberDiff line change
@@ -271,8 +271,6 @@ void get_checksum2(char *buf, int32 len, char *sum)
271271
free(buf1);
272272
buf1 = new_array(char, len+4);
273273
len1 = len;
274-
if (!buf1)
275-
out_of_memory("get_checksum2");
276274
}
277275

278276
memcpy(buf1, buf, len);

clientserver.c

+2-4
Original file line numberDiff line numberDiff line change
@@ -235,8 +235,7 @@ int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char
235235
else
236236
modlen = p - *argv;
237237

238-
if (!(modname = new_array(char, modlen+1+1))) /* room for '/' & '\0' */
239-
out_of_memory("start_inband_exchange");
238+
modname = new_array(char, modlen+1+1); /* room for '/' & '\0' */
240239
strlcpy(modname, *argv, modlen + 1);
241240
modname[modlen] = '/';
242241
modname[modlen+1] = '\0';
@@ -1233,8 +1232,7 @@ int start_daemon(int f_in, int f_out)
12331232
io_printf(f_out, "@ERROR: invalid early_input length\n");
12341233
return -1;
12351234
}
1236-
if (!(early_input = new_array(char, early_input_len)))
1237-
out_of_memory("exchange_protocols");
1235+
early_input = new_array(char, early_input_len);
12381236
read_buf(f_in, early_input, early_input_len);
12391237

12401238
if (!read_line_old(f_in, line, sizeof line, 0))

compat.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -243,8 +243,7 @@ static void init_nno_saw(struct name_num_obj *nno, int val)
243243
}
244244

245245
if (!nno->saw) {
246-
if (!(nno->saw = new_array0(uchar, nno->saw_len)))
247-
out_of_memory("init_nno_saw");
246+
nno->saw = new_array0(uchar, nno->saw_len);
248247

249248
/* We'll take this opportunity to make sure that the main_name values are set right. */
250249
for (cnt = 1, nni = nno->list; nni->name; nni++, cnt++) {

exclude.c

+6-15
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
#include "rsync.h"
2424
#include "default-cvsignore.h"
25+
#include "ifuncs.h"
2526

2627
extern int am_server;
2728
extern int am_sender;
@@ -200,8 +201,7 @@ static void add_rule(filter_rule_list *listp, const char *pat, unsigned int pat_
200201
} else
201202
suf_len = 0;
202203

203-
if (!(rule->pattern = new_array(char, pre_len + pat_len + suf_len + 1)))
204-
out_of_memory("add_rule");
204+
rule->pattern = new_array(char, pre_len + pat_len + suf_len + 1);
205205
if (pre_len) {
206206
memcpy(rule->pattern, dirbuf + module_dirlen, pre_len);
207207
for (cp = rule->pattern; cp < rule->pattern + pre_len; cp++) {
@@ -262,19 +262,14 @@ static void add_rule(filter_rule_list *listp, const char *pat, unsigned int pat_
262262
}
263263
}
264264

265-
if (!(lp = new_array0(filter_rule_list, 1)))
266-
out_of_memory("add_rule");
265+
lp = new_array0(filter_rule_list, 1);
267266
if (asprintf(&lp->debug_type, " [per-dir %s]", cp) < 0)
268267
out_of_memory("add_rule");
269268
rule->u.mergelist = lp;
270269

271270
if (mergelist_cnt == mergelist_size) {
272271
mergelist_size += 5;
273-
mergelist_parents = realloc_array(mergelist_parents,
274-
filter_rule *,
275-
mergelist_size);
276-
if (!mergelist_parents)
277-
out_of_memory("add_rule");
272+
mergelist_parents = realloc_array(mergelist_parents, filter_rule *, mergelist_size);
278273
}
279274
if (DEBUG_GTE(FILTER, 2)) {
280275
rprintf(FINFO, "[%s] activating mergelist #%d%s\n",
@@ -498,8 +493,6 @@ void *push_local_filters(const char *dir, unsigned int dirlen)
498493
push = (struct local_filter_state *)new_array(char,
499494
sizeof (struct local_filter_state)
500495
+ (mergelist_cnt-1) * sizeof (filter_rule_list));
501-
if (!push)
502-
out_of_memory("push_local_filters");
503496

504497
push->mergelist_cnt = mergelist_cnt;
505498
for (i = 0; i < mergelist_cnt; i++) {
@@ -822,8 +815,7 @@ static filter_rule *parse_rule_tok(const char **rulestr_ptr,
822815
if (!*s)
823816
return NULL;
824817

825-
if (!(rule = new0(filter_rule)))
826-
out_of_memory("parse_rule_tok");
818+
rule = new0(filter_rule);
827819

828820
/* Inherit from the template. Don't inherit FILTRULES_SIDES; we check
829821
* that later. */
@@ -1125,8 +1117,7 @@ void parse_filter_str(filter_rule_list *listp, const char *rulestr,
11251117
const char *name;
11261118
filter_rule *excl_self;
11271119

1128-
if (!(excl_self = new0(filter_rule)))
1129-
out_of_memory("parse_filter_str");
1120+
excl_self = new0(filter_rule);
11301121
/* Find the beginning of the basename and add an exclude for it. */
11311122
for (name = pat + pat_len; name > pat && name[-1] != '/'; name--) {}
11321123
add_rule(listp, name, (pat + pat_len) - name, excl_self, 0);

fileio.c

+1-6
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,6 @@ int write_file(int f, int use_seek, OFF_T offset, const char *buf, int len)
157157
wf_writeBufSize = WRITE_SIZE * 8;
158158
wf_writeBufCnt = 0;
159159
wf_writeBuf = new_array(char, wf_writeBufSize);
160-
if (!wf_writeBuf)
161-
out_of_memory("write_file");
162160
}
163161
r1 = (int)MIN((size_t)len, wf_writeBufSize - wf_writeBufCnt);
164162
if (r1) {
@@ -217,8 +215,7 @@ struct map_struct *map_file(int fd, OFF_T len, int32 read_size, int32 blk_size)
217215
{
218216
struct map_struct *map;
219217

220-
if (!(map = new0(struct map_struct)))
221-
out_of_memory("map_file");
218+
map = new0(struct map_struct);
222219

223220
if (blk_size && (read_size % blk_size))
224221
read_size += blk_size - (read_size % blk_size);
@@ -261,8 +258,6 @@ char *map_ptr(struct map_struct *map, OFF_T offset, int32 len)
261258
/* make sure we have allocated enough memory for the window */
262259
if (window_size > map->p_size) {
263260
map->p = realloc_array(map->p, char, window_size);
264-
if (!map->p)
265-
out_of_memory("map_ptr");
266261
map->p_size = window_size;
267262
}
268263

flist.c

+10-20
Original file line numberDiff line numberDiff line change
@@ -301,8 +301,7 @@ static void flist_expand(struct file_list *flist, int extra)
301301
if (flist->malloced < flist->used + extra)
302302
flist->malloced = flist->used + extra;
303303

304-
new_ptr = realloc_array(flist->files, struct file_struct *,
305-
flist->malloced);
304+
new_ptr = realloc_array(flist->files, struct file_struct *, flist->malloced);
306305

307306
if (DEBUG_GTE(FLIST, 1) && flist->malloced != FLIST_START) {
308307
rprintf(FCLIENT, "[%s] expand file_list pointer array to %s bytes, did%s move\n",
@@ -1335,10 +1334,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
13351334
+ linkname_len;
13361335
if (pool)
13371336
bp = pool_alloc(pool, alloc_len, "make_file");
1338-
else {
1339-
if (!(bp = new_array(char, alloc_len)))
1340-
out_of_memory("make_file");
1341-
}
1337+
else
1338+
bp = new_array(char, alloc_len);
13421339

13431340
memset(bp, 0, extra_len + FILE_STRUCT_LEN);
13441341
bp += extra_len;
@@ -1661,8 +1658,7 @@ static void fsort(struct file_struct **fp, size_t num)
16611658
if (use_qsort)
16621659
qsort(fp, num, PTR_SIZE, file_compare);
16631660
else {
1664-
struct file_struct **tmp = new_array(struct file_struct *,
1665-
(num+1) / 2);
1661+
struct file_struct **tmp = new_array(struct file_struct *, (num+1) / 2);
16661662
fsort_tmp(fp, num, tmp);
16671663
free(tmp);
16681664
}
@@ -1895,13 +1891,11 @@ static void send_implied_dirs(int f, struct file_list *flist, char *fname,
18951891
len = strlen(limit+1);
18961892
memcpy(&relname_list, F_DIR_RELNAMES_P(lastpath_struct), sizeof relname_list);
18971893
if (!relname_list) {
1898-
if (!(relname_list = new0(item_list)))
1899-
out_of_memory("send_implied_dirs");
1894+
relname_list = new0(item_list);
19001895
memcpy(F_DIR_RELNAMES_P(lastpath_struct), &relname_list, sizeof relname_list);
19011896
}
19021897
rnpp = EXPAND_ITEM_LIST(relname_list, relnamecache *, 32);
1903-
if (!(*rnpp = (relnamecache*)new_array(char, sizeof (relnamecache) + len)))
1904-
out_of_memory("send_implied_dirs");
1898+
*rnpp = (relnamecache*)new_array(char, sizeof (relnamecache) + len);
19051899
(*rnpp)->name_type = name_type;
19061900
strlcpy((*rnpp)->fname, limit+1, len + 1);
19071901

@@ -2059,8 +2053,7 @@ void send_extra_file_list(int f, int at_least)
20592053
}
20602054

20612055
if (need_unsorted_flist) {
2062-
if (!(flist->sorted = new_array(struct file_struct *, flist->used)))
2063-
out_of_memory("send_extra_file_list");
2056+
flist->sorted = new_array(struct file_struct *, flist->used);
20642057
memcpy(flist->sorted, flist->files,
20652058
flist->used * sizeof (struct file_struct*));
20662059
} else
@@ -2414,8 +2407,7 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
24142407
* recursion mode, the sender marks duplicate dirs so that it can
24152408
* send them together in a single file-list. */
24162409
if (need_unsorted_flist) {
2417-
if (!(flist->sorted = new_array(struct file_struct *, flist->used)))
2418-
out_of_memory("send_file_list");
2410+
flist->sorted = new_array(struct file_struct *, flist->used);
24192411
memcpy(flist->sorted, flist->files,
24202412
flist->used * sizeof (struct file_struct*));
24212413
} else
@@ -2597,8 +2589,7 @@ struct file_list *recv_file_list(int f, int dir_ndx)
25972589
* order and for calling flist_find()). We keep the "files"
25982590
* list unsorted for our exchange of index numbers with the
25992591
* other side (since their names may not sort the same). */
2600-
if (!(flist->sorted = new_array(struct file_struct *, flist->used)))
2601-
out_of_memory("recv_file_list");
2592+
flist->sorted = new_array(struct file_struct *, flist->used);
26022593
memcpy(flist->sorted, flist->files,
26032594
flist->used * sizeof (struct file_struct*));
26042595
if (inc_recurse && dir_flist->used > dstart) {
@@ -2808,8 +2799,7 @@ struct file_list *flist_new(int flags, char *msg)
28082799
{
28092800
struct file_list *flist;
28102801

2811-
if (!(flist = new0(struct file_list)))
2812-
out_of_memory(msg);
2802+
flist = new0(struct file_list);
28132803

28142804
if (flags & FLIST_TEMP) {
28152805
if (!(flist->file_pool = pool_create(SMALL_EXTENT, 0,

generator.c

-2
Original file line numberDiff line numberDiff line change
@@ -2227,8 +2227,6 @@ void generate_files(int f_out, const char *local_name)
22272227
if (delete_during == 2) {
22282228
deldelay_size = BIGPATHBUFLEN * 4;
22292229
deldelay_buf = new_array(char, deldelay_size);
2230-
if (!deldelay_buf)
2231-
out_of_memory("delete-delay");
22322230
}
22332231
info_levels[INFO_FLIST] = info_levels[INFO_PROGRESS] = 0;
22342232

getgroups.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@
2020

2121
#include "rsync.h"
2222

23-
int
24-
main(UNUSED(int argc), UNUSED(char *argv[]))
23+
int main(UNUSED(int argc), UNUSED(char *argv[]))
2524
{
2625
int n, i;
2726
gid_t *list;

hashtable.c

+3-5
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,8 @@ struct hashtable *hashtable_create(int size, int key64)
3535
size *= 2;
3636
}
3737

38-
if (!(tbl = new(struct hashtable))
39-
|| !(tbl->nodes = new_array0(char, size * node_size)))
40-
out_of_memory("hashtable_create");
38+
tbl = new(struct hashtable);
39+
tbl->nodes = new_array0(char, size * node_size);
4140
tbl->size = size;
4241
tbl->entries = 0;
4342
tbl->node_size = node_size;
@@ -94,8 +93,7 @@ void *hashtable_find(struct hashtable *tbl, int64 key, void *data_when_new)
9493
int size = tbl->size * 2;
9594
int i;
9695

97-
if (!(tbl->nodes = new_array0(char, size * tbl->node_size)))
98-
out_of_memory("hashtable_node");
96+
tbl->nodes = new_array0(char, size * tbl->node_size);
9997
tbl->size = size;
10098
tbl->entries = 0;
10199

0 commit comments

Comments
 (0)