diff options
author | Ron Yorston <rmy@pobox.com> | 2017-07-18 15:58:52 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2017-07-18 15:58:52 +0100 |
commit | b680f05ad449505e3d914bebd4c8d83bf768c094 (patch) | |
tree | c08ded13d430b0e7e0104f2eb594fad190ce98a3 /util-linux | |
parent | 258200ff81d5a9da54dab35acf36213eff1e399b (diff) | |
parent | 513a2457b65894b10b9fd6aa8753fca59eced08c (diff) | |
download | busybox-w32-b680f05ad449505e3d914bebd4c8d83bf768c094.tar.gz busybox-w32-b680f05ad449505e3d914bebd4c8d83bf768c094.tar.bz2 busybox-w32-b680f05ad449505e3d914bebd4c8d83bf768c094.zip |
Merge branch 'busybox' into merge
Diffstat (limited to 'util-linux')
-rw-r--r-- | util-linux/blkdiscard.c | 7 | ||||
-rw-r--r-- | util-linux/fdisk.c | 3 | ||||
-rwxr-xr-x | util-linux/mkfs_ext2_test.sh | 12 | ||||
-rw-r--r-- | util-linux/mount.c | 3 | ||||
-rw-r--r-- | util-linux/setpriv.c | 451 | ||||
-rw-r--r-- | util-linux/unshare.c | 7 |
6 files changed, 473 insertions, 10 deletions
diff --git a/util-linux/blkdiscard.c b/util-linux/blkdiscard.c index af0bc946d..85039c5d0 100644 --- a/util-linux/blkdiscard.c +++ b/util-linux/blkdiscard.c | |||
@@ -28,6 +28,13 @@ | |||
28 | #include "libbb.h" | 28 | #include "libbb.h" |
29 | #include <linux/fs.h> | 29 | #include <linux/fs.h> |
30 | 30 | ||
31 | #ifndef BLKDISCARD | ||
32 | #define BLKDISCARD 0x1277 | ||
33 | #endif | ||
34 | #ifndef BLKSECDISCARD | ||
35 | #define BLKSECDISCARD 0x127d | ||
36 | #endif | ||
37 | |||
31 | int blkdiscard_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 38 | int blkdiscard_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
32 | int blkdiscard_main(int argc UNUSED_PARAM, char **argv) | 39 | int blkdiscard_main(int argc UNUSED_PARAM, char **argv) |
33 | { | 40 | { |
diff --git a/util-linux/fdisk.c b/util-linux/fdisk.c index 916d4e30e..4467525c7 100644 --- a/util-linux/fdisk.c +++ b/util-linux/fdisk.c | |||
@@ -185,6 +185,8 @@ struct hd_geometry { | |||
185 | 185 | ||
186 | #define HDIO_GETGEO 0x0301 /* get device geometry */ | 186 | #define HDIO_GETGEO 0x0301 /* get device geometry */ |
187 | 187 | ||
188 | /* TODO: #if ENABLE_FEATURE_FDISK_WRITABLE */ | ||
189 | /* (currently fdisk_sun/sgi.c do not have proper WRITABLE #ifs) */ | ||
188 | static const char msg_building_new_label[] ALIGN1 = | 190 | static const char msg_building_new_label[] ALIGN1 = |
189 | "Building a new %s. Changes will remain in memory only,\n" | 191 | "Building a new %s. Changes will remain in memory only,\n" |
190 | "until you decide to write them. After that the previous content\n" | 192 | "until you decide to write them. After that the previous content\n" |
@@ -192,6 +194,7 @@ static const char msg_building_new_label[] ALIGN1 = | |||
192 | 194 | ||
193 | static const char msg_part_already_defined[] ALIGN1 = | 195 | static const char msg_part_already_defined[] ALIGN1 = |
194 | "Partition %u is already defined, delete it before re-adding\n"; | 196 | "Partition %u is already defined, delete it before re-adding\n"; |
197 | /* #endif */ | ||
195 | 198 | ||
196 | 199 | ||
197 | struct partition { | 200 | struct partition { |
diff --git a/util-linux/mkfs_ext2_test.sh b/util-linux/mkfs_ext2_test.sh index f5347cc04..df22963f2 100755 --- a/util-linux/mkfs_ext2_test.sh +++ b/util-linux/mkfs_ext2_test.sh | |||
@@ -47,7 +47,7 @@ test_mke2fs() { | |||
47 | kilobytes=60 | 47 | kilobytes=60 |
48 | while true; do | 48 | while true; do |
49 | test_mke2fs || exit 1 | 49 | test_mke2fs || exit 1 |
50 | : $((kilobytes++)) | 50 | kilobytes=$((kilobytes+1)) |
51 | test $kilobytes = 200 && break | 51 | test $kilobytes = 200 && break |
52 | done | 52 | done |
53 | 53 | ||
@@ -56,7 +56,7 @@ done | |||
56 | kilobytes=$((1 * 8*1024 - 50)) | 56 | kilobytes=$((1 * 8*1024 - 50)) |
57 | while true; do | 57 | while true; do |
58 | test_mke2fs || exit 1 | 58 | test_mke2fs || exit 1 |
59 | : $((kilobytes++)) | 59 | kilobytes=$((kilobytes+1)) |
60 | test $kilobytes = $((1 * 8*1024 + 300)) && break | 60 | test $kilobytes = $((1 * 8*1024 + 300)) && break |
61 | done | 61 | done |
62 | 62 | ||
@@ -65,7 +65,7 @@ done | |||
65 | kilobytes=$((2 * 8*1024 - 50)) | 65 | kilobytes=$((2 * 8*1024 - 50)) |
66 | while true; do | 66 | while true; do |
67 | test_mke2fs || exit 1 | 67 | test_mke2fs || exit 1 |
68 | : $((kilobytes++)) | 68 | kilobytes=$((kilobytes+1)) |
69 | test $kilobytes = $((2 * 8*1024 + 400)) && break | 69 | test $kilobytes = $((2 * 8*1024 + 400)) && break |
70 | done | 70 | done |
71 | 71 | ||
@@ -74,7 +74,7 @@ done | |||
74 | kilobytes=$((3 * 8*1024 - 50)) | 74 | kilobytes=$((3 * 8*1024 - 50)) |
75 | while true; do | 75 | while true; do |
76 | test_mke2fs || exit 1 | 76 | test_mke2fs || exit 1 |
77 | : $((kilobytes++)) | 77 | kilobytes=$((kilobytes+1)) |
78 | test $kilobytes = $((3 * 8*1024 + 500)) && break | 78 | test $kilobytes = $((3 * 8*1024 + 500)) && break |
79 | done | 79 | done |
80 | 80 | ||
@@ -83,7 +83,7 @@ done | |||
83 | kilobytes=$((4 * 8*1024 - 50)) | 83 | kilobytes=$((4 * 8*1024 - 50)) |
84 | while true; do | 84 | while true; do |
85 | test_mke2fs || exit 1 | 85 | test_mke2fs || exit 1 |
86 | : $((kilobytes++)) | 86 | kilobytes=$((kilobytes+1)) |
87 | test $kilobytes = $((4 * 8*1024 + 600)) && break | 87 | test $kilobytes = $((4 * 8*1024 + 600)) && break |
88 | done | 88 | done |
89 | 89 | ||
@@ -92,7 +92,7 @@ done | |||
92 | kilobytes=$((5 * 8*1024 - 50)) | 92 | kilobytes=$((5 * 8*1024 - 50)) |
93 | while true; do | 93 | while true; do |
94 | test_mke2fs || exit 1 | 94 | test_mke2fs || exit 1 |
95 | : $((kilobytes++)) | 95 | kilobytes=$((kilobytes+1)) |
96 | test $kilobytes = $((5 * 8*1024 + 700)) && break | 96 | test $kilobytes = $((5 * 8*1024 + 700)) && break |
97 | done | 97 | done |
98 | exit | 98 | exit |
diff --git a/util-linux/mount.c b/util-linux/mount.c index 6bb18524d..5fcc7958c 100644 --- a/util-linux/mount.c +++ b/util-linux/mount.c | |||
@@ -246,7 +246,8 @@ | |||
246 | /* This is just a warning of a common mistake. Possibly this should be a | 246 | /* This is just a warning of a common mistake. Possibly this should be a |
247 | * uclibc faq entry rather than in busybox... */ | 247 | * uclibc faq entry rather than in busybox... */ |
248 | # if defined(__UCLIBC__) && ! defined(__UCLIBC_HAS_RPC__) | 248 | # if defined(__UCLIBC__) && ! defined(__UCLIBC_HAS_RPC__) |
249 | # error "You need to build uClibc with UCLIBC_HAS_RPC for NFS support" | 249 | # warning "You probably need to build uClibc with UCLIBC_HAS_RPC for NFS support" |
250 | /* not #error, since user may be using e.g. libtirpc instead */ | ||
250 | # endif | 251 | # endif |
251 | # include <rpc/rpc.h> | 252 | # include <rpc/rpc.h> |
252 | # include <rpc/pmap_prot.h> | 253 | # include <rpc/pmap_prot.h> |
diff --git a/util-linux/setpriv.c b/util-linux/setpriv.c new file mode 100644 index 000000000..3d8dfea52 --- /dev/null +++ b/util-linux/setpriv.c | |||
@@ -0,0 +1,451 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * setpriv implementation for busybox based on linux-utils-ng 2.29 | ||
4 | * | ||
5 | * Copyright (C) 2017 by <assafgordon@gmail.com> | ||
6 | * | ||
7 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | ||
8 | * | ||
9 | */ | ||
10 | //config:config SETPRIV | ||
11 | //config: bool "setpriv" | ||
12 | //config: default y | ||
13 | //config: select PLATFORM_LINUX | ||
14 | //config: select LONG_OPTS | ||
15 | //config: help | ||
16 | //config: Run a program with different Linux privilege settings. | ||
17 | //config: Requires kernel >= 3.5 | ||
18 | //config: | ||
19 | //config:config FEATURE_SETPRIV_DUMP | ||
20 | //config: bool "Support dumping current privilege state" | ||
21 | //config: default y | ||
22 | //config: depends on SETPRIV | ||
23 | //config: help | ||
24 | //config: Enables the "--dump" switch to print out the current privilege | ||
25 | //config: state. This is helpful for diagnosing problems. | ||
26 | //config: | ||
27 | //config:config FEATURE_SETPRIV_CAPABILITIES | ||
28 | //config: bool "Support capabilities" | ||
29 | //config: default y | ||
30 | //config: depends on SETPRIV | ||
31 | //config: help | ||
32 | //config: Capabilities can be used to grant processes additional rights | ||
33 | //config: without the necessity to always execute as the root user. | ||
34 | //config: Enabling this option enables "--dump" to show information on | ||
35 | //config: capabilities. | ||
36 | //config: | ||
37 | //config:config FEATURE_SETPRIV_CAPABILITY_NAMES | ||
38 | //config: bool "Support capability names" | ||
39 | //config: default y | ||
40 | //config: depends on SETPRIV && FEATURE_SETPRIV_CAPABILITIES | ||
41 | //config: help | ||
42 | //config: Capabilities can be either referenced via a human-readble name, | ||
43 | //config: e.g. "net_admin", or using their index, e.g. "cap_12". Enabling | ||
44 | //config: this option allows using the human-readable names in addition to | ||
45 | //config: the index-based names. | ||
46 | |||
47 | //applet:IF_SETPRIV(APPLET(setpriv, BB_DIR_BIN, BB_SUID_DROP)) | ||
48 | |||
49 | //kbuild:lib-$(CONFIG_SETPRIV) += setpriv.o | ||
50 | |||
51 | //usage:#define setpriv_trivial_usage | ||
52 | //usage: "[OPTIONS] PROG [ARGS]" | ||
53 | //usage:#define setpriv_full_usage "\n\n" | ||
54 | //usage: "Run PROG with different privilege settings\n" | ||
55 | //usage: IF_FEATURE_SETPRIV_DUMP( | ||
56 | //usage: "\n-d,--dump Show current capabilities" | ||
57 | //usage: ) | ||
58 | //usage: "\n--nnp,--no-new-privs Ignore setuid/setgid bits and file capabilities" | ||
59 | //usage: IF_FEATURE_SETPRIV_CAPABILITIES( | ||
60 | //usage: "\n--inh-caps CAP,CAP Set inheritable capabilities" | ||
61 | //usage: "\n--ambient-caps CAP,CAP Set ambient capabilities" | ||
62 | //usage: ) | ||
63 | |||
64 | //setpriv from util-linux 2.28: | ||
65 | // -d, --dump show current state (and do not exec anything) | ||
66 | // --nnp, --no-new-privs disallow granting new privileges | ||
67 | // --inh-caps <caps,...> set inheritable capabilities | ||
68 | // --bounding-set <caps> set capability bounding set | ||
69 | // --ruid <uid> set real uid | ||
70 | // --euid <uid> set effective uid | ||
71 | // --rgid <gid> set real gid | ||
72 | // --egid <gid> set effective gid | ||
73 | // --reuid <uid> set real and effective uid | ||
74 | // --regid <gid> set real and effective gid | ||
75 | // --clear-groups clear supplementary groups | ||
76 | // --keep-groups keep supplementary groups | ||
77 | // --groups <group,...> set supplementary groups | ||
78 | // --securebits <bits> set securebits | ||
79 | // --selinux-label <label> set SELinux label | ||
80 | // --apparmor-profile <pr> set AppArmor profile | ||
81 | |||
82 | #if ENABLE_FEATURE_SETPRIV_CAPABILITIES | ||
83 | #include <linux/capability.h> | ||
84 | // #include <sys/capability.h> | ||
85 | // This header is in libcap, but the functions are in libc. | ||
86 | // Comment in the header says this above capset/capget: | ||
87 | /* system calls - look to libc for function to system call mapping */ | ||
88 | extern int capset(cap_user_header_t header, cap_user_data_t data); | ||
89 | extern int capget(cap_user_header_t header, const cap_user_data_t data); | ||
90 | // so for bbox, let's just repeat the declarations. | ||
91 | // This way, libcap needs not be installed in build environment. | ||
92 | #endif | ||
93 | #include <sys/prctl.h> | ||
94 | #include "libbb.h" | ||
95 | |||
96 | #ifndef PR_CAPBSET_READ | ||
97 | #define PR_CAPBSET_READ 23 | ||
98 | #endif | ||
99 | |||
100 | #ifndef PR_SET_NO_NEW_PRIVS | ||
101 | #define PR_SET_NO_NEW_PRIVS 38 | ||
102 | #endif | ||
103 | |||
104 | #ifndef PR_GET_NO_NEW_PRIVS | ||
105 | #define PR_GET_NO_NEW_PRIVS 39 | ||
106 | #endif | ||
107 | |||
108 | #ifndef PR_CAP_AMBIENT | ||
109 | #define PR_CAP_AMBIENT 47 | ||
110 | #define PR_CAP_AMBIENT_IS_SET 1 | ||
111 | #define PR_CAP_AMBIENT_RAISE 2 | ||
112 | #define PR_CAP_AMBIENT_LOWER 3 | ||
113 | #endif | ||
114 | |||
115 | enum { | ||
116 | IF_FEATURE_SETPRIV_DUMP(OPTBIT_DUMP,) | ||
117 | IF_FEATURE_SETPRIV_CAPABILITIES(OPTBIT_INH,) | ||
118 | IF_FEATURE_SETPRIV_CAPABILITIES(OPTBIT_AMB,) | ||
119 | OPTBIT_NNP, | ||
120 | |||
121 | IF_FEATURE_SETPRIV_DUMP(OPT_DUMP = (1 << OPTBIT_DUMP),) | ||
122 | IF_FEATURE_SETPRIV_CAPABILITIES(OPT_INH = (1 << OPTBIT_INH),) | ||
123 | IF_FEATURE_SETPRIV_CAPABILITIES(OPT_AMB = (1 << OPTBIT_AMB),) | ||
124 | OPT_NNP = (1 << OPTBIT_NNP), | ||
125 | }; | ||
126 | |||
127 | #if ENABLE_FEATURE_SETPRIV_CAPABILITIES | ||
128 | struct caps { | ||
129 | struct __user_cap_header_struct header; | ||
130 | cap_user_data_t data; | ||
131 | int u32s; | ||
132 | }; | ||
133 | |||
134 | # if ENABLE_FEATURE_SETPRIV_CAPABILITY_NAMES | ||
135 | static const char *const capabilities[] = { | ||
136 | "chown", | ||
137 | "dac_override", | ||
138 | "dac_read_search", | ||
139 | "fowner", | ||
140 | "fsetid", | ||
141 | "kill", | ||
142 | "setgid", | ||
143 | "setuid", | ||
144 | "setpcap", | ||
145 | "linux_immutable", | ||
146 | "net_bind_service", | ||
147 | "net_broadcast", | ||
148 | "net_admin", | ||
149 | "net_raw", | ||
150 | "ipc_lock", | ||
151 | "ipc_owner", | ||
152 | "sys_module", | ||
153 | "sys_rawio", | ||
154 | "sys_chroot", | ||
155 | "sys_ptrace", | ||
156 | "sys_pacct", | ||
157 | "sys_admin", | ||
158 | "sys_boot", | ||
159 | "sys_nice", | ||
160 | "sys_resource", | ||
161 | "sys_time", | ||
162 | "sys_tty_config", | ||
163 | "mknod", | ||
164 | "lease", | ||
165 | "audit_write", | ||
166 | "audit_control", | ||
167 | "setfcap", | ||
168 | "mac_override", | ||
169 | "mac_admin", | ||
170 | "syslog", | ||
171 | "wake_alarm", | ||
172 | "block_suspend", | ||
173 | "audit_read", | ||
174 | }; | ||
175 | # endif /* FEATURE_SETPRIV_CAPABILITY_NAMES */ | ||
176 | |||
177 | static void getcaps(struct caps *caps) | ||
178 | { | ||
179 | static const uint8_t versions[] = { | ||
180 | _LINUX_CAPABILITY_U32S_3, /* = 2 (fits into byte) */ | ||
181 | _LINUX_CAPABILITY_U32S_2, /* = 2 */ | ||
182 | _LINUX_CAPABILITY_U32S_1, /* = 1 */ | ||
183 | }; | ||
184 | int i; | ||
185 | |||
186 | caps->header.pid = 0; | ||
187 | for (i = 0; i < ARRAY_SIZE(versions); i++) { | ||
188 | caps->header.version = versions[i]; | ||
189 | if (capget(&caps->header, NULL) == 0) | ||
190 | goto got_it; | ||
191 | } | ||
192 | bb_simple_perror_msg_and_die("capget"); | ||
193 | got_it: | ||
194 | |||
195 | switch (caps->header.version) { | ||
196 | case _LINUX_CAPABILITY_VERSION_1: | ||
197 | caps->u32s = _LINUX_CAPABILITY_U32S_1; | ||
198 | break; | ||
199 | case _LINUX_CAPABILITY_VERSION_2: | ||
200 | caps->u32s = _LINUX_CAPABILITY_U32S_2; | ||
201 | break; | ||
202 | case _LINUX_CAPABILITY_VERSION_3: | ||
203 | caps->u32s = _LINUX_CAPABILITY_U32S_3; | ||
204 | break; | ||
205 | default: | ||
206 | bb_error_msg_and_die("unsupported capability version"); | ||
207 | } | ||
208 | |||
209 | caps->data = xmalloc(sizeof(caps->data[0]) * caps->u32s); | ||
210 | if (capget(&caps->header, caps->data) < 0) | ||
211 | bb_simple_perror_msg_and_die("capget"); | ||
212 | } | ||
213 | |||
214 | static void parse_cap(unsigned long *index, const char *cap) | ||
215 | { | ||
216 | unsigned long i; | ||
217 | |||
218 | switch (cap[0]) { | ||
219 | case '-': | ||
220 | break; | ||
221 | case '+': | ||
222 | break; | ||
223 | default: | ||
224 | bb_error_msg_and_die("invalid capability '%s'", cap); | ||
225 | break; | ||
226 | } | ||
227 | |||
228 | cap++; | ||
229 | if ((sscanf(cap, "cap_%lu", &i)) == 1) { | ||
230 | if (!cap_valid(i)) | ||
231 | bb_error_msg_and_die("unsupported capability '%s'", cap); | ||
232 | *index = i; | ||
233 | return; | ||
234 | } | ||
235 | |||
236 | # if ENABLE_FEATURE_SETPRIV_CAPABILITY_NAMES | ||
237 | for (i = 0; i < ARRAY_SIZE(capabilities); i++) { | ||
238 | if (strcmp(capabilities[i], cap) != 0) | ||
239 | continue; | ||
240 | |||
241 | if (!cap_valid(i)) | ||
242 | bb_error_msg_and_die("unsupported capability '%s'", cap); | ||
243 | *index = i; | ||
244 | return; | ||
245 | } | ||
246 | # endif | ||
247 | |||
248 | bb_error_msg_and_die("unknown capability '%s'", cap); | ||
249 | } | ||
250 | |||
251 | static void set_inh_caps(char *capstring) | ||
252 | { | ||
253 | struct caps caps; | ||
254 | |||
255 | getcaps(&caps); | ||
256 | |||
257 | capstring = strtok(capstring, ","); | ||
258 | while (capstring) { | ||
259 | unsigned long cap; | ||
260 | |||
261 | parse_cap(&cap, capstring); | ||
262 | if (CAP_TO_INDEX(cap) >= caps.u32s) | ||
263 | bb_error_msg_and_die("invalid capability cap"); | ||
264 | |||
265 | if (capstring[0] == '+') | ||
266 | caps.data[CAP_TO_INDEX(cap)].inheritable |= CAP_TO_MASK(cap); | ||
267 | else | ||
268 | caps.data[CAP_TO_INDEX(cap)].inheritable &= ~CAP_TO_MASK(cap); | ||
269 | capstring = strtok(NULL, ","); | ||
270 | } | ||
271 | |||
272 | if ((capset(&caps.header, caps.data)) < 0) | ||
273 | bb_perror_msg_and_die("capset"); | ||
274 | |||
275 | if (ENABLE_FEATURE_CLEAN_UP) | ||
276 | free(caps.data); | ||
277 | } | ||
278 | |||
279 | static void set_ambient_caps(char *string) | ||
280 | { | ||
281 | char *cap; | ||
282 | |||
283 | cap = strtok(string, ","); | ||
284 | while (cap) { | ||
285 | unsigned long index; | ||
286 | |||
287 | parse_cap(&index, cap); | ||
288 | if (cap[0] == '+') { | ||
289 | if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, index, 0, 0) < 0) | ||
290 | bb_perror_msg("cap_ambient_raise"); | ||
291 | } else { | ||
292 | if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_LOWER, index, 0, 0) < 0) | ||
293 | bb_perror_msg("cap_ambient_lower"); | ||
294 | } | ||
295 | cap = strtok(NULL, ","); | ||
296 | } | ||
297 | } | ||
298 | #endif /* FEATURE_SETPRIV_CAPABILITIES */ | ||
299 | |||
300 | #if ENABLE_FEATURE_SETPRIV_DUMP | ||
301 | # if ENABLE_FEATURE_SETPRIV_CAPABILITY_NAMES | ||
302 | static void printf_cap(const char *pfx, unsigned cap_no) | ||
303 | { | ||
304 | if (cap_no < ARRAY_SIZE(capabilities)) { | ||
305 | printf("%s%s", pfx, capabilities[cap_no]); | ||
306 | return; | ||
307 | } | ||
308 | printf("%scap_%u", pfx, cap_no); | ||
309 | } | ||
310 | # else | ||
311 | # define printf_cap(pfx, cap_no) printf("%scap_%u", (pfx), (cap_no)) | ||
312 | # endif | ||
313 | |||
314 | static int dump(void) | ||
315 | { | ||
316 | IF_FEATURE_SETPRIV_CAPABILITIES(struct caps caps;) | ||
317 | const char *fmt; | ||
318 | uid_t ruid, euid, suid; | ||
319 | gid_t rgid, egid, sgid; | ||
320 | gid_t *gids; | ||
321 | int i, ngids, nnp; | ||
322 | |||
323 | getresuid(&ruid, &euid, &suid); /* never fails in Linux */ | ||
324 | getresgid(&rgid, &egid, &sgid); /* never fails in Linux */ | ||
325 | ngids = 0; | ||
326 | gids = bb_getgroups(&ngids, NULL); /* never fails in Linux */ | ||
327 | |||
328 | nnp = prctl(PR_GET_NO_NEW_PRIVS, 0, 0, 0, 0); | ||
329 | if (nnp < 0) | ||
330 | bb_perror_msg_and_die("prctl: %s", "GET_NO_NEW_PRIVS"); | ||
331 | |||
332 | printf("uid: %u\n", (unsigned)ruid); | ||
333 | printf("euid: %u\n", (unsigned)euid); | ||
334 | printf("gid: %u\n", (unsigned)rgid); | ||
335 | printf("egid: %u\n", (unsigned)egid); | ||
336 | |||
337 | printf("Supplementary groups: "); | ||
338 | if (ngids == 0) { | ||
339 | printf("[none]"); | ||
340 | } else { | ||
341 | fmt = ",%u" + 1; | ||
342 | for (i = 0; i < ngids; i++) { | ||
343 | printf(fmt, (unsigned)gids[i]); | ||
344 | fmt = ",%u"; | ||
345 | } | ||
346 | } | ||
347 | printf("\nno_new_privs: %d\n", nnp); | ||
348 | |||
349 | # if ENABLE_FEATURE_SETPRIV_CAPABILITIES | ||
350 | getcaps(&caps); | ||
351 | printf("Inheritable capabilities: "); | ||
352 | fmt = ""; | ||
353 | for (i = 0; cap_valid(i); i++) { | ||
354 | unsigned idx = CAP_TO_INDEX(i); | ||
355 | if (idx >= caps.u32s) { | ||
356 | printf("\nindex: %u u32s: %u capability: %u\n", idx, caps.u32s, i); | ||
357 | bb_error_msg_and_die("unsupported capability"); | ||
358 | } | ||
359 | if (caps.data[idx].inheritable & CAP_TO_MASK(i)) { | ||
360 | printf_cap(fmt, i); | ||
361 | fmt = ","; | ||
362 | } | ||
363 | } | ||
364 | if (!fmt[0]) | ||
365 | printf("[none]"); | ||
366 | |||
367 | printf("\nAmbient capabilities: "); | ||
368 | fmt = ""; | ||
369 | for (i = 0; cap_valid(i); i++) { | ||
370 | int ret = prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, (unsigned long) i, 0UL, 0UL); | ||
371 | if (ret < 0) | ||
372 | bb_perror_msg_and_die("prctl: %s", "CAP_AMBIENT_IS_SET"); | ||
373 | if (ret) { | ||
374 | printf_cap(fmt, i); | ||
375 | fmt = ","; | ||
376 | } | ||
377 | } | ||
378 | if (i == 0) | ||
379 | printf("[unsupported]"); | ||
380 | else if (!fmt[0]) | ||
381 | printf("[none]"); | ||
382 | |||
383 | printf("\nCapability bounding set: "); | ||
384 | fmt = ""; | ||
385 | for (i = 0; cap_valid(i); i++) { | ||
386 | int ret = prctl(PR_CAPBSET_READ, (unsigned long) i, 0UL, 0UL, 0UL); | ||
387 | if (ret < 0) | ||
388 | bb_perror_msg_and_die("prctl: %s", "CAPBSET_READ"); | ||
389 | if (ret) { | ||
390 | printf_cap(fmt, i); | ||
391 | fmt = ","; | ||
392 | } | ||
393 | } | ||
394 | if (!fmt[0]) | ||
395 | printf("[none]"); | ||
396 | bb_putchar('\n'); | ||
397 | # endif | ||
398 | |||
399 | if (ENABLE_FEATURE_CLEAN_UP) { | ||
400 | IF_FEATURE_SETPRIV_CAPABILITIES(free(caps.data);) | ||
401 | free(gids); | ||
402 | } | ||
403 | return EXIT_SUCCESS; | ||
404 | } | ||
405 | #endif /* FEATURE_SETPRIV_DUMP */ | ||
406 | |||
407 | int setpriv_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
408 | int setpriv_main(int argc UNUSED_PARAM, char **argv) | ||
409 | { | ||
410 | static const char setpriv_longopts[] ALIGN1 = | ||
411 | IF_FEATURE_SETPRIV_DUMP( | ||
412 | "dump\0" No_argument "d" | ||
413 | ) | ||
414 | "nnp\0" No_argument "\xff" | ||
415 | "no-new-privs\0" No_argument "\xff" | ||
416 | IF_FEATURE_SETPRIV_CAPABILITIES( | ||
417 | "inh-caps\0" Required_argument "\xfe" | ||
418 | "ambient-caps\0" Required_argument "\xfd" | ||
419 | ) | ||
420 | ; | ||
421 | int opts; | ||
422 | IF_FEATURE_SETPRIV_CAPABILITIES(char *inh_caps, *ambient_caps;) | ||
423 | |||
424 | applet_long_options = setpriv_longopts; | ||
425 | opts = getopt32(argv, "+"IF_FEATURE_SETPRIV_DUMP("d") | ||
426 | IF_FEATURE_SETPRIV_CAPABILITIES("\xfe:\xfd:", &inh_caps, &ambient_caps)); | ||
427 | argv += optind; | ||
428 | |||
429 | #if ENABLE_FEATURE_SETPRIV_DUMP | ||
430 | if (opts & OPT_DUMP) { | ||
431 | if (argv[0] || (opts - OPT_DUMP) != 0) | ||
432 | bb_show_usage(); | ||
433 | return dump(); | ||
434 | } | ||
435 | #endif | ||
436 | if (opts & OPT_NNP) { | ||
437 | if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) | ||
438 | bb_perror_msg_and_die("prctl: %s", "SET_NO_NEW_PRIVS"); | ||
439 | } | ||
440 | |||
441 | #if ENABLE_FEATURE_SETPRIV_CAPABILITIES | ||
442 | if (opts & OPT_INH) | ||
443 | set_inh_caps(inh_caps); | ||
444 | if (opts & OPT_AMB) | ||
445 | set_ambient_caps(ambient_caps); | ||
446 | #endif | ||
447 | |||
448 | if (!argv[0]) | ||
449 | bb_show_usage(); | ||
450 | BB_EXECVP_or_die(argv); | ||
451 | } | ||
diff --git a/util-linux/unshare.c b/util-linux/unshare.c index 52e8f1421..875e3f86e 100644 --- a/util-linux/unshare.c +++ b/util-linux/unshare.c | |||
@@ -9,12 +9,13 @@ | |||
9 | //config:config UNSHARE | 9 | //config:config UNSHARE |
10 | //config: bool "unshare" | 10 | //config: bool "unshare" |
11 | //config: default y | 11 | //config: default y |
12 | //config: depends on LONG_OPTS && !NOMMU | 12 | //config: depends on !NOMMU |
13 | //config: select PLATFORM_LINUX | 13 | //config: select PLATFORM_LINUX |
14 | //config: select LONG_OPTS | ||
14 | //config: help | 15 | //config: help |
15 | //config: Run program with some namespaces unshared from parent. | 16 | //config: Run program with some namespaces unshared from parent. |
16 | 17 | ||
17 | // depends on LONG_OPTS: it is awkward to exclude code which handles --propagation | 18 | // needs LONG_OPTS: it is awkward to exclude code which handles --propagation |
18 | // and --setgroups based on LONG_OPTS, so instead applet requires LONG_OPTS. | 19 | // and --setgroups based on LONG_OPTS, so instead applet requires LONG_OPTS. |
19 | // depends on !NOMMU: we need fork() | 20 | // depends on !NOMMU: we need fork() |
20 | 21 | ||
@@ -32,7 +33,7 @@ | |||
32 | //usage: "\n -p,--pid[=FILE] Unshare PID namespace" | 33 | //usage: "\n -p,--pid[=FILE] Unshare PID namespace" |
33 | //usage: "\n -U,--user[=FILE] Unshare user namespace" | 34 | //usage: "\n -U,--user[=FILE] Unshare user namespace" |
34 | //usage: "\n -f,--fork Fork before execing PROG" | 35 | //usage: "\n -f,--fork Fork before execing PROG" |
35 | //usage: "\n -r,--map-root-user Map current user to root (implies -u)" | 36 | //usage: "\n -r,--map-root-user Map current user to root (implies -U)" |
36 | //usage: "\n --mount-proc[=DIR] Mount /proc filesystem first (implies -m)" | 37 | //usage: "\n --mount-proc[=DIR] Mount /proc filesystem first (implies -m)" |
37 | //usage: "\n --propagation slave|shared|private|unchanged" | 38 | //usage: "\n --propagation slave|shared|private|unchanged" |
38 | //usage: "\n Modify mount propagation in mount namespace" | 39 | //usage: "\n Modify mount propagation in mount namespace" |