Skip to content

Commit 91bd3b2

Browse files
Yonghong Songgregkh
authored andcommitted
selftests/bpf: Add a test to verify previous stacksafe() fix
commit 662c3e2 upstream. 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 <yonghong.song@linux.dev> Link: https://lore.kernel.org/r/20240812214852.214037-1-yonghong.song@linux.dev Signed-off-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Shung-Hsi Yu <shung-hsi.yu@suse.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 5032f94 commit 91bd3b2

1 file changed

Lines changed: 54 additions & 0 deletions

File tree

  • tools/testing/selftests/bpf/progs

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

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

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

0 commit comments

Comments
 (0)