Skip to content

Commit 662c3e2

Browse files
Yonghong SongAlexei Starovoitov
authored andcommitted
selftests/bpf: Add a test to verify previous stacksafe() fix
A selftest is added such that without the previous patch, a crash can happen. With the previous patch, the test can run successfully. The new test is written in a way which mimics original crash case: main_prog static_prog_1 static_prog_2 where static_prog_1 has different paths to static_prog_2 and some path has stack allocated and some other path does not. A stacksafe() checking in static_prog_2() triggered the crash. Signed-off-by: Yonghong Song <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent bed2eb9 commit 662c3e2

File tree

1 file changed

+54
-0
lines changed
  • tools/testing/selftests/bpf/progs

1 file changed

+54
-0
lines changed

tools/testing/selftests/bpf/progs/iters.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1432,4 +1432,58 @@ int iter_arr_with_actual_elem_count(const void *ctx)
14321432
return sum;
14331433
}
14341434

1435+
__u32 upper, select_n, result;
1436+
__u64 global;
1437+
1438+
static __noinline bool nest_2(char *str)
1439+
{
1440+
/* some insns (including branch insns) to ensure stacksafe() is triggered
1441+
* in nest_2(). This way, stacksafe() can compare frame associated with nest_1().
1442+
*/
1443+
if (str[0] == 't')
1444+
return true;
1445+
if (str[1] == 'e')
1446+
return true;
1447+
if (str[2] == 's')
1448+
return true;
1449+
if (str[3] == 't')
1450+
return true;
1451+
return false;
1452+
}
1453+
1454+
static __noinline bool nest_1(int n)
1455+
{
1456+
/* case 0: allocate stack, case 1: no allocate stack */
1457+
switch (n) {
1458+
case 0: {
1459+
char comm[16];
1460+
1461+
if (bpf_get_current_comm(comm, 16))
1462+
return false;
1463+
return nest_2(comm);
1464+
}
1465+
case 1:
1466+
return nest_2((char *)&global);
1467+
default:
1468+
return false;
1469+
}
1470+
}
1471+
1472+
SEC("raw_tp")
1473+
__success
1474+
int iter_subprog_check_stacksafe(const void *ctx)
1475+
{
1476+
long i;
1477+
1478+
bpf_for(i, 0, upper) {
1479+
if (!nest_1(select_n)) {
1480+
result = 1;
1481+
return 0;
1482+
}
1483+
}
1484+
1485+
result = 2;
1486+
return 0;
1487+
}
1488+
14351489
char _license[] SEC("license") = "GPL";

0 commit comments

Comments
 (0)