Skip to content

Commit 0d66550

Browse files
Merge pull request AFLplusplus#2519 from TERESH1/fix_ub_havoc_mutation
Fix ASAN/UBSAN errors in afl_mutate
2 parents 0696c90 + 0cec00e commit 0d66550

File tree

2 files changed

+97
-20
lines changed

2 files changed

+97
-20
lines changed

include/afl-mutations.h

Lines changed: 53 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1896,7 +1896,7 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps,
18961896
if (unlikely(len < 2)) { break; } // no retry
18971897

18981898
item = rand_below(afl, sizeof(interesting_16) >> 1);
1899-
*(u16 *)(buf + rand_below(afl, len - 1)) = interesting_16[item];
1899+
INSERT16(buf, rand_below(afl, len - 1), interesting_16[item]);
19001900

19011901
break;
19021902

@@ -1909,7 +1909,7 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps,
19091909
if (unlikely(len < 2)) { break; } // no retry
19101910

19111911
item = rand_below(afl, sizeof(interesting_16) >> 1);
1912-
*(u16 *)(buf + rand_below(afl, len - 1)) = SWAP16(interesting_16[item]);
1912+
INSERT16(buf, rand_below(afl, len - 1), SWAP16(interesting_16[item]));
19131913

19141914
break;
19151915

@@ -1922,7 +1922,7 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps,
19221922
if (unlikely(len < 4)) { break; } // no retry
19231923

19241924
item = rand_below(afl, sizeof(interesting_32) >> 2);
1925-
*(u32 *)(buf + rand_below(afl, len - 3)) = interesting_32[item];
1925+
INSERT32(buf, rand_below(afl, len - 3), interesting_32[item]);
19261926

19271927
break;
19281928

@@ -1935,7 +1935,7 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps,
19351935
if (unlikely(len < 4)) { break; } // no retry
19361936

19371937
item = rand_below(afl, sizeof(interesting_32) >> 2);
1938-
*(u32 *)(buf + rand_below(afl, len - 3)) = SWAP32(interesting_32[item]);
1938+
INSERT32(buf, rand_below(afl, len - 3), SWAP32(interesting_32[item]));
19391939

19401940
break;
19411941

@@ -1969,7 +1969,7 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps,
19691969

19701970
u32 pos = rand_below(afl, len - 1);
19711971
item = 1 + rand_below(afl, ARITH_MAX);
1972-
*(u16 *)(buf + pos) -= item;
1972+
INSERT16(buf, pos, EXTRACT16(buf, pos) - item);
19731973

19741974
break;
19751975

@@ -1982,8 +1982,8 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps,
19821982
if (unlikely(len < 2)) { break; } // no retry
19831983

19841984
u32 pos = rand_below(afl, len - 1);
1985-
u16 num = 1 + rand_below(afl, ARITH_MAX);
1986-
*(u16 *)(buf + pos) = SWAP16(SWAP16(*(u16 *)(buf + pos)) - num);
1985+
item = 1 + rand_below(afl, ARITH_MAX);
1986+
INSERT16(buf, pos, SWAP16(SWAP16(EXTRACT16(buf, pos)) - item));
19871987

19881988
break;
19891989

@@ -1997,7 +1997,7 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps,
19971997

19981998
u32 pos = rand_below(afl, len - 1);
19991999
item = 1 + rand_below(afl, ARITH_MAX);
2000-
*(u16 *)(buf + pos) += item;
2000+
INSERT16(buf, pos, EXTRACT16(buf, pos) + item);
20012001

20022002
break;
20032003

@@ -2010,8 +2010,8 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps,
20102010
if (unlikely(len < 2)) { break; } // no retry
20112011

20122012
u32 pos = rand_below(afl, len - 1);
2013-
u16 num = 1 + rand_below(afl, ARITH_MAX);
2014-
*(u16 *)(buf + pos) = SWAP16(SWAP16(*(u16 *)(buf + pos)) + num);
2013+
item = 1 + rand_below(afl, ARITH_MAX);
2014+
INSERT16(buf, pos, SWAP16(SWAP16(EXTRACT16(buf, pos)) + item));
20152015

20162016
break;
20172017

@@ -2025,7 +2025,7 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps,
20252025

20262026
u32 pos = rand_below(afl, len - 3);
20272027
item = 1 + rand_below(afl, ARITH_MAX);
2028-
*(u32 *)(buf + pos) -= item;
2028+
INSERT32(buf, pos, EXTRACT32(buf, pos) - item);
20292029

20302030
break;
20312031

@@ -2038,8 +2038,8 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps,
20382038
if (unlikely(len < 4)) { break; } // no retry
20392039

20402040
u32 pos = rand_below(afl, len - 3);
2041-
u32 num = 1 + rand_below(afl, ARITH_MAX);
2042-
*(u32 *)(buf + pos) = SWAP32(SWAP32(*(u32 *)(buf + pos)) - num);
2041+
item = 1 + rand_below(afl, ARITH_MAX);
2042+
INSERT32(buf, pos, SWAP32(SWAP32(EXTRACT32(buf, pos)) - item));
20432043

20442044
break;
20452045

@@ -2053,7 +2053,7 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps,
20532053

20542054
u32 pos = rand_below(afl, len - 3);
20552055
item = 1 + rand_below(afl, ARITH_MAX);
2056-
*(u32 *)(buf + pos) += item;
2056+
INSERT32(buf, pos, EXTRACT32(buf, pos) + item);
20572057

20582058
break;
20592059

@@ -2066,8 +2066,8 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps,
20662066
if (unlikely(len < 4)) { break; } // no retry
20672067

20682068
u32 pos = rand_below(afl, len - 3);
2069-
u32 num = 1 + rand_below(afl, ARITH_MAX);
2070-
*(u32 *)(buf + pos) = SWAP32(SWAP32(*(u32 *)(buf + pos)) + num);
2069+
item = 1 + rand_below(afl, ARITH_MAX);
2070+
INSERT32(buf, pos, SWAP32(SWAP32(EXTRACT32(buf, pos) + item)));
20712071

20722072
break;
20732073

@@ -2344,6 +2344,7 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps,
23442344
if (unlikely(len < 2)) { break; } // no retry
23452345

23462346
u32 clone_len = 1;
2347+
if (unlikely(len + clone_len > max_len)) { goto retry_havoc_step; }
23472348
u32 clone_to = rand_below(afl, len);
23482349
u32 strat = rand_below(afl, 2);
23492350
u32 clone_from = clone_to ? clone_to - 1 : 0;
@@ -2419,7 +2420,17 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps,
24192420
s64 val = buf[off] - '0';
24202421
for (u32 i = off + 1; i < off2; ++i) {
24212422

2422-
val = (val * 10) + buf[i] - '0';
2423+
u8 digit = buf[i] - '0';
2424+
s64 valx10;
2425+
2426+
if (val > INT64_MAX/10 || (valx10 = (val * 10)) > INT64_MAX - digit) {
2427+
2428+
off2 = i;
2429+
break;
2430+
2431+
}
2432+
2433+
val = valx10 + digit;
24232434

24242435
}
24252436

@@ -2429,12 +2440,24 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps,
24292440
switch (strat) {
24302441

24312442
case 0:
2443+
if (val == INT64_MAX){
2444+
val /= 10;
2445+
--off2;
2446+
}
24322447
val++;
24332448
break;
24342449
case 1:
2450+
if (val == INT64_MIN){
2451+
val /= 10;
2452+
--off2;
2453+
}
24352454
val--;
24362455
break;
24372456
case 2:
2457+
if (val > INT64_MAX/2 || val < INT64_MIN/2) {
2458+
val /= 10;
2459+
--off2;
2460+
}
24382461
val *= 2;
24392462
break;
24402463
case 3:
@@ -2453,9 +2476,17 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps,
24532476

24542477
break;
24552478
case 5:
2479+
if (val > INT64_MAX - 256){
2480+
val /= 10;
2481+
--off2;
2482+
}
24562483
val += rand_below(afl, 256);
24572484
break;
24582485
case 6:
2486+
if (val < INT64_MIN + 256){
2487+
val /= 10;
2488+
--off2;
2489+
}
24592490
val -= rand_below(afl, 256);
24602491
break;
24612492
case 7:
@@ -2475,6 +2506,8 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps,
24752506

24762507
} else {
24772508

2509+
if (unlikely(off + new_len + len - off2 > max_len)) { goto retry_havoc_step; }
2510+
24782511
/* Head */
24792512

24802513
memcpy(tmp_buf, buf, off);
@@ -2563,7 +2596,7 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps,
25632596

25642597
u32 use_extra = rand_below(afl, afl->extras_cnt);
25652598
u32 extra_len = afl->extras[use_extra].len;
2566-
if (unlikely(len + extra_len >= max_len)) { goto retry_havoc_step; }
2599+
if (unlikely(len + extra_len > max_len)) { goto retry_havoc_step; }
25672600

25682601
u8 *ptr = afl->extras[use_extra].data;
25692602
u32 insert_at = rand_below(afl, len + 1);
@@ -2603,7 +2636,7 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps,
26032636

26042637
u32 use_extra = rand_below(afl, afl->a_extras_cnt);
26052638
u32 extra_len = afl->a_extras[use_extra].len;
2606-
if (unlikely(len + extra_len >= max_len)) { goto retry_havoc_step; }
2639+
if (unlikely(len + extra_len > max_len)) { goto retry_havoc_step; }
26072640

26082641
u8 *ptr = afl->a_extras[use_extra].data;
26092642
u32 insert_at = rand_below(afl, len + 1);
@@ -2643,7 +2676,7 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps,
26432676

26442677
if (unlikely(!splice_buf || !splice_len)) { goto retry_havoc_step; }
26452678

2646-
if (unlikely(len + HAVOC_BLK_XL >= max_len)) { goto retry_havoc_step; }
2679+
if (unlikely(len + HAVOC_BLK_XL > max_len)) { goto retry_havoc_step; }
26472680

26482681
/* insert mode */
26492682

include/types.h

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,50 @@ typedef int128_t s128;
161161
\
162162
})
163163

164+
#define EXTRACT16(_s, _o) \
165+
({ \
166+
\
167+
u8 *s = (u8 *)(_s) + (_o); \
168+
u16 _ret = s[1]; \
169+
_ret = (_ret << 8) | s[0]; \
170+
_ret; \
171+
\
172+
})
173+
174+
#define EXTRACT32(_s, _o) \
175+
({ \
176+
\
177+
u8 *s = (u8 *)(_s) + (_o); \
178+
u32 _ret = s[3]; \
179+
_ret = (_ret << 8) | s[2]; \
180+
_ret = (_ret << 8) | s[1]; \
181+
_ret = (_ret << 8) | s[0]; \
182+
_ret; \
183+
\
184+
})
185+
186+
#define INSERT16(_d, _o, _x) \
187+
{ \
188+
\
189+
u8 *d = (u8 *)(_d) + (_o); \
190+
u16 x = _x; \
191+
d[0] = x & 0xFF; x >>= 8; \
192+
d[1] = x & 0xFF; \
193+
\
194+
}
195+
196+
#define INSERT32(_d, _o, _x) \
197+
{ \
198+
\
199+
u8 *d = (u8 *)(_d) + (_o); \
200+
u32 x = _x; \
201+
d[0] = x & 0xFF; x >>= 8; \
202+
d[1] = x & 0xFF; x >>= 8; \
203+
d[2] = x & 0xFF; x >>= 8; \
204+
d[3] = x & 0xFF; \
205+
\
206+
}
207+
164208
#ifdef AFL_LLVM_PASS
165209
#if defined(__linux__) || !defined(__ANDROID__)
166210
#define AFL_SR(s) (srandom(s))

0 commit comments

Comments
 (0)