Skip to content

Commit 8fdadac

Browse files
committed
selftests/seccomp: validate uprobe syscall passes through seccomp
UPROBE.not_attached.uprobe_default_allow UPROBE.not_attached.uprobe_default_block UPROBE.not_attached.uprobe_block_syscall UPROBE.not_attached.uprobe_default_block_with_syscall UPROBE.uprobe_attached.uprobe_default_allow UPROBE.uprobe_attached.uprobe_default_block UPROBE.uprobe_attached.uprobe_block_syscall UPROBE.uprobe_attached.uprobe_default_block_with_syscall UPROBE.uretprobe_attached.uprobe_default_allow UPROBE.uretprobe_attached.uprobe_default_block UPROBE.uretprobe_attached.uprobe_block_syscall UPROBE.uretprobe_attached.uprobe_default_block_with_syscall Signed-off-by: Jiri Olsa <[email protected]>
1 parent 68fd5f9 commit 8fdadac

File tree

1 file changed

+63
-21
lines changed

1 file changed

+63
-21
lines changed

tools/testing/selftests/seccomp/seccomp_bpf.c

+63-21
Original file line numberDiff line numberDiff line change
@@ -4893,7 +4893,23 @@ TEST(tsync_vs_dead_thread_leader)
48934893
EXPECT_EQ(0, status);
48944894
}
48954895

4896-
noinline int probed(void)
4896+
#ifdef __x86_64__
4897+
__attribute__((naked)) noinline int probed_uprobe(void)
4898+
{
4899+
/* Optimized uprobe is possible only on top of nop5 instruction. */
4900+
asm volatile (" \n"
4901+
".byte 0x0f, 0x1f, 0x44, 0x00, 0x00 \n"
4902+
"ret \n"
4903+
);
4904+
}
4905+
#else
4906+
noinline int probed_uprobe(void)
4907+
{
4908+
return 1;
4909+
}
4910+
#endif
4911+
4912+
noinline int probed_uretprobe(void)
48974913
{
48984914
return 1;
48994915
}
@@ -4946,35 +4962,46 @@ static ssize_t get_uprobe_offset(const void *addr)
49464962
return found ? (uintptr_t)addr - start + base : -1;
49474963
}
49484964

4949-
FIXTURE(URETPROBE) {
4965+
FIXTURE(UPROBE) {
49504966
int fd;
49514967
};
49524968

4953-
FIXTURE_VARIANT(URETPROBE) {
4969+
FIXTURE_VARIANT(UPROBE) {
49544970
/*
4955-
* All of the URETPROBE behaviors can be tested with either
4956-
* uretprobe attached or not
4971+
* All of the U(RET)PROBE behaviors can be tested with either
4972+
* u(ret)probe attached or not
49574973
*/
49584974
bool attach;
4975+
/*
4976+
* Test both uprobe and uretprobe.
4977+
*/
4978+
bool uretprobe;
49594979
};
49604980

4961-
FIXTURE_VARIANT_ADD(URETPROBE, attached) {
4981+
FIXTURE_VARIANT_ADD(UPROBE, not_attached) {
4982+
.attach = false,
4983+
.uretprobe = false,
4984+
};
4985+
4986+
FIXTURE_VARIANT_ADD(UPROBE, uprobe_attached) {
49624987
.attach = true,
4988+
.uretprobe = false,
49634989
};
49644990

4965-
FIXTURE_VARIANT_ADD(URETPROBE, not_attached) {
4966-
.attach = false,
4991+
FIXTURE_VARIANT_ADD(UPROBE, uretprobe_attached) {
4992+
.attach = true,
4993+
.uretprobe = true,
49674994
};
49684995

4969-
FIXTURE_SETUP(URETPROBE)
4996+
FIXTURE_SETUP(UPROBE)
49704997
{
49714998
const size_t attr_sz = sizeof(struct perf_event_attr);
49724999
struct perf_event_attr attr;
49735000
ssize_t offset;
49745001
int type, bit;
49755002

4976-
#ifndef __NR_uretprobe
4977-
SKIP(return, "__NR_uretprobe syscall not defined");
5003+
#if !defined(__NR_uprobe) || !defined(__NR_uretprobe)
5004+
SKIP(return, "__NR_uprobe ot __NR_uretprobe syscalls not defined");
49785005
#endif
49795006

49805007
if (!variant->attach)
@@ -4984,12 +5011,17 @@ FIXTURE_SETUP(URETPROBE)
49845011

49855012
type = determine_uprobe_perf_type();
49865013
ASSERT_GE(type, 0);
4987-
bit = determine_uprobe_retprobe_bit();
4988-
ASSERT_GE(bit, 0);
4989-
offset = get_uprobe_offset(probed);
5014+
5015+
if (variant->uretprobe) {
5016+
bit = determine_uprobe_retprobe_bit();
5017+
ASSERT_GE(bit, 0);
5018+
}
5019+
5020+
offset = get_uprobe_offset(variant->uretprobe ? probed_uretprobe : probed_uprobe);
49905021
ASSERT_GE(offset, 0);
49915022

4992-
attr.config |= 1 << bit;
5023+
if (variant->uretprobe)
5024+
attr.config |= 1 << bit;
49935025
attr.size = attr_sz;
49945026
attr.type = type;
49955027
attr.config1 = ptr_to_u64("/proc/self/exe");
@@ -5000,7 +5032,7 @@ FIXTURE_SETUP(URETPROBE)
50005032
PERF_FLAG_FD_CLOEXEC);
50015033
}
50025034

5003-
FIXTURE_TEARDOWN(URETPROBE)
5035+
FIXTURE_TEARDOWN(UPROBE)
50045036
{
50055037
/* we could call close(self->fd), but we'd need extra filter for
50065038
* that and since we are calling _exit right away..
@@ -5014,11 +5046,15 @@ static int run_probed_with_filter(struct sock_fprog *prog)
50145046
return -1;
50155047
}
50165048

5017-
probed();
5049+
/* uprobe is optimized after first hit, so let's hit twice */
5050+
probed_uprobe();
5051+
probed_uprobe();
5052+
5053+
probed_uretprobe();
50185054
return 0;
50195055
}
50205056

5021-
TEST_F(URETPROBE, uretprobe_default_allow)
5057+
TEST_F(UPROBE, uprobe_default_allow)
50225058
{
50235059
struct sock_filter filter[] = {
50245060
BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
@@ -5031,7 +5067,7 @@ TEST_F(URETPROBE, uretprobe_default_allow)
50315067
ASSERT_EQ(0, run_probed_with_filter(&prog));
50325068
}
50335069

5034-
TEST_F(URETPROBE, uretprobe_default_block)
5070+
TEST_F(UPROBE, uprobe_default_block)
50355071
{
50365072
struct sock_filter filter[] = {
50375073
BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
@@ -5048,11 +5084,14 @@ TEST_F(URETPROBE, uretprobe_default_block)
50485084
ASSERT_EQ(0, run_probed_with_filter(&prog));
50495085
}
50505086

5051-
TEST_F(URETPROBE, uretprobe_block_uretprobe_syscall)
5087+
TEST_F(UPROBE, uprobe_block_syscall)
50525088
{
50535089
struct sock_filter filter[] = {
50545090
BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
50555091
offsetof(struct seccomp_data, nr)),
5092+
#ifdef __NR_uprobe
5093+
BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_uprobe, 1, 2),
5094+
#endif
50565095
#ifdef __NR_uretprobe
50575096
BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_uretprobe, 0, 1),
50585097
#endif
@@ -5067,11 +5106,14 @@ TEST_F(URETPROBE, uretprobe_block_uretprobe_syscall)
50675106
ASSERT_EQ(0, run_probed_with_filter(&prog));
50685107
}
50695108

5070-
TEST_F(URETPROBE, uretprobe_default_block_with_uretprobe_syscall)
5109+
TEST_F(UPROBE, uprobe_default_block_with_syscall)
50715110
{
50725111
struct sock_filter filter[] = {
50735112
BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
50745113
offsetof(struct seccomp_data, nr)),
5114+
#ifdef __NR_uprobe
5115+
BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_uprobe, 3, 0),
5116+
#endif
50755117
#ifdef __NR_uretprobe
50765118
BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_uretprobe, 2, 0),
50775119
#endif

0 commit comments

Comments
 (0)