File: test_prctl.c

package info (click to toggle)
priv-wrapper 1.0.1-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 320 kB
  • sloc: ansic: 847; sh: 15; makefile: 11
file content (142 lines) | stat: -rw-r--r-- 3,184 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <stdint.h>
#include <cmocka.h>

#include <errno.h>
#include <stdlib.h>

#include <linux/seccomp.h>
#include <sys/prctl.h>

static int setup(void **state) {
	(void)state; /* unused */

	setenv("PRIV_WRAPPER", "1", 1);

	return 0;
}

static void test_prctl_ALL(void **state)
{
	int rc;

	(void)state; /* unused */

	setenv("PRIV_WRAPPER_PRCTL_DISABLE", "ALL", 1);

	rc = prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT);
	assert_return_code(rc, errno);

	rc = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
	assert_return_code(rc, errno);

	rc = prctl(PR_SET_NO_NEW_PRIVS, 0, 0, 0, 0);
	assert_return_code(rc, errno);

	rc = prctl(PR_SET_DUMPABLE, 2, 0, 0, 0); /* 2 is invalid value */
	assert_return_code(rc, errno);

	unsetenv("PRIV_WRAPPER_PRCTL_DISABLE");
}

static void test_prctl_PR_SET_SECCOMP(void **state)
{
	int rc;

	(void)state; /* unused */

	setenv("PRIV_WRAPPER_PRCTL_DISABLE", "PR_SET_SECCOMP", 1);
	rc = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, NULL, 0, 0);
	assert_return_code(rc, errno);
	unsetenv("PRIV_WRAPPER_PRCTL_DISABLE");
}

static void test_prctl_PR_SET_SECCOMP_fail(void **state)
{
	int rc;

	(void)state; /* unused */

	rc = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, NULL, 0, 0);
	assert_int_equal(rc, -1);
	/* alpha and sparc64 return EINVAL, which is OK for us. */
	if (errno == EINVAL)
		assert_int_equal(errno, EINVAL);
	else
		assert_int_equal(errno, EFAULT);
}

/* Once PR_SET_NO_NEW_PRIVS is set to 1, it cannot be reset to 0. */
static void test_prctl_PR_SET_NO_NEW_PRIVS(void **state)
{
	int rc;

	(void)state; /* unused */

	setenv("PRIV_WRAPPER_PRCTL_DISABLE", "PR_SET_NO_NEW_PRIVS", 1);

	rc = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
	assert_return_code(rc, errno);

	rc = prctl(PR_SET_NO_NEW_PRIVS, 0, 0, 0, 0);
	assert_return_code(rc, errno);

	unsetenv("PRIV_WRAPPER_PRCTL_DISABLE");
}

static void test_prctl_PR_SET_NO_NEW_PRIVS_fail(void **state)
{
	int rc;

	(void)state; /* unused */

	rc = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
	assert_return_code(rc, errno);

	rc = prctl(PR_SET_NO_NEW_PRIVS, 0, 0, 0, 0);
	assert_int_equal(rc, -1);
	assert_int_equal(errno, EINVAL);
}

/* arg==2 is an invalid value which fails with real prctl syscall */
static void test_prctl_PR_SET_DUMPABLE(void **state)
{
	int rc;

	(void)state; /* unused */

	setenv("PRIV_WRAPPER_PRCTL_DISABLE", "PR_SET_DUMPABLE", 1);
	rc = prctl(PR_SET_DUMPABLE, 2, 0, 0, 0);
	unsetenv("PRIV_WRAPPER_PRCTL_DISABLE");

	assert_return_code(rc, errno);
}

static void test_prctl_PR_SET_DUMPABLE_fail(void **state)
{
	int rc;

	(void)state; /* unused */

	rc = prctl(PR_SET_DUMPABLE, 2, 0, 0, 0);

	assert_int_equal(rc, -1);
	assert_int_equal(errno, EINVAL);
}

int main(void)
{
	const struct CMUnitTest tests[] = {
		cmocka_unit_test(test_prctl_ALL),
		cmocka_unit_test(test_prctl_PR_SET_SECCOMP),
		cmocka_unit_test(test_prctl_PR_SET_SECCOMP_fail),
		cmocka_unit_test(test_prctl_PR_SET_NO_NEW_PRIVS),
		cmocka_unit_test(test_prctl_PR_SET_NO_NEW_PRIVS_fail),
		cmocka_unit_test(test_prctl_PR_SET_DUMPABLE),
		cmocka_unit_test(test_prctl_PR_SET_DUMPABLE_fail),
	};

	return cmocka_run_group_tests(tests, setup, NULL);
}