-
-
Notifications
You must be signed in to change notification settings - Fork 590
Expand file tree
/
Copy patht_hashtable_overflow.c
More file actions
50 lines (44 loc) · 2.13 KB
/
Copy patht_hashtable_overflow.c
File metadata and controls
50 lines (44 loc) · 2.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
/*
* Regression harness for the hashtable size*node_size integer overflow
* (Leonid Bugaev May-2026 re-audit, KI-11/12).
*
* hashtable_create() once computed the slot-array byte count as
* new_array0(char, size * node_size) in 32-bit int arithmetic; for a large
* peer/data-driven size the product wrapped to a tiny value, under-allocating
* the table while tbl->size recorded the huge size -- a later node access then
* ran out of bounds (heap overflow / SEGV). The fix passes size and node_size
* as separate factors so my_alloc's --max-alloc guard rejects the oversized
* request, exiting RERR_MALLOC instead of under-allocating.
*
* This harness sets a realistic max_alloc (t_stub leaves it at SIZE_MAX) and
* asks for an absurd size: the fixed code exits RERR_MALLOC; a regressed build
* under-allocates and crashes on the node access below. Not linked into rsync.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 3 as published by the
* Free Software Foundation.
*/
#include "rsync.h"
extern size_t max_alloc; /* defined in util2.o/t_stub.o */
short info_levels[COUNT_INFO], debug_levels[COUNT_DEBUG]; /* for DEBUG_GTE in hashtable.o */
int main(UNUSED(int argc), UNUSED(char *argv[]))
{
struct hashtable *tbl;
int i;
/* A realistic --max-alloc cap (the default is 1 GiB) so my_alloc's guard
* can engage; t_stub.o leaves max_alloc == SIZE_MAX. */
max_alloc = (size_t)1024 * 1024 * 1024;
/* 2^28 buckets * 16-byte node = 2^32 bytes: the product wraps int to ~0 in
* the unfixed code. The fix must reject this (exit RERR_MALLOC) rather than
* under-allocate. */
tbl = hashtable_create(1 << 28, 0);
/* Unreachable with the fix (hashtable_create exits above). If a regression
* lets it return, touch a node near the claimed end -- an under-allocated
* table faults here -- and report the unexpected survival as a failure. */
for (i = 0; i < tbl->size; i += tbl->size / 64 + 1) {
struct ht_int32_node *node = HT_NODE(tbl, tbl->nodes, i);
node->key = i;
}
fprintf(stderr, "FAIL: hashtable_create(1<<28) was not rejected\n");
return 1;
}