Skip to content

Commit c2557fc

Browse files
committed
Fix SIGFPE when dividing INT64_MIN by -1.
Submitted by @vthib
1 parent a3aa05b commit c2557fc

File tree

2 files changed

+24
-6
lines changed

2 files changed

+24
-6
lines changed

libyara/exec.c

+10-6
Original file line numberDiff line numberDiff line change
@@ -1049,10 +1049,12 @@ int yr_execute_code(YR_SCAN_CONTEXT* context)
10491049
pop(r1);
10501050
ensure_defined(r2);
10511051
ensure_defined(r1);
1052-
if (r2.i != 0)
1053-
r1.i = r1.i % r2.i;
1054-
else
1052+
// If divisor is zero the result is undefined. It's also undefined
1053+
// when dividing INT64_MIN by -1.
1054+
if (r2.i == 0 || (r1.i == INT64_MIN && r2.i == -1))
10551055
r1.i = YR_UNDEFINED;
1056+
else
1057+
r1.i = r1.i % r2.i;
10561058
push(r1);
10571059
break;
10581060

@@ -2099,10 +2101,12 @@ int yr_execute_code(YR_SCAN_CONTEXT* context)
20992101
pop(r1);
21002102
ensure_defined(r2);
21012103
ensure_defined(r1);
2102-
if (r2.i != 0)
2103-
r1.i = r1.i / r2.i;
2104-
else
2104+
// If divisor is zero the result is undefined. It's also undefined
2105+
// when dividing INT64_MIN by -1.
2106+
if (r2.i == 0 || (r1.i == INT64_MIN && r2.i == -1))
21052107
r1.i = YR_UNDEFINED;
2108+
else
2109+
r1.i = r1.i / r2.i;
21062110
push(r1);
21072111
break;
21082112

tests/test-rules.c

+14
Original file line numberDiff line numberDiff line change
@@ -3727,6 +3727,20 @@ void test_defined()
37273727
not defined ($a at pe.number_of_resources) \
37283728
}",
37293729
NULL);
3730+
3731+
// Test that operations that would trigger a SIGFPE are detected and
3732+
// returns undefined
3733+
assert_true_rule(
3734+
"rule t { \
3735+
strings: \
3736+
$a = /aaa/ \
3737+
condition: \
3738+
(not defined (1 \\ #a)) and \
3739+
(not defined (1 % #a)) and \
3740+
(not defined ((#a + -0x7FFFFFFFFFFFFFFF - 1) \\ -1)) and \
3741+
(not defined ((#a + -0x7FFFFFFFFFFFFFFF - 1) % -1)) \
3742+
}",
3743+
NULL);
37303744
}
37313745

37323746
static void test_pass(int pass)

0 commit comments

Comments
 (0)