xref: /aosp_15_r20/external/libcap-ng/src/cap-ng.c (revision 8dd5e09d5faf27a871e8654ddaa2d2af7c696578)
1 /* libcap-ng.c --
2  * Copyright 2009-10, 2013, 2017, 2020-21 Red Hat Inc.
3  * All Rights Reserved.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with this program; see the file COPYING.LIB. If not, write to the
17  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor
18  * Boston, MA 02110-1335, USA.
19  *
20  * Authors:
21  *      Steve Grubb <[email protected]>
22  */
23 
24 #include "config.h"
25 #include "cap-ng.h"
26 #include <string.h>
27 #include <stdarg.h>
28 #include <stdio.h>
29 #include <stdio_ext.h>
30 #include <stdlib.h>
31 #include <sys/prctl.h>
32 #include <pwd.h>
33 #include <grp.h>
34 #include <sys/stat.h>
35 #include <errno.h>
36 #include <fcntl.h>
37 #include <endian.h>
38 #include <byteswap.h>
39 #ifdef HAVE_PTHREAD_H
40 #include <pthread.h>	// For pthread_atfork
41 #endif
42 #ifdef HAVE_SYSCALL_H
43 #include <sys/syscall.h>
44 #endif
45 #ifdef HAVE_LINUX_SECUREBITS_H
46 #include <linux/securebits.h>
47 #endif
48 #ifdef HAVE_LINUX_MAGIC_H
49 #include <sys/vfs.h>
50 #include <linux/magic.h>
51 #endif
52 
53 # define hidden __attribute__ ((visibility ("hidden")))
54 unsigned int last_cap hidden = 0;
55 /*
56  * Some milestones of when things became available:
57  * 2.6.24 kernel	XATTR_NAME_CAPS
58  * 2.6.25 kernel	PR_CAPBSET_DROP, CAPABILITY_VERSION_2
59  * 2.6.26 kernel	PR_SET_SECUREBITS, SECURE_*_LOCKED, VERSION_3
60  * 3.5    kernel	PR_SET_NO_NEW_PRIVS
61  * 4.3    kernel	PR_CAP_AMBIENT
62  * 4.14   kernel	VFS_CAP_REVISION_3
63  */
64 #ifdef PR_CAPBSET_DROP
65 static int HAVE_PR_CAPBSET_DROP = 0;
66 #endif
67 #ifdef PR_SET_SECUREBITS
68 static int HAVE_PR_SET_SECUREBITS = 0;
69 #endif
70 #ifdef PR_SET_NO_NEW_PRIVS
71 static int HAVE_PR_SET_NO_NEW_PRIVS = 0;
72 #endif
73 #ifdef PR_CAP_AMBIENT
74 static int HAVE_PR_CAP_AMBIENT = 0;
75 #endif
76 
77 /* External syscall prototypes */
78 extern int capset(cap_user_header_t header, cap_user_data_t data);
79 extern int capget(cap_user_header_t header, const cap_user_data_t data);
80 
81 // Local functions
82 static void update_bounding_set(capng_act_t action, unsigned int capability,
83 	unsigned int idx);
84 static void update_ambient_set(capng_act_t action, unsigned int capability,
85 	unsigned int idx);
86 
87 // Local defines
88 #define MASK(x) (1U << (x))
89 #ifdef PR_CAPBSET_DROP
90 #define UPPER_MASK ~((~0U)<<(last_cap-31))
91 #else
92 // For v1 systems UPPER_MASK will never be used
93 #define UPPER_MASK (unsigned)(~0U)
94 #endif
95 
96 // Re-define cap_valid so its uniform between V1 and V3
97 #undef cap_valid
98 #define cap_valid(x) ((x) <= last_cap)
99 
100 // If we don't have the xattr library, then we can't
101 // compile-in file system capabilities
102 #if !defined(HAVE_ATTR_XATTR_H) && !defined (HAVE_SYS_XATTR_H)
103 #undef VFS_CAP_U32
104 #endif
105 
106 #ifdef VFS_CAP_U32
107  #ifdef HAVE_SYS_XATTR_H
108    #include <sys/xattr.h>
109  #else
110   #ifdef HAVE_ATTR_XATTR_H
111    #include <attr/xattr.h>
112   #endif
113  #endif
114  #if __BYTE_ORDER == __BIG_ENDIAN
115   #define FIXUP(x) bswap_32(x)
116  #else
117   #define FIXUP(x) (x)
118  #endif
119 #endif
120 
121 #ifndef _LINUX_CAPABILITY_VERSION_1
122 #define _LINUX_CAPABILITY_VERSION_1 0x19980330
123 #endif
124 #ifndef _LINUX_CAPABILITY_VERSION_2
125 #define _LINUX_CAPABILITY_VERSION_2 0x20071026
126 #endif
127 #ifndef _LINUX_CAPABILITY_VERSION_3
128 #define _LINUX_CAPABILITY_VERSION_3 0x20080522
129 #endif
130 
131 // This public API went private in the 2.6.36 kernel - hope it never changes
132 #ifndef XATTR_CAPS_SUFFIX
133 #define XATTR_CAPS_SUFFIX "capability"
134 #endif
135 #ifndef XATTR_SECURITY_PREFIX
136 #define XATTR_SECURITY_PREFIX "security."
137 #endif
138 #ifndef XATTR_NAME_CAPS
139 #define XATTR_NAME_CAPS XATTR_SECURITY_PREFIX XATTR_CAPS_SUFFIX
140 #endif
141 
142 
143 /* Child processes can't get caps back */
144 #ifndef SECURE_NOROOT
145 #define SECURE_NOROOT                   0
146 #endif
147 #ifndef SECURE_NOROOT_LOCKED
148 #define SECURE_NOROOT_LOCKED            1  /* make bit-0 immutable */
149 #endif
150 /* Setuid apps run by uid 0 don't get caps back */
151 #ifndef SECURE_NO_SETUID_FIXUP
152 #define SECURE_NO_SETUID_FIXUP          2
153 #endif
154 #ifndef SECURE_NO_SETUID_FIXUP_LOCKED
155 #define SECURE_NO_SETUID_FIXUP_LOCKED   3  /* make bit-2 immutable */
156 #endif
157 
158 #ifndef VFS_CAP_U32
159 #define VFS_CAP_U32 2
160 #endif
161 
162 #if (VFS_CAP_U32 != 2)
163 #error VFS_CAP_U32 does not match the library, you need a new version
164 #endif
165 
166 
167 // States: new, allocated, initted, updated, applied
168 typedef enum { CAPNG_NEW, CAPNG_ERROR, CAPNG_ALLOCATED, CAPNG_INIT,
169 	CAPNG_UPDATED, CAPNG_APPLIED } capng_states_t;
170 
171 // Create an easy data struct out of the kernel definitions
172 typedef union {
173 	struct __user_cap_data_struct v1;
174 	struct __user_cap_data_struct v3[VFS_CAP_U32];
175 } cap_data_t;
176 
177 // This struct keeps all state info
178 struct cap_ng
179 {
180 	int cap_ver;
181 	int vfs_cap_ver;
182 	struct __user_cap_header_struct hdr;
183 	cap_data_t data;
184 	capng_states_t state;
185 	__le32 rootid;
186 	__u32 bounds[VFS_CAP_U32];
187 	__u32 ambient[VFS_CAP_U32];
188 };
189 
190 // Global variables with per thread uniqueness
191 static __thread struct cap_ng m =	{ 1, 1,
192 					{0, 0},
193 					{ {0, 0, 0} },
194 					CAPNG_NEW, CAPNG_UNSET_ROOTID,
195 					{0, 0},
196 					{0, 0} };
197 
198 /*
199  * Reset the state so that init gets called to erase everything
200  */
deinit(void)201 static void deinit(void)
202 {
203 	m.state = CAPNG_NEW;
204 }
205 
test_cap(unsigned int cap)206 static inline int test_cap(unsigned int cap)
207 {
208 	// prctl returns 0 or 1 for valid caps, -1 otherwise
209 	return prctl(PR_CAPBSET_READ, cap) >= 0;
210 }
211 
212 // The maximum cap value is determined by VFS_CAP_U32
213 #define MAX_CAP_VALUE (VFS_CAP_U32 * sizeof(__le32) * 8)
214 
215 static void init_lib(void) __attribute__ ((constructor));
init_lib(void)216 static void init_lib(void)
217 {
218        // This is so dynamic libraries don't re-init
219        static unsigned int run_once = 0;
220        if (run_once)
221                return;
222        run_once = 1;
223 
224 #ifdef HAVE_PTHREAD_H
225 	pthread_atfork(NULL, NULL, deinit);
226 #endif
227 	// Detect last cap
228 	if (last_cap == 0) {
229 		int fd;
230 
231 		// Try to read last cap from procfs
232 		fd = open("/proc/sys/kernel/cap_last_cap", O_RDONLY);
233 		if (fd >= 0) {
234 #ifdef HAVE_LINUX_MAGIC_H
235 			struct statfs st;
236 			// Bail out if procfs is invalid or fstatfs fails
237 			if (fstatfs(fd, &st) || st.f_type != PROC_SUPER_MAGIC)
238 				goto fail;
239 #endif
240 			char buf[8];
241 			int num = read(fd, buf, sizeof(buf) - 1);
242 			if (num > 0) {
243 				buf[num] = 0;
244 				errno = 0;
245 				unsigned int val = strtoul(buf, NULL, 10);
246 				if (errno == 0)
247 					last_cap = val;
248 			}
249 fail:
250 			close(fd);
251 		}
252 		// Run a binary search over capabilities
253 		if (last_cap == 0) {
254 			// starting with last_cap=MAX_CAP_VALUE means we always know
255 			// that cap1 is invalid after the first iteration
256 			last_cap = MAX_CAP_VALUE;
257 			unsigned int cap0 = 0, cap1 = MAX_CAP_VALUE;
258 
259 			while (cap0 < last_cap) {
260 				if (test_cap(last_cap))
261 					cap0 = last_cap;
262 				else
263 					cap1 = last_cap;
264 
265 				last_cap = (cap0 + cap1) / 2U;
266 			}
267 		}
268 	}
269 	// Detect prctl options at runtime
270 #ifdef PR_CAPBSET_DROP
271 	errno = 0;
272 	prctl(PR_CAPBSET_READ, 0, 0, 0, 0);
273 	if (!errno)
274 		HAVE_PR_CAPBSET_DROP = 1;
275 #endif
276 #ifdef PR_SET_SECUREBITS
277 	errno = 0;
278 	prctl(PR_GET_SECUREBITS, 0, 0, 0, 0);
279 	if (!errno)
280 		HAVE_PR_SET_SECUREBITS = 1;
281 #endif
282 #ifdef PR_SET_NO_NEW_PRIVS
283 	errno = 0;
284 	prctl(PR_GET_NO_NEW_PRIVS, 0, 0, 0, 0);
285 	if (!errno)
286 		HAVE_PR_SET_NO_NEW_PRIVS = 1;
287 #endif
288 #ifdef PR_CAP_AMBIENT
289 	errno = 0;
290 	prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, 0, 0, 0);
291 	if (!errno)
292 		HAVE_PR_CAP_AMBIENT = 1;
293 #endif
294 }
295 
init(void)296 static void init(void)
297 {
298 	// This is so static libs get initialized
299 	init_lib();
300 
301 	if (m.state != CAPNG_NEW)
302 		return;
303 
304 	memset(&m.hdr, 0, sizeof(m.hdr));
305 	(void)capget(&m.hdr, NULL); // Returns -EINVAL
306 	if (m.hdr.version == _LINUX_CAPABILITY_VERSION_3 ||
307 		m.hdr.version == _LINUX_CAPABILITY_VERSION_2) {
308 		m.cap_ver = 3;
309 	} else if (m.hdr.version == _LINUX_CAPABILITY_VERSION_1) {
310 		m.cap_ver = 1;
311 	} else {
312 		m.state = CAPNG_ERROR;
313 		return;
314 	}
315 
316 #if VFS_CAP_REVISION == VFS_CAP_REVISION_1
317 	m.vfs_cap_ver = 1;
318 #else
319 	m.vfs_cap_ver = 2; // Intentionally set to 2 for both 2 & 3
320 #endif
321 
322 	memset(&m.data, 0, sizeof(cap_data_t));
323 #ifdef HAVE_SYSCALL_H
324 	m.hdr.pid = (unsigned)syscall(__NR_gettid);
325 #else
326 	m.hdr.pid = (unsigned)getpid();
327 #endif
328 	m.rootid = CAPNG_UNSET_ROOTID;
329 	m.state = CAPNG_ALLOCATED;
330 }
331 
capng_clear(capng_select_t set)332 void capng_clear(capng_select_t set)
333 {
334 	if (m.state == CAPNG_NEW)
335 		init();
336 	if (m.state == CAPNG_ERROR)
337 		return;
338 
339 	if (set & CAPNG_SELECT_CAPS)
340 		memset(&m.data, 0, sizeof(cap_data_t));
341 #ifdef PR_CAPBSET_DROP
342 if (HAVE_PR_CAPBSET_DROP) {
343 	if (set & CAPNG_SELECT_BOUNDS)
344 		memset(m.bounds, 0, sizeof(m.bounds));
345 }
346 #endif
347 #ifdef PR_CAP_AMBIENT
348 if (HAVE_PR_CAP_AMBIENT) {
349 	if (set & CAPNG_SELECT_AMBIENT)
350 		memset(m.ambient, 0, sizeof(m.ambient));
351 }
352 #endif
353 	m.state = CAPNG_INIT;
354 }
355 
capng_fill(capng_select_t set)356 void capng_fill(capng_select_t set)
357 {
358 	if (m.state == CAPNG_NEW)
359 		init();
360 	if (m.state == CAPNG_ERROR)
361 		return;
362 
363 	if (set & CAPNG_SELECT_CAPS) {
364 		if (m.cap_ver == 1) {
365 			m.data.v1.effective = 0x7FFFFFFFU;
366 			m.data.v1.permitted = 0x7FFFFFFFU;
367 			m.data.v1.inheritable = 0;
368 		} else {
369 			m.data.v3[0].effective = 0xFFFFFFFFU;
370 			m.data.v3[0].permitted = 0xFFFFFFFFU;
371 			m.data.v3[0].inheritable = 0;
372 			m.data.v3[1].effective = 0xFFFFFFFFU;
373 			m.data.v3[1].permitted = 0xFFFFFFFFU;
374 			m.data.v3[1].inheritable = 0;
375 		}
376 	}
377 #ifdef PR_CAPBSET_DROP
378 if (HAVE_PR_CAPBSET_DROP) {
379 	if (set & CAPNG_SELECT_BOUNDS) {
380 		unsigned i;
381 		for (i=0; i<sizeof(m.bounds)/sizeof(__u32); i++)
382 			m.bounds[i] = 0xFFFFFFFFU;
383 	}
384 }
385 #endif
386 #ifdef PR_CAP_AMBIENT
387 if (HAVE_PR_CAP_AMBIENT) {
388 	if (set & CAPNG_SELECT_AMBIENT) {
389 		unsigned i;
390 		for (i=0; i<sizeof(m.ambient)/sizeof(__u32); i++)
391 			m.ambient[i] = 0xFFFFFFFFU;
392 	}
393 }
394 #endif
395 	m.state = CAPNG_INIT;
396 }
397 
capng_setpid(int pid)398 void capng_setpid(int pid)
399 {
400 	if (m.state == CAPNG_NEW)
401 		init();
402 	if (m.state == CAPNG_ERROR)
403 		return;
404 
405 	m.hdr.pid = pid;
406 }
407 
capng_get_rootid(void)408 int capng_get_rootid(void)
409 {
410 #ifdef VFS_CAP_REVISION_3
411 	return m.rootid;
412 #else
413 	return CAPNG_UNSET_ROOTID;
414 #endif
415 }
416 
capng_set_rootid(int rootid)417 int capng_set_rootid(int rootid)
418 {
419 #ifdef VFS_CAP_REVISION_3
420 	if (m.state == CAPNG_NEW)
421 		init();
422 	if (m.state == CAPNG_ERROR)
423 		return -1;
424 
425 	if (rootid < 0)
426 		return -1;
427 
428 	m.rootid = rootid;
429 	m.vfs_cap_ver = 3;
430 
431 	return 0;
432 #else
433 	return -1;
434 #endif
435 }
436 
437 #ifdef PR_CAPBSET_DROP
get_bounding_set(void)438 static int get_bounding_set(void)
439 {
440 	char buf[64];
441 	FILE *f;
442 	int rc;
443 
444 	snprintf(buf, sizeof(buf), "/proc/%d/status", m.hdr.pid ? m.hdr.pid :
445 #ifdef HAVE_SYSCALL_H
446 		(int)syscall(__NR_gettid));
447 #else
448 		(int)getpid());
449 #endif
450 	f = fopen(buf, "re");
451 	if (f) {
452 		__fsetlocking(f, FSETLOCKING_BYCALLER);
453 		while (fgets(buf, sizeof(buf), f)) {
454 			if (strncmp(buf, "CapB", 4))
455 				continue;
456 			sscanf(buf, "CapBnd:  %08x%08x",
457 			       &m.bounds[1], &m.bounds[0]);
458 			fclose(f);
459 			return 0;
460 		}
461 		// Didn't find bounding set, fall through and try prctl way
462 		fclose(f);
463 	}
464 	// Might be in a container with no procfs - do it the hard way
465 	memset(m.bounds, 0, sizeof(m.bounds));
466 	unsigned int i = 0;
467 	do {
468 		rc = prctl(PR_CAPBSET_READ, i, 0, 0, 0);
469 		if (rc < 0)
470 			return -1;
471 
472 		// Just add set bits
473 		if (rc)
474 			update_bounding_set(CAPNG_ADD, i%32, i>>5);
475 		i++;
476 	} while (cap_valid(i));
477 
478 	return 0;
479 }
480 #endif
481 
482 #ifdef PR_CAP_AMBIENT
get_ambient_set(void)483 static int get_ambient_set(void)
484 {
485 	char buf[64];
486 	FILE *f;
487 	int rc;
488 
489 	snprintf(buf, sizeof(buf), "/proc/%d/status", m.hdr.pid ? m.hdr.pid :
490 #ifdef HAVE_SYSCALL_H
491 		(int)syscall(__NR_gettid));
492 #else
493 		(int)getpid());
494 #endif
495 	f = fopen(buf, "re");
496 	if (f) {
497 		__fsetlocking(f, FSETLOCKING_BYCALLER);
498 		while (fgets(buf, sizeof(buf), f)) {
499 			if (strncmp(buf, "CapA", 4))
500 				continue;
501 			sscanf(buf, "CapAmb:  %08x%08x",
502 			       &m.ambient[1], &m.ambient[0]);
503 			fclose(f);
504 			return 0;
505 		}
506 		fclose(f);
507 		// Didn't find ambient set, fall through and try prctl way
508 	}
509 	// Might be in a container with no procfs - do it the hard way
510 	memset(m.ambient, 0, sizeof(m.ambient));
511 	unsigned int i = 0;
512 	do {
513 		rc = prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, i, 0, 0);
514 		if (rc < 0)
515 			return -1;
516 
517 		// Just add set bits
518 		if (rc)
519 			update_ambient_set(CAPNG_ADD, i%32, i>>5);
520 		i++;
521 	} while (cap_valid(i));
522 
523 	return 0;
524 }
525 #endif
526 
527 /*
528  * Returns 0 on success and -1 on failure
529  */
capng_get_caps_process(void)530 int capng_get_caps_process(void)
531 {
532 	int rc;
533 
534 	if (m.state == CAPNG_NEW)
535 		init();
536 	if (m.state == CAPNG_ERROR)
537 		return -1;
538 
539 	rc = capget((cap_user_header_t)&m.hdr, (cap_user_data_t)&m.data);
540 	if (rc == 0) {
541 		m.state = CAPNG_INIT;
542 #ifdef PR_CAPBSET_DROP
543 if (HAVE_PR_CAPBSET_DROP) {
544 		rc = get_bounding_set();
545 		if (rc < 0)
546 			m.state = CAPNG_ERROR;
547 }
548 #endif
549 #ifdef PR_CAP_AMBIENT
550 if (HAVE_PR_CAP_AMBIENT) {
551 		rc = get_ambient_set();
552 		if (rc < 0)
553 			m.state = CAPNG_ERROR;
554 }
555 #endif
556 	}
557 
558 	return rc;
559 }
560 
561 #ifdef VFS_CAP_U32
562 #ifdef VFS_CAP_REVISION_3
load_data(const struct vfs_ns_cap_data * filedata,int size)563 static int load_data(const struct vfs_ns_cap_data *filedata, int size)
564 #else
565 static int load_data(const struct vfs_cap_data *filedata, int size)
566 #endif
567 {
568 	unsigned int magic;
569 
570 	if (m.cap_ver == 1)
571 		return -1;	// Should never get here but just in case
572 
573 	magic = FIXUP(filedata->magic_etc);
574 	switch (magic & VFS_CAP_REVISION_MASK)
575 	{
576 		case VFS_CAP_REVISION_1:
577 			m.vfs_cap_ver = 1;
578 			if (size != XATTR_CAPS_SZ_1)
579 				return -1;
580 			break;
581 		case VFS_CAP_REVISION_2:
582 			m.vfs_cap_ver = 2;
583 			if (size != XATTR_CAPS_SZ_2)
584 				return -1;
585 			break;
586 #ifdef VFS_CAP_REVISION_3
587 		case VFS_CAP_REVISION_3:
588 			m.vfs_cap_ver = 3;
589 			if (size != XATTR_CAPS_SZ_3)
590 				return -1;
591 			break;
592 #endif
593 		default:
594 			return -1;
595 	}
596 
597 	// Now stuff the data structures
598 	m.data.v3[0].permitted = FIXUP(filedata->data[0].permitted);
599 	m.data.v3[1].permitted = FIXUP(filedata->data[1].permitted);
600 	m.data.v3[0].inheritable = FIXUP(filedata->data[0].inheritable);
601 	m.data.v3[1].inheritable = FIXUP(filedata->data[1].inheritable);
602 	if (magic & VFS_CAP_FLAGS_EFFECTIVE) {
603 		m.data.v3[0].effective =
604 			m.data.v3[0].permitted | m.data.v3[0].inheritable;
605 		m.data.v3[1].effective =
606 			m.data.v3[1].permitted | m.data.v3[1].inheritable;
607 	} else {
608 		m.data.v3[0].effective = 0;
609 		m.data.v3[1].effective = 0;
610 	}
611 #ifdef VFS_CAP_REVISION_3
612 	if (size == XATTR_CAPS_SZ_3) {
613 	    struct vfs_ns_cap_data *d = (struct vfs_ns_cap_data *)filedata;
614 	    m.rootid = FIXUP(d->rootid);
615 	}
616 #endif
617 	return 0;
618 }
619 #endif
620 
capng_get_caps_fd(int fd)621 int capng_get_caps_fd(int fd)
622 {
623 #ifndef VFS_CAP_U32
624 	return -1;
625 #else
626 	int rc;
627 #ifdef VFS_CAP_REVISION_3
628 	struct vfs_ns_cap_data filedata;
629 #else
630 	struct vfs_cap_data filedata;
631 #endif
632 	if (m.state == CAPNG_NEW)
633 		init();
634 	if (m.state == CAPNG_ERROR)
635 		return -1;
636 
637 	rc = fgetxattr(fd, XATTR_NAME_CAPS, &filedata, sizeof(filedata));
638 	if (rc <= 0)
639 		return -1;
640 
641 	rc = load_data(&filedata, rc);
642 	if (rc == 0)
643 		m.state = CAPNG_INIT;
644 	else
645 		m.state = CAPNG_ERROR; // If load data failed, malformed data
646 
647 	return rc;
648 #endif
649 }
650 
v1_update(capng_act_t action,unsigned int capability,__u32 * data)651 static void v1_update(capng_act_t action, unsigned int capability, __u32 *data)
652 {
653 	if (action == CAPNG_ADD)
654 		*data |= MASK(capability);
655 	else
656 		*data &= ~(MASK(capability));
657 }
658 
update_effective(capng_act_t action,unsigned int capability,unsigned int idx)659 static void update_effective(capng_act_t action, unsigned int capability,
660 	unsigned int idx)
661 {
662 	if (action == CAPNG_ADD)
663 		m.data.v3[idx].effective |= MASK(capability);
664 	else
665 		m.data.v3[idx].effective &= ~(MASK(capability));
666 }
667 
update_permitted(capng_act_t action,unsigned int capability,unsigned int idx)668 static void update_permitted(capng_act_t action, unsigned int capability,
669 	unsigned int idx)
670 {
671 	if (action == CAPNG_ADD)
672 		m.data.v3[idx].permitted |= MASK(capability);
673 	else
674 		m.data.v3[idx].permitted &= ~(MASK(capability));
675 }
676 
update_inheritable(capng_act_t action,unsigned int capability,unsigned int idx)677 static void update_inheritable(capng_act_t action, unsigned int capability,
678 	unsigned int idx)
679 {
680 	if (action == CAPNG_ADD)
681 		m.data.v3[idx].inheritable |= MASK(capability);
682 	else
683 		m.data.v3[idx].inheritable &= ~(MASK(capability));
684 }
685 
update_bounding_set(capng_act_t action,unsigned int capability,unsigned int idx)686 static void update_bounding_set(capng_act_t action, unsigned int capability,
687 	unsigned int idx)
688 {
689 #ifdef PR_CAPBSET_DROP
690 if (HAVE_PR_CAPBSET_DROP) {
691 	if (action == CAPNG_ADD)
692 		m.bounds[idx] |= MASK(capability);
693 	else
694 		m.bounds[idx] &= ~(MASK(capability));
695 }
696 #endif
697 }
698 
update_ambient_set(capng_act_t action,unsigned int capability,unsigned int idx)699 static void update_ambient_set(capng_act_t action, unsigned int capability,
700 	unsigned int idx)
701 {
702 #ifdef PR_CAP_AMBIENT
703 if (HAVE_PR_CAP_AMBIENT) {
704 	if (action == CAPNG_ADD)
705 		m.ambient[idx] |= MASK(capability);
706 	else
707 		m.ambient[idx] &= ~(MASK(capability));
708 }
709 #endif
710 }
711 
capng_update(capng_act_t action,capng_type_t type,unsigned int capability)712 int capng_update(capng_act_t action, capng_type_t type, unsigned int capability)
713 {
714 	// Before updating, we expect that the data is initialized to something
715 	if (m.state < CAPNG_INIT)
716 		return -1;
717 	if (!cap_valid(capability)) {
718 		errno = EINVAL;
719 		return -1;
720 	}
721 
722 	if (m.cap_ver == 1) {
723 		if (CAPNG_EFFECTIVE & type)
724 			v1_update(action, capability, &m.data.v1.effective);
725 		if (CAPNG_PERMITTED & type)
726 			v1_update(action, capability, &m.data.v1.permitted);
727 		if (CAPNG_INHERITABLE & type)
728 			v1_update(action, capability, &m.data.v1.inheritable);
729 	} else {
730 		unsigned int idx;
731 
732 		if (capability > 31) {
733 			idx = capability>>5;
734 			capability %= 32;
735 		} else
736 			idx = 0;
737 
738 		if (CAPNG_EFFECTIVE & type)
739 			update_effective(action, capability, idx);
740 		if (CAPNG_PERMITTED & type)
741 			update_permitted(action, capability, idx);
742 		if (CAPNG_INHERITABLE & type)
743 			update_inheritable(action, capability, idx);
744 		if (CAPNG_BOUNDING_SET & type)
745 			update_bounding_set(action, capability, idx);
746 		if (CAPNG_AMBIENT & type)
747 			update_ambient_set(action, capability, idx);
748 	}
749 
750 	m.state = CAPNG_UPDATED;
751 	return 0;
752 }
753 
capng_updatev(capng_act_t action,capng_type_t type,unsigned int capability,...)754 int capng_updatev(capng_act_t action, capng_type_t type,
755                 unsigned int capability, ...)
756 {
757 	int rc;
758 	unsigned int cap;
759 	va_list ap;
760 
761 	rc = capng_update(action, type, capability);
762 	if (rc)
763 		return rc;
764 	va_start(ap, capability);
765 	cap = va_arg(ap, unsigned int);
766 	while (cap_valid(cap)) {
767 		rc = capng_update(action, type, cap);
768 		if (rc)
769 			break;
770 		cap = va_arg(ap, unsigned int);
771 	}
772 	va_end(ap);
773 
774 	// See if planned exit or invalid
775 	if (cap == (unsigned)-1)
776 		rc = 0;
777 	else {
778 		rc = -1;
779 		errno = EINVAL;
780 	}
781 
782 	return rc;
783 }
784 
capng_apply(capng_select_t set)785 int capng_apply(capng_select_t set)
786 {
787 	int rc = 0;
788 
789 	// Before updating, we expect that the data is initialized to something
790 	if (m.state < CAPNG_INIT)
791 		return -1;
792 
793 	if (set & CAPNG_SELECT_BOUNDS) {
794 #ifdef PR_CAPBSET_DROP
795 if (HAVE_PR_CAPBSET_DROP) {
796 		struct cap_ng state;
797 		memcpy(&state, &m, sizeof(state)); /* save state */
798 		if (capng_get_caps_process())
799 			return -9;
800 		if (capng_have_capability(CAPNG_EFFECTIVE, CAP_SETPCAP)) {
801 			unsigned int i;
802 			memcpy(&m, &state, sizeof(m)); /* restore state */
803 			for (i=0; i <= last_cap; i++) {
804 				if (capng_have_capability(CAPNG_BOUNDING_SET,
805 								 i) == 0) {
806 				    if (prctl(PR_CAPBSET_DROP, i, 0, 0, 0) <0) {
807 					rc = -2;
808 					goto try_caps;
809 				    }
810 				}
811 			}
812 			m.state = CAPNG_APPLIED;
813 			if (get_bounding_set() < 0) {
814 				rc = -3;
815 				goto try_caps;
816 			}
817 		} else {
818 			memcpy(&m, &state, sizeof(m)); /* restore state */
819 			rc = -4;
820 			goto try_caps;
821 		}
822 }
823 #endif
824 	}
825 
826 	// Try caps is here so that if someone had SELECT_BOTH and we blew up
827 	// doing the bounding set, we at least try to set any capabilities
828 	// before returning in case the caller also doesn't bother checking
829 	// the return code.
830 try_caps:
831 	if (set & CAPNG_SELECT_CAPS) {
832 		if (capset((cap_user_header_t)&m.hdr,
833 				(cap_user_data_t)&m.data) == 0)
834 			m.state = CAPNG_APPLIED;
835 		else
836 			rc = -5;
837 	}
838 
839 	// Most programs do not and should not mess with ambient capabilities.
840 	// Instead of returning here if rc is set, we'll let it try to
841 	// do something with ambient capabilities in hopes that it's lowering
842 	// capabilities. Again, this is for people that don't check their
843 	// return codes.
844 	//
845 	// Do ambient last so that inheritable and permitted are set by the
846 	// time we get here.
847 	if (set & CAPNG_SELECT_AMBIENT) {
848 #ifdef PR_CAP_AMBIENT
849 if (HAVE_PR_CAP_AMBIENT) {
850 		if (capng_have_capabilities(CAPNG_SELECT_AMBIENT) ==
851 								CAPNG_NONE) {
852 			if (prctl(PR_CAP_AMBIENT,
853 				   PR_CAP_AMBIENT_CLEAR_ALL, 0, 0, 0) < 0) {
854 				rc = -6;
855 				goto out;
856 			}
857 		} else {
858 			unsigned int i;
859 
860 			// Clear them all
861 			if (prctl(PR_CAP_AMBIENT,
862 				   PR_CAP_AMBIENT_CLEAR_ALL, 0, 0, 0) < 0) {
863 				rc = -7;
864 				goto out;
865 			}
866 			for (i=0; i <= last_cap; i++) {
867 				if (capng_have_capability(CAPNG_AMBIENT, i))
868 					if (prctl(PR_CAP_AMBIENT,
869 					    PR_CAP_AMBIENT_RAISE, i, 0, 0) < 0){
870 						rc = -8;
871 						goto out;
872 					}
873 			}
874 		}
875 		m.state = CAPNG_APPLIED;
876 }
877 #endif
878 	}
879 out:
880 	return rc;
881 }
882 
883 #ifdef VFS_CAP_U32
884 #ifdef VFS_CAP_REVISION_3
save_data(struct vfs_ns_cap_data * filedata,int * size)885 static int save_data(struct vfs_ns_cap_data *filedata, int *size)
886 #else
887 static int save_data(struct vfs_cap_data *filedata, int *size)
888 #endif
889 {
890 	// Now stuff the data structures
891 	if (m.vfs_cap_ver == 1) {
892 		filedata->data[0].permitted = FIXUP(m.data.v1.permitted);
893 		filedata->data[0].inheritable = FIXUP(m.data.v1.inheritable);
894 		filedata->magic_etc = FIXUP(VFS_CAP_REVISION_1);
895 		*size = XATTR_CAPS_SZ_1;
896 	} else if (m.vfs_cap_ver == 2 || m.vfs_cap_ver == 3) {
897 		int eff;
898 
899 		if (m.data.v3[0].effective || m.data.v3[1].effective)
900 			eff = VFS_CAP_FLAGS_EFFECTIVE;
901 		else
902 			eff = 0;
903 		filedata->data[0].permitted = FIXUP(m.data.v3[0].permitted);
904 		filedata->data[0].inheritable = FIXUP(m.data.v3[0].inheritable);
905 		filedata->data[1].permitted = FIXUP(m.data.v3[1].permitted);
906 		filedata->data[1].inheritable = FIXUP(m.data.v3[1].inheritable);
907 		filedata->magic_etc = FIXUP(VFS_CAP_REVISION_2 | eff);
908 		*size = XATTR_CAPS_SZ_2;
909 	}
910 #ifdef VFS_CAP_REVISION_3
911 	if (m.vfs_cap_ver == 3) {
912 		// Kernel doesn't support namespaces with non-0 rootid
913 		if (m.rootid!= 0)
914 			return -1;
915 		filedata->rootid = FIXUP(m.rootid);
916 		*size = XATTR_CAPS_SZ_3;
917 	}
918 #endif
919 
920 	return 0;
921 }
922 #endif
923 
capng_apply_caps_fd(int fd)924 int capng_apply_caps_fd(int fd)
925 {
926 #ifndef VFS_CAP_U32
927 	return -1;
928 #else
929 	int rc, size = 0;
930 #ifdef VFS_CAP_REVISION_3
931 	struct vfs_ns_cap_data filedata;
932 #else
933 	struct vfs_cap_data filedata;
934 #endif
935 	struct stat buf;
936 
937 	// Before updating, we expect that the data is initialized to something
938 	if (m.state < CAPNG_INIT)
939 		return -1;
940 
941 	if (fstat(fd, &buf) != 0)
942 		return -1;
943 	if (S_ISLNK(buf.st_mode) || !S_ISREG(buf.st_mode)) {
944 		errno = EINVAL;
945 		return -1;
946 	}
947 	if (capng_have_capabilities(CAPNG_SELECT_CAPS) == CAPNG_NONE)
948 		rc = fremovexattr(fd, XATTR_NAME_CAPS);
949 	else {
950 		if (save_data(&filedata, &size)) {
951 			m.state = CAPNG_ERROR;
952 			errno = EINVAL;
953 			return -2;
954 		}
955 		rc = fsetxattr(fd, XATTR_NAME_CAPS, &filedata, size, 0);
956 	}
957 
958 	if (rc == 0)
959 		m.state = CAPNG_APPLIED;
960 
961 	return rc;
962 #endif
963 }
964 
965 // Change uids keeping/removing only certain capabilities
966 // flag to drop supp groups
capng_change_id(int uid,int gid,capng_flags_t flag)967 int capng_change_id(int uid, int gid, capng_flags_t flag)
968 {
969 	int rc, ret, need_setgid, need_setuid;
970 
971 	// Before updating, we expect that the data is initialized to something
972 	if (m.state < CAPNG_INIT)
973 		return -1;
974 
975 	// Check the current capabilities
976 #ifdef PR_CAPBSET_DROP
977 if (HAVE_PR_CAPBSET_DROP) {
978 	// If newer kernel, we need setpcap to change the bounding set
979 	if (capng_have_capability(CAPNG_EFFECTIVE, CAP_SETPCAP) == 0 &&
980 					flag & CAPNG_CLEAR_BOUNDING)
981 		capng_update(CAPNG_ADD,
982 				CAPNG_EFFECTIVE|CAPNG_PERMITTED, CAP_SETPCAP);
983 }
984 #endif
985 	if (gid == -1 || capng_have_capability(CAPNG_EFFECTIVE, CAP_SETGID))
986 		need_setgid = 0;
987 	else {
988 		need_setgid = 1;
989 		capng_update(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
990 				CAP_SETGID);
991 	}
992 	if (uid == -1 || capng_have_capability(CAPNG_EFFECTIVE, CAP_SETUID))
993 		need_setuid = 0;
994 	else {
995 		need_setuid = 1;
996 		capng_update(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
997 				CAP_SETUID);
998 	}
999 
1000 	// Tell system we want to keep caps across uid change
1001 	if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0))
1002 		return -2;
1003 
1004 	// Change to the temp capabilities
1005 	rc = capng_apply(CAPNG_SELECT_CAPS);
1006 	if (rc < 0) {
1007 		ret = -3;
1008 		goto err_out;
1009 	}
1010 
1011 	// If we are clearing ambient, only clear since its applied at the end
1012 	if (flag & CAPNG_CLEAR_AMBIENT)
1013 		capng_clear(CAPNG_SELECT_AMBIENT);
1014 
1015 	// Clear bounding set if needed while we have CAP_SETPCAP
1016 	if (flag & CAPNG_CLEAR_BOUNDING) {
1017 		capng_clear(CAPNG_SELECT_BOUNDS);
1018 		rc = capng_apply(CAPNG_SELECT_BOUNDS);
1019 		if (rc) {
1020 			ret = -8;
1021 			goto err_out;
1022 		}
1023 	}
1024 
1025 	// Change gid
1026 	if (gid != -1) {
1027 		rc = setresgid(gid, gid, gid);
1028 		if (rc) {
1029 			ret = -4;
1030 			goto err_out;
1031 		}
1032 	}
1033 
1034 	// See if we need to init supplemental groups
1035 	if ((flag & CAPNG_INIT_SUPP_GRP) && uid != -1) {
1036 		struct passwd *pw = getpwuid(uid);
1037 		if (pw == NULL) {
1038 			ret = -10;
1039 			goto err_out;
1040 		}
1041 		if (gid != -1) {
1042 			if (initgroups(pw->pw_name, gid)) {
1043 				ret = -5;
1044 				goto err_out;
1045 			}
1046 		} else if (initgroups(pw->pw_name, pw->pw_gid)) {
1047 			ret = -5;
1048 			goto err_out;
1049 		}
1050 	}
1051 
1052 	// See if we need to unload supplemental groups
1053 	if ((flag & CAPNG_DROP_SUPP_GRP) && gid != -1) {
1054 		if (setgroups(0, NULL)) {
1055 			ret = -5;
1056 			goto err_out;
1057 		}
1058 	}
1059 
1060 	// Change uid
1061 	if (uid != -1) {
1062 		rc = setresuid(uid, uid, uid);
1063 		if (rc) {
1064 			ret = -6;
1065 			goto err_out;
1066 		}
1067 	}
1068 
1069 	// Tell it we are done keeping capabilities
1070 	rc = prctl(PR_SET_KEEPCAPS, 0, 0, 0, 0);
1071 	if (rc)
1072 		return -7;
1073 
1074 	// Now throw away CAP_SETPCAP so no more changes
1075 	if (need_setgid)
1076 		capng_update(CAPNG_DROP, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
1077 				CAP_SETGID);
1078 	if (need_setuid)
1079 		capng_update(CAPNG_DROP, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
1080 				CAP_SETUID);
1081 
1082 	// Now drop setpcap & apply
1083 	capng_update(CAPNG_DROP, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
1084 				CAP_SETPCAP);
1085 	rc = capng_apply(CAPNG_SELECT_CAPS|CAPNG_SELECT_AMBIENT);
1086 	if (rc < 0)
1087 		return -9;
1088 
1089 	// Done
1090 	m.state = CAPNG_UPDATED;
1091 	return 0;
1092 
1093 err_out:
1094 	prctl(PR_SET_KEEPCAPS, 0, 0, 0, 0);
1095 	return ret;
1096 }
1097 
capng_lock(void)1098 int capng_lock(void)
1099 {
1100 	// If either fail, return -1 since something is not right
1101 #ifdef PR_SET_SECUREBITS
1102 if (HAVE_PR_SET_SECUREBITS) {
1103 	int rc = prctl(PR_SET_SECUREBITS,
1104 			1 << SECURE_NOROOT |
1105 			1 << SECURE_NOROOT_LOCKED |
1106 			1 << SECURE_NO_SETUID_FIXUP |
1107 			1 << SECURE_NO_SETUID_FIXUP_LOCKED, 0, 0, 0);
1108 #ifdef PR_SET_NO_NEW_PRIVS
1109 if (HAVE_PR_SET_NO_NEW_PRIVS) {
1110 	if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0))
1111 		return -1;
1112 }
1113 #endif
1114 	if (rc)
1115 		return -1;
1116 }
1117 #endif
1118 
1119 	return 0;
1120 }
1121 
1122 // -1 - error, 0 - no caps, 1 partial caps, 2 full caps
capng_have_capabilities(capng_select_t set)1123 capng_results_t capng_have_capabilities(capng_select_t set)
1124 {
1125 	int empty = 0, full = 0;
1126 
1127 	// First, try to init with current set
1128 	if (m.state < CAPNG_INIT) {
1129 		if (capng_get_caps_process())
1130 			return CAPNG_FAIL;
1131 	}
1132 
1133 	// If we still don't have anything, error out
1134 	if (m.state < CAPNG_INIT)
1135 		return CAPNG_FAIL;
1136 
1137 	if (set & CAPNG_SELECT_CAPS) {
1138 		if (m.cap_ver == 1) {
1139 			if (m.data.v1.effective == 0)
1140 				empty = 1;
1141 			// after fill, 30 bits starts from upper to lower
1142 			else if (m.data.v1.effective == 0x7FFFFFFFU)
1143 				full = 1;
1144 			// actual capabilities read from system
1145 			else if (m.data.v1.effective == 0xFFFFFEFFU)
1146 				full = 1;
1147 			else
1148 				return CAPNG_PARTIAL;
1149 		} else {
1150 			if (m.data.v3[0].effective == 0)
1151 				empty = 1;
1152 			else if (m.data.v3[0].effective == 0xFFFFFFFFU)
1153 				full = 1;
1154 			else
1155 				return CAPNG_PARTIAL;
1156 			if ((m.data.v3[1].effective & UPPER_MASK) == 0 && !full)
1157 				empty = 1;
1158 			else if ((m.data.v3[1].effective & UPPER_MASK) ==
1159 						UPPER_MASK && !empty)
1160 				full = 1;
1161 			else
1162 				return CAPNG_PARTIAL;
1163 		}
1164 	}
1165 #ifdef PR_CAPBSET_DROP
1166 if (HAVE_PR_CAPBSET_DROP) {
1167 	if (set & CAPNG_SELECT_BOUNDS) {
1168 		if (m.bounds[0] == 0)
1169 			empty = 1;
1170 		else if (m.bounds[0] == 0xFFFFFFFFU)
1171 			full = 1;
1172 		else
1173 			return CAPNG_PARTIAL;
1174 		if ((m.bounds[1] & UPPER_MASK) == 0)
1175 			empty = 1;
1176 		else if ((m.bounds[1] & UPPER_MASK) == UPPER_MASK)
1177 			full = 1;
1178 		else
1179 			return CAPNG_PARTIAL;
1180 	}
1181 } else
1182 	empty = 1;
1183 #endif
1184 #ifdef PR_CAP_AMBIENT
1185 if (HAVE_PR_CAP_AMBIENT) {
1186 	if (set & CAPNG_SELECT_AMBIENT) {
1187 		if (m.ambient[0] == 0)
1188 			empty = 1;
1189 		else if (m.ambient[0] == 0xFFFFFFFFU)
1190 			full = 1;
1191 		else
1192 			return CAPNG_PARTIAL;
1193 		if ((m.ambient[1] & UPPER_MASK) == 0)
1194 			empty = 1;
1195 		else if ((m.ambient[1] & UPPER_MASK) == UPPER_MASK)
1196 			full = 1;
1197 		else
1198 			return CAPNG_PARTIAL;
1199 	}
1200 } else
1201 	empty = 1;
1202 #endif
1203 	if (empty == 1 && full == 0)
1204 		return CAPNG_NONE;
1205 	else if (empty == 0 && full == 1)
1206 		return CAPNG_FULL;
1207 
1208 	return CAPNG_PARTIAL;
1209 }
1210 
1211 // -1 - error, 0 - no caps, 1 partial caps, 2 full caps
capng_have_permitted_capabilities(void)1212 capng_results_t capng_have_permitted_capabilities(void)
1213 {
1214 	int empty = 0, full = 0;
1215 
1216 	// First, try to init with current set
1217 	if (m.state < CAPNG_INIT) {
1218 		if (capng_get_caps_process())
1219 			return CAPNG_FAIL;
1220 	}
1221 
1222 	// If we still don't have anything, error out
1223 	if (m.state < CAPNG_INIT)
1224 		return CAPNG_FAIL;
1225 
1226 	if (m.data.v3[0].permitted == 0)
1227 		empty = 1;
1228 	else if (m.data.v3[0].permitted == 0xFFFFFFFFU)
1229 		full = 1;
1230 	else
1231 		return CAPNG_PARTIAL;
1232 
1233 	if ((m.data.v3[1].permitted & UPPER_MASK) == 0 && !full)
1234 		empty = 1;
1235 	else if ((m.data.v3[1].permitted & UPPER_MASK) == UPPER_MASK && !empty)
1236 		full = 1;
1237 	else
1238 		return CAPNG_PARTIAL;
1239 
1240 	if (empty == 1 && full == 0)
1241 		return CAPNG_NONE;
1242 	else if (empty == 0 && full == 1)
1243 		return CAPNG_FULL;
1244 
1245 	return CAPNG_PARTIAL;
1246 }
1247 
check_effective(unsigned int capability,unsigned int idx)1248 static int check_effective(unsigned int capability, unsigned int idx)
1249 {
1250 	return MASK(capability) & m.data.v3[idx].effective ? 1 : 0;
1251 }
1252 
check_permitted(unsigned int capability,unsigned int idx)1253 static int check_permitted(unsigned int capability, unsigned int idx)
1254 {
1255 	return MASK(capability) & m.data.v3[idx].permitted ? 1 : 0;
1256 }
1257 
check_inheritable(unsigned int capability,unsigned int idx)1258 static int check_inheritable(unsigned int capability, unsigned int idx)
1259 {
1260 	return MASK(capability) & m.data.v3[idx].inheritable ? 1 : 0;
1261 }
1262 
bounds_bit_check(unsigned int capability,unsigned int idx)1263 static int bounds_bit_check(unsigned int capability, unsigned int idx)
1264 {
1265 #ifdef PR_CAPBSET_DROP
1266 if (HAVE_PR_CAPBSET_DROP) {
1267 	return MASK(capability) & m.bounds[idx] ? 1 : 0;
1268 }
1269 #endif
1270 	return 0;
1271 }
1272 
ambient_bit_check(unsigned int capability,unsigned int idx)1273 static int ambient_bit_check(unsigned int capability, unsigned int idx)
1274 {
1275 #ifdef PR_CAP_AMBIENT
1276 if (HAVE_PR_CAP_AMBIENT) {
1277 	return MASK(capability) & m.ambient[idx] ? 1 : 0;
1278 }
1279 #endif
1280 	return 0;
1281 }
1282 
v1_check(unsigned int capability,__u32 data)1283 static int v1_check(unsigned int capability, __u32 data)
1284 {
1285 	return MASK(capability) & data ? 1 : 0;
1286 }
1287 
capng_have_capability(capng_type_t which,unsigned int capability)1288 int capng_have_capability(capng_type_t which, unsigned int capability)
1289 {
1290 	// First, try to init with current set
1291 	if (m.state < CAPNG_INIT) {
1292 		if (capng_get_caps_process())
1293 			return 0;
1294 	}
1295 
1296 	// If we still don't have anything, error out
1297 	if (m.state < CAPNG_INIT)
1298 		return 0;
1299 	if (m.cap_ver == 1 && capability > 31)
1300 		return 0;
1301 	if (!cap_valid(capability))
1302 		return 0;
1303 
1304 	if (m.cap_ver == 1) {
1305 		if (which == CAPNG_EFFECTIVE)
1306 			return v1_check(capability, m.data.v1.effective);
1307 		else if (which == CAPNG_PERMITTED)
1308 			return v1_check(capability, m.data.v1.permitted);
1309 		else if (which == CAPNG_INHERITABLE)
1310 			return v1_check(capability, m.data.v1.inheritable);
1311 	} else {
1312 		unsigned int idx;
1313 
1314 		if (capability > 31) {
1315 			idx = capability>>5;
1316 			capability %= 32;
1317 		} else
1318 			idx = 0;
1319 
1320 		if (which == CAPNG_EFFECTIVE)
1321 			return check_effective(capability, idx);
1322 		else if (which == CAPNG_PERMITTED)
1323 			return check_permitted(capability, idx);
1324 		else if (which == CAPNG_INHERITABLE)
1325 			return check_inheritable(capability, idx);
1326 		else if (which == CAPNG_BOUNDING_SET)
1327 			return bounds_bit_check(capability, idx);
1328 		else if (which == CAPNG_AMBIENT)
1329 			return ambient_bit_check(capability, idx);
1330 	}
1331 	return 0;
1332 }
1333 
capng_print_caps_numeric(capng_print_t where,capng_select_t set)1334 char *capng_print_caps_numeric(capng_print_t where, capng_select_t set)
1335 {
1336 	char *ptr = NULL;
1337 
1338 	if (m.state < CAPNG_INIT)
1339 		return ptr;
1340 
1341 	if (where == CAPNG_PRINT_STDOUT) {
1342 		if (set & CAPNG_SELECT_CAPS) {
1343 			if (m.cap_ver == 1) {
1344 				printf( "Effective:    %08X\n"
1345 					"Permitted:    %08X\n"
1346 					"Inheritable:  %08X\n",
1347 					m.data.v1.effective,
1348 					m.data.v1.permitted,
1349 					m.data.v1.inheritable);
1350 			} else {
1351 				printf( "Effective:    %08X, %08X\n"
1352 					"Permitted:    %08X, %08X\n"
1353 					"Inheritable:  %08X, %08X\n",
1354 					m.data.v3[1].effective & UPPER_MASK,
1355 					m.data.v3[0].effective,
1356 					m.data.v3[1].permitted & UPPER_MASK,
1357 					m.data.v3[0].permitted,
1358 					m.data.v3[1].inheritable & UPPER_MASK,
1359 					m.data.v3[0].inheritable);
1360 			}
1361 		}
1362 #ifdef PR_CAPBSET_DROP
1363 if (HAVE_PR_CAPBSET_DROP) {
1364 		if (set & CAPNG_SELECT_BOUNDS)
1365 			printf("Bounding Set: %08X, %08X\n",
1366 				m.bounds[1] & UPPER_MASK, m.bounds[0]);
1367 }
1368 #endif
1369 #ifdef PR_CAP_AMBIENT
1370 if (HAVE_PR_CAP_AMBIENT) {
1371 		if (set & CAPNG_SELECT_AMBIENT)
1372 			printf("Ambient :     %08X, %08X\n",
1373 				m.ambient[1] & UPPER_MASK, m.ambient[0]);
1374 }
1375 #endif
1376 	} else if (where == CAPNG_PRINT_BUFFER) {
1377 		if (set & CAPNG_SELECT_CAPS) {
1378 			// Make it big enough for bounding & ambient set, too
1379 			ptr = malloc(160);
1380 			if (m.cap_ver == 1) {
1381 				snprintf(ptr, 160,
1382 					"Effective:   %08X\n"
1383 					"Permitted:   %08X\n"
1384 					"Inheritable: %08X\n",
1385 					m.data.v1.effective,
1386 					m.data.v1.permitted,
1387 					m.data.v1.inheritable);
1388 			} else {
1389 				snprintf(ptr, 160,
1390 					"Effective:   %08X, %08X\n"
1391 					"Permitted:   %08X, %08X\n"
1392 					"Inheritable: %08X, %08X\n",
1393 					m.data.v3[1].effective & UPPER_MASK,
1394 					m.data.v3[0].effective,
1395 					m.data.v3[1].permitted & UPPER_MASK,
1396 					m.data.v3[0].permitted,
1397 					m.data.v3[1].inheritable & UPPER_MASK,
1398 					m.data.v3[0].inheritable);
1399 			}
1400 		}
1401 		if (set & CAPNG_SELECT_BOUNDS) {
1402 #ifdef PR_CAPBSET_DROP
1403 if (HAVE_PR_CAPBSET_DROP) {
1404 			char *s;
1405 			// If ptr is NULL, we only room for bounding and ambient
1406 			if (ptr == NULL ) {
1407 				ptr = malloc(80);
1408 				if (ptr == NULL)
1409 					return ptr;
1410 				*ptr = 0;
1411 				s = ptr;
1412 			} else
1413 				s = ptr + strlen(ptr);
1414 			snprintf(s, 40, "Bounding Set: %08X, %08X\n",
1415 					m.bounds[1] & UPPER_MASK, m.bounds[0]);
1416 }
1417 #endif
1418 		}
1419 		if (set & CAPNG_SELECT_AMBIENT) {
1420 #ifdef PR_CAP_AMBIENT
1421 if (HAVE_PR_CAP_AMBIENT) {
1422 			char *s;
1423 			// If ptr is NULL, we only room for ambient
1424 			if (ptr == NULL ) {
1425 				ptr = malloc(40);
1426 				if (ptr == NULL)
1427 					return ptr;
1428 				*ptr = 0;
1429 				s = ptr;
1430 			} else
1431 				s = ptr + strlen(ptr);
1432 			snprintf(s, 40, "Ambient Set: %08X, %08X\n",
1433 					m.ambient[1] & UPPER_MASK,
1434 					m.ambient[0]);
1435 }
1436 #endif
1437 		}
1438 	}
1439 
1440 	return ptr;
1441 }
1442 
capng_print_caps_text(capng_print_t where,capng_type_t which)1443 char *capng_print_caps_text(capng_print_t where, capng_type_t which)
1444 {
1445 	unsigned int i, once = 0, cnt = 0;
1446 	char *ptr = NULL;
1447 
1448 	if (m.state < CAPNG_INIT)
1449 		return ptr;
1450 
1451 	for (i=0; i<=last_cap; i++) {
1452 		if (capng_have_capability(which, i)) {
1453 			const char *n = capng_capability_to_name(i);
1454 			if (n == NULL)
1455 				n = "unknown";
1456 			if (where == CAPNG_PRINT_STDOUT) {
1457 				if (once == 0) {
1458 					printf("%s", n);
1459 					once++;
1460 				} else
1461 					printf(", %s", n);
1462 			} else if (where == CAPNG_PRINT_BUFFER) {
1463 				int len;
1464 				if (once == 0) {
1465 					ptr = malloc(last_cap*20);
1466 					if (ptr == NULL)
1467 						return ptr;
1468 					len = sprintf(ptr+cnt, "%s", n);
1469 					once++;
1470 				} else
1471 					len = sprintf(ptr+cnt, ", %s", n);
1472 				if (len > 0)
1473 					cnt+=len;
1474 			}
1475 		}
1476 	}
1477 	if (once == 0) {
1478 		if (where == CAPNG_PRINT_STDOUT)
1479 			printf("none");
1480 		else
1481 			ptr = strdup("none");
1482 	}
1483 	return ptr;
1484 }
1485 
capng_save_state(void)1486 void *capng_save_state(void)
1487 {
1488 	void *ptr = malloc(sizeof(m));
1489 	if (ptr)
1490 		memcpy(ptr, &m, sizeof(m));
1491 	return ptr;
1492 }
1493 
capng_restore_state(void ** state)1494 void capng_restore_state(void **state)
1495 {
1496 	if (state) {
1497 		void *ptr = *state;
1498 		if (ptr)
1499 			memcpy(&m, ptr, sizeof(m));
1500 		free(ptr);
1501 		*state = NULL;
1502 	}
1503 }
1504 
1505