Home | History | Annotate | Download | only in src
      1 /* libcap-ng.c --
      2  * Copyright 2009-10 Red Hat Inc., Durham, North Carolina.
      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
     16  * License along with this library; if not, write to the Free Software
     17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     18  *
     19  * Authors:
     20  *      Steve Grubb <sgrubb (at) redhat.com>
     21  */
     22 
     23 #include "config.h"
     24 #include "cap-ng.h"
     25 #include <string.h>
     26 #include <stdarg.h>
     27 #include <stdio.h>
     28 #if !defined(ANDROID)
     29 #include <stdio_ext.h>
     30 #endif
     31 #include <stdlib.h>
     32 #include <sys/prctl.h>
     33 #include <grp.h>
     34 #include <sys/stat.h>
     35 #include <stdarg.h>
     36 #include <errno.h>
     37 #include <byteswap.h>
     38 #ifdef HAVE_SYSCALL_H
     39 #include <sys/syscall.h>
     40 #endif
     41 #ifdef HAVE_LINUX_SECUREBITS_H
     42 #include <linux/securebits.h>
     43 #endif
     44 
     45 /*
     46  * Some milestones of when things became available:
     47  * 2.6.24 kernel	XATTR_NAME_CAPS
     48  * 2.6.25 kernel	PR_CAPBSET_DROP, CAPABILITY_VERSION_2
     49  * 2.6.26 kernel	PR_SET_SECUREBITS, SECURE_*_LOCKED, VERSION_3
     50  */
     51 
     52 /* External syscall prototypes */
     53 extern int capset(cap_user_header_t header, cap_user_data_t data);
     54 extern int capget(cap_user_header_t header, const cap_user_data_t data);
     55 
     56 // Local defines
     57 #define MASK(x) (1U << (x))
     58 #ifdef PR_CAPBSET_DROP
     59 #define UPPER_MASK ~(unsigned)((~0U)<<(CAP_LAST_CAP-31))
     60 #else
     61 // For v1 systems UPPER_MASK will never be used
     62 #define UPPER_MASK (unsigned)(~0U)
     63 #endif
     64 
     65 // Re-define cap_valid so its uniform between V1 and V3
     66 #undef cap_valid
     67 #define cap_valid(x) ((x) <= CAP_LAST_CAP)
     68 
     69 // If we don't have the xattr library, then we can't
     70 // compile-in file system capabilities
     71 #ifndef HAVE_ATTR_XATTR_H
     72 #undef VFS_CAP_U32
     73 #endif
     74 
     75 #ifdef VFS_CAP_U32
     76  #include <attr/xattr.h>
     77  #if __BYTE_ORDER == __BIG_ENDIAN
     78   #define FIXUP(x) bswap_32(x)
     79  #else
     80   #define FIXUP(x) (x)
     81  #endif
     82 #endif
     83 
     84 #ifndef _LINUX_CAPABILITY_VERSION_1
     85 #define _LINUX_CAPABILITY_VERSION_1 0x19980330
     86 #endif
     87 #ifndef _LINUX_CAPABILITY_VERSION_2
     88 #define _LINUX_CAPABILITY_VERSION_2 0x20071026
     89 #endif
     90 #ifndef _LINUX_CAPABILITY_VERSION_3
     91 #define _LINUX_CAPABILITY_VERSION_3 0x20080522
     92 #endif
     93 
     94 // This public API went private in the 2.6.36 kernel - hope it never changes
     95 #ifndef XATTR_CAPS_SUFFIX
     96 #define XATTR_CAPS_SUFFIX "capability"
     97 #endif
     98 #ifndef XATTR_SECURITY_PREFIX
     99 #define XATTR_SECURITY_PREFIX "security."
    100 #endif
    101 #ifndef XATTR_NAME_CAPS
    102 #define XATTR_NAME_CAPS XATTR_SECURITY_PREFIX XATTR_CAPS_SUFFIX
    103 #endif
    104 
    105 
    106 /* Child processes can't get caps back */
    107 #ifndef SECURE_NOROOT
    108 #define SECURE_NOROOT                   0
    109 #endif
    110 #ifndef SECURE_NOROOT_LOCKED
    111 #define SECURE_NOROOT_LOCKED            1  /* make bit-0 immutable */
    112 #endif
    113 /* Setuid apps run by uid 0 don't get caps back */
    114 #ifndef SECURE_NO_SETUID_FIXUP
    115 #define SECURE_NO_SETUID_FIXUP          2
    116 #endif
    117 #ifndef SECURE_NO_SETUID_FIXUP_LOCKED
    118 #define SECURE_NO_SETUID_FIXUP_LOCKED   3  /* make bit-2 immutable */
    119 #endif
    120 
    121 // States: new, allocated, initted, updated, applied
    122 typedef enum { CAPNG_NEW, CAPNG_ERROR, CAPNG_ALLOCATED, CAPNG_INIT,
    123 	CAPNG_UPDATED, CAPNG_APPLIED } capng_states_t;
    124 
    125 // Create an easy data struct out of the kernel definitions
    126 typedef union {
    127 	struct __user_cap_data_struct v1;
    128 	struct __user_cap_data_struct v3[2];
    129 } cap_data_t;
    130 
    131 // This struct keeps all state info
    132 struct cap_ng
    133 {
    134 	int cap_ver;
    135 	struct __user_cap_header_struct hdr;
    136 	cap_data_t data;
    137 	capng_states_t state;
    138 	__u32 bounds[2];
    139 };
    140 
    141 // Global variables with per thread uniqueness
    142 static __thread struct cap_ng m =	{ 1,
    143 					{0, 0},
    144 					{ {0, 0, 0} },
    145 					CAPNG_NEW,
    146 					{0, 0} };
    147 
    148 
    149 static void init(void)
    150 {
    151 	if (m.state != CAPNG_NEW)
    152 		return;
    153 
    154 	memset(&m.hdr, 0, sizeof(m.hdr));
    155 	(void)capget(&m.hdr, NULL); // Returns -EINVAL
    156 	if (m.hdr.version == _LINUX_CAPABILITY_VERSION_3 ||
    157 		m.hdr.version == _LINUX_CAPABILITY_VERSION_2) {
    158 		m.cap_ver = 3;
    159 	} else if (m.hdr.version == _LINUX_CAPABILITY_VERSION_1) {
    160 		m.cap_ver = 1;
    161 	} else {
    162 		m.state = CAPNG_ERROR;
    163 		return;
    164 	}
    165 
    166 	memset(&m.data, 0, sizeof(cap_data_t));
    167 #ifdef HAVE_SYSCALL_H
    168 	m.hdr.pid = (unsigned)syscall(__NR_gettid);
    169 #else
    170 	m.hdr.pid = (unsigned)getpid();
    171 #endif
    172 	m.state = CAPNG_ALLOCATED;
    173 }
    174 
    175 void capng_clear(capng_select_t set)
    176 {
    177 	if (m.state == CAPNG_NEW)
    178 		init();
    179 	if (m.state == CAPNG_ERROR)
    180 		return;
    181 
    182 	if (set & CAPNG_SELECT_CAPS)
    183 		memset(&m.data, 0, sizeof(cap_data_t));
    184 #ifdef PR_CAPBSET_DROP
    185 	if (set & CAPNG_SELECT_BOUNDS)
    186 		memset(m.bounds, 0, sizeof(m.bounds));
    187 #endif
    188 	m.state = CAPNG_INIT;
    189 }
    190 
    191 void capng_fill(capng_select_t set)
    192 {
    193 	if (m.state == CAPNG_NEW)
    194 		init();
    195 	if (m.state == CAPNG_ERROR)
    196 		return;
    197 
    198 	if (set & CAPNG_SELECT_CAPS) {
    199 		if (m.cap_ver == 1) {
    200 			m.data.v1.effective = 0x7FFFFFFFU;
    201 			m.data.v1.permitted = 0x7FFFFFFFU;
    202 			m.data.v1.inheritable = 0;
    203 		} else {
    204 			m.data.v3[0].effective = 0xFFFFFFFFU;
    205 			m.data.v3[0].permitted = 0xFFFFFFFFU;
    206 			m.data.v3[0].inheritable = 0;
    207 			m.data.v3[1].effective = 0xFFFFFFFFU;
    208 			m.data.v3[1].permitted = 0xFFFFFFFFU;
    209 			m.data.v3[1].inheritable = 0;
    210 		}
    211 	}
    212 #ifdef PR_CAPBSET_DROP
    213 	if (set & CAPNG_SELECT_BOUNDS) {
    214 		unsigned i;
    215 		for (i=0; i<sizeof(m.bounds)/sizeof(__u32); i++)
    216 			m.bounds[i] = 0xFFFFFFFFU;
    217 	}
    218 #endif
    219 	m.state = CAPNG_INIT;
    220 }
    221 
    222 void capng_setpid(int pid)
    223 {
    224 	if (m.state == CAPNG_NEW)
    225 		init();
    226 	if (m.state == CAPNG_ERROR)
    227 		return;
    228 
    229 	m.hdr.pid = pid;
    230 }
    231 
    232 #ifdef PR_CAPBSET_DROP
    233 static int get_bounding_set(void)
    234 {
    235 	char buf[64];
    236 	FILE *f;
    237 
    238 	snprintf(buf, sizeof(buf), "/proc/%u/status", m.hdr.pid ? m.hdr.pid :
    239 #ifdef HAVE_SYSCALL_H
    240 		(unsigned)syscall(__NR_gettid));
    241 #else
    242 		(unsigned)getpid();
    243 #endif
    244 	f = fopen(buf, "re");
    245 	if (f == NULL)
    246 		return -1;
    247 #if !defined(ANDROID)
    248 	__fsetlocking(f, FSETLOCKING_BYCALLER);
    249 #endif
    250 	while (fgets(buf, sizeof(buf), f)) {
    251 		if (strncmp(buf, "CapB", 4))
    252 			continue;
    253 		sscanf(buf, "CapBnd:  %08x%08x", &m.bounds[1], &m.bounds[0]);
    254 		fclose(f);
    255 		return 0;
    256 	}
    257 	fclose(f);
    258 	return -1;
    259 }
    260 #endif
    261 
    262 int capng_get_caps_process(void)
    263 {
    264 	int rc;
    265 
    266 	if (m.state == CAPNG_NEW)
    267 		init();
    268 	if (m.state == CAPNG_ERROR)
    269 		return -1;
    270 
    271 	rc = capget((cap_user_header_t)&m.hdr, (cap_user_data_t)&m.data);
    272 	if (rc == 0) {
    273 		m.state = CAPNG_INIT;
    274 #ifdef PR_CAPBSET_DROP
    275 		rc = get_bounding_set();
    276 		if (rc < 0)
    277 			m.state = CAPNG_ERROR;
    278 #endif
    279 	}
    280 
    281 	return rc;
    282 }
    283 
    284 #ifdef VFS_CAP_U32
    285 static int load_data(const struct vfs_cap_data *filedata, int size)
    286 {
    287 	unsigned int magic;
    288 
    289 	if (m.cap_ver == 1)
    290 		return -1;	// Should never get here but just in case
    291 
    292 	magic = FIXUP(filedata->magic_etc);
    293 	switch (magic & VFS_CAP_REVISION_MASK)
    294 	{
    295 		case VFS_CAP_REVISION_1:
    296 			m.cap_ver = 1;
    297 			if (size != XATTR_CAPS_SZ_1)
    298 				return -1;
    299 			break;
    300 		case VFS_CAP_REVISION_2:
    301 			m.cap_ver = 2;
    302 			if (size != XATTR_CAPS_SZ_2)
    303 				return -1;
    304 			break;
    305 		default:
    306 			return -1;
    307 	}
    308 
    309 	// Now stuff the data structures
    310 	m.data.v3[0].permitted = FIXUP(filedata->data[0].permitted);
    311 	m.data.v3[1].permitted = FIXUP(filedata->data[1].permitted);
    312 	m.data.v3[0].inheritable = FIXUP(filedata->data[0].inheritable);
    313 	m.data.v3[1].inheritable = FIXUP(filedata->data[1].inheritable);
    314 	if (magic & VFS_CAP_FLAGS_EFFECTIVE) {
    315 		m.data.v3[0].effective =
    316 			m.data.v3[0].permitted | m.data.v3[0].inheritable;
    317 		m.data.v3[1].effective =
    318 			m.data.v3[1].permitted | m.data.v3[1].inheritable;
    319 	} else {
    320 		m.data.v3[0].effective = 0;
    321 		m.data.v3[1].effective = 0;
    322 	}
    323 	return 0;
    324 }
    325 #endif
    326 
    327 int capng_get_caps_fd(int fd)
    328 {
    329 #ifndef VFS_CAP_U32
    330 	return -1;
    331 #else
    332 	int rc;
    333 	struct vfs_cap_data filedata;
    334 
    335 	if (m.state == CAPNG_NEW)
    336 		init();
    337 	if (m.state == CAPNG_ERROR)
    338 		return -1;
    339 
    340 	rc = fgetxattr(fd, XATTR_NAME_CAPS, &filedata, sizeof(filedata));
    341 	if (rc <= 0)
    342 		return -1;
    343 
    344 	rc = load_data(&filedata, rc);
    345 	if (rc == 0)
    346 		m.state = CAPNG_INIT;
    347 
    348 	return rc;
    349 #endif
    350 }
    351 
    352 static void v1_update(capng_act_t action, unsigned int capability, __u32 *data)
    353 {
    354 	if (action == CAPNG_ADD)
    355 		*data |= MASK(capability);
    356 	else
    357 		*data &= ~(MASK(capability));
    358 }
    359 
    360 static void update_effective(capng_act_t action, unsigned int capability,
    361 	unsigned int idx)
    362 {
    363 	if (action == CAPNG_ADD)
    364 		m.data.v3[idx].effective |= MASK(capability);
    365 	else
    366 		m.data.v3[idx].effective &= ~(MASK(capability));
    367 }
    368 
    369 static void update_permitted(capng_act_t action, unsigned int capability,
    370 	unsigned int idx)
    371 {
    372 	if (action == CAPNG_ADD)
    373 		m.data.v3[idx].permitted |= MASK(capability);
    374 	else
    375 		m.data.v3[idx].permitted &= ~(MASK(capability));
    376 }
    377 
    378 static void update_inheritable(capng_act_t action, unsigned int capability,
    379 	unsigned int idx)
    380 {
    381 	if (action == CAPNG_ADD)
    382 		m.data.v3[idx].inheritable |= MASK(capability);
    383 	else
    384 		m.data.v3[idx].inheritable &= ~(MASK(capability));
    385 }
    386 
    387 static void update_bounding_set(capng_act_t action, unsigned int capability,
    388 	unsigned int idx)
    389 {
    390 #ifdef PR_CAPBSET_DROP
    391 	if (action == CAPNG_ADD)
    392 		m.bounds[idx] |= MASK(capability);
    393 	else
    394 		m.bounds[idx] &= ~(MASK(capability));
    395 #endif
    396 }
    397 
    398 int capng_update(capng_act_t action, capng_type_t type, unsigned int capability)
    399 {
    400 	// Before updating, we expect that the data is initialized to something
    401 	if (m.state < CAPNG_INIT)
    402 		return -1;
    403 	if (!cap_valid(capability)) {
    404 		errno = EINVAL;
    405 		return -1;
    406 	}
    407 
    408 	if (m.cap_ver == 1) {
    409 		if (CAPNG_EFFECTIVE & type)
    410 			v1_update(action, capability, &m.data.v1.effective);
    411 		if (CAPNG_PERMITTED & type)
    412 			v1_update(action, capability, &m.data.v1.permitted);
    413 		if (CAPNG_INHERITABLE & type)
    414 			v1_update(action, capability, &m.data.v1.inheritable);
    415 	} else {
    416 		int idx;
    417 
    418 		if (capability > 31) {
    419 			idx = capability>>5;
    420 			capability %= 32;
    421 		} else
    422 			idx = 0;
    423 
    424 		if (CAPNG_EFFECTIVE & type)
    425 			update_effective(action, capability, idx);
    426 		if (CAPNG_PERMITTED & type)
    427 			update_permitted(action, capability, idx);
    428 		if (CAPNG_INHERITABLE & type)
    429 			update_inheritable(action, capability, idx);
    430 		if (CAPNG_BOUNDING_SET & type)
    431 			update_bounding_set(action, capability, idx);
    432 	}
    433 
    434 	m.state = CAPNG_UPDATED;
    435 	return 0;
    436 }
    437 
    438 int capng_updatev(capng_act_t action, capng_type_t type,
    439                 unsigned int capability, ...)
    440 {
    441 	int rc;
    442 	unsigned int cap;
    443 	va_list ap;
    444 
    445 	rc = capng_update(action, type, capability);
    446 	if (rc)
    447 		return rc;
    448 	va_start(ap, capability);
    449 	cap = va_arg(ap, unsigned int);
    450 	while (cap_valid(cap)) {
    451 		rc = capng_update(action, type, cap);
    452 		if (rc)
    453 			break;
    454 		cap = va_arg(ap, unsigned int);
    455 	}
    456 	va_end(ap);
    457 
    458 	// See if planned exit or invalid
    459 	if (cap == (unsigned)-1)
    460 		rc = 0;
    461 	else {
    462 		rc = -1;
    463 		errno = EINVAL;
    464 	}
    465 
    466 	return rc;
    467 }
    468 
    469 int capng_apply(capng_select_t set)
    470 {
    471 	int rc = -1;
    472 
    473 	// Before updating, we expect that the data is initialized to something
    474 	if (m.state < CAPNG_INIT)
    475 		return -1;
    476 
    477 	if (set & CAPNG_SELECT_BOUNDS) {
    478 #ifdef PR_CAPBSET_DROP
    479 		void *s = capng_save_state();
    480 		capng_get_caps_process();
    481 		if (capng_have_capability(CAPNG_EFFECTIVE, CAP_SETPCAP)) {
    482 			int i;
    483 			capng_restore_state(&s);
    484 			rc = 0;
    485 			for (i=0; i <= CAP_LAST_CAP && rc == 0; i++)
    486 				if (capng_have_capability(CAPNG_BOUNDING_SET,
    487 								 i) == 0)
    488 					rc = prctl(PR_CAPBSET_DROP, i, 0, 0, 0);
    489 			if (rc == 0)
    490 				m.state = CAPNG_APPLIED;
    491 		} else
    492 			capng_restore_state(&s);
    493 #else
    494 		rc = 0;
    495 #endif
    496 	}
    497 	if (set & CAPNG_SELECT_CAPS) {
    498 		rc = capset((cap_user_header_t)&m.hdr,
    499 				(cap_user_data_t)&m.data);
    500 		if (rc == 0)
    501 			m.state = CAPNG_APPLIED;
    502 	}
    503 	return rc;
    504 }
    505 
    506 #ifdef VFS_CAP_U32
    507 static int save_data(struct vfs_cap_data *filedata, int *size)
    508 {
    509 	// Now stuff the data structures
    510 	if (m.cap_ver == 1) {
    511 		filedata->data[0].permitted = FIXUP(m.data.v1.permitted);
    512 		filedata->data[0].inheritable = FIXUP(m.data.v1.inheritable);
    513 		filedata->magic_etc = FIXUP(VFS_CAP_REVISION_1);
    514 		*size = XATTR_CAPS_SZ_1;
    515 	} else {
    516 		int eff;
    517 
    518 		if (m.data.v3[0].effective || m.data.v3[1].effective)
    519 			eff = VFS_CAP_FLAGS_EFFECTIVE;
    520 		else
    521 			eff = 0;
    522 		filedata->data[0].permitted = FIXUP(m.data.v3[0].permitted);
    523 		filedata->data[0].inheritable = FIXUP(m.data.v3[0].inheritable);
    524 		filedata->data[1].permitted = FIXUP(m.data.v3[1].permitted);
    525 		filedata->data[1].inheritable = FIXUP(m.data.v3[1].inheritable);
    526 		filedata->magic_etc = FIXUP(VFS_CAP_REVISION_2 | eff);
    527 		*size = XATTR_CAPS_SZ_2;
    528 	}
    529 
    530 	return 0;
    531 }
    532 #endif
    533 
    534 int capng_apply_caps_fd(int fd)
    535 {
    536 #ifndef VFS_CAP_U32
    537 	return -1;
    538 #else
    539 	int rc, size;
    540 	struct vfs_cap_data filedata;
    541 	struct stat buf;
    542 
    543 	// Before updating, we expect that the data is initialized to something
    544 	if (m.state < CAPNG_INIT)
    545 		return -1;
    546 
    547 	if (fstat(fd, &buf) != 0)
    548 		return -1;
    549 	if (S_ISLNK(buf.st_mode) || !S_ISREG(buf.st_mode)) {
    550 		errno = EINVAL;
    551 		return -1;
    552 	}
    553 	if (capng_have_capabilities(CAPNG_SELECT_CAPS) == CAPNG_NONE)
    554 		rc = fremovexattr(fd, XATTR_NAME_CAPS);
    555 	else {
    556 		save_data(&filedata, &size);
    557 		rc = fsetxattr(fd, XATTR_NAME_CAPS, &filedata, size, 0);
    558 	}
    559 
    560 	if (rc == 0)
    561 		m.state = CAPNG_APPLIED;
    562 
    563 	return rc;
    564 #endif
    565 }
    566 
    567 // Change uids keeping/removing only certain capabilities
    568 // flag to drop supp groups
    569 int capng_change_id(int uid, int gid, capng_flags_t flag)
    570 {
    571 	int rc, need_setgid, need_setuid;
    572 
    573 	// Before updating, we expect that the data is initialized to something
    574 	if (m.state < CAPNG_INIT)
    575 		return -1;
    576 
    577 	// Check the current capabilities
    578 #ifdef PR_CAPBSET_DROP
    579 	// If newer kernel, we need setpcap to change the bounding set
    580 	if (capng_have_capability(CAPNG_EFFECTIVE, CAP_SETPCAP) == 0 &&
    581 					flag & CAPNG_CLEAR_BOUNDING)
    582 		capng_update(CAPNG_ADD,
    583 				CAPNG_EFFECTIVE|CAPNG_PERMITTED, CAP_SETPCAP);
    584 #endif
    585 	if (gid == -1 || capng_have_capability(CAPNG_EFFECTIVE, CAP_SETGID))
    586 		need_setgid = 0;
    587 	else {
    588 		need_setgid = 1;
    589 		capng_update(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
    590 				CAP_SETGID);
    591 	}
    592 	if (uid == -1 || capng_have_capability(CAPNG_EFFECTIVE, CAP_SETUID))
    593 		need_setuid = 0;
    594 	else {
    595 		need_setuid = 1;
    596 		capng_update(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
    597 				CAP_SETUID);
    598 	}
    599 
    600 	// Tell system we want to keep caps across uid change
    601 	if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0))
    602 		return -2;
    603 
    604 	// Change to the temp capabilities
    605 	rc = capng_apply(CAPNG_SELECT_CAPS);
    606 	if (rc < 0)
    607 		return -3;
    608 
    609 	// Clear bounding set if needed while we have CAP_SETPCAP
    610 	if (flag & CAPNG_CLEAR_BOUNDING) {
    611 		capng_clear(CAPNG_BOUNDING_SET);
    612 		rc = capng_apply(CAPNG_SELECT_BOUNDS);
    613 		if (rc)
    614 			return -8;
    615 	}
    616 
    617 	// Change gid
    618 	if (gid != -1) {
    619 		rc = setresgid(gid, gid, gid);
    620 		if (rc)
    621 			return -4;
    622 	}
    623 
    624 	// See if we need to unload supplemental groups
    625 	if ((flag & CAPNG_DROP_SUPP_GRP) && gid != -1) {
    626 		if (setgroups(0, NULL))
    627 			return -5;
    628 	}
    629 
    630 	// Change uid
    631 	if (uid != -1) {
    632 		rc = setresuid(uid, uid, uid);
    633 		if (rc)
    634 			return -6;
    635 	}
    636 
    637 	// Tell it we are done keeping capabilities
    638 	rc = prctl(PR_SET_KEEPCAPS, 0, 0, 0, 0);
    639 	if (rc)
    640 		return -7;
    641 
    642 	// Now throw away CAP_SETPCAP so no more changes
    643 	if (need_setgid)
    644 		capng_update(CAPNG_DROP, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
    645 				CAP_SETGID);
    646 	if (need_setuid)
    647 		capng_update(CAPNG_DROP, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
    648 				CAP_SETUID);
    649 
    650 	// Now drop setpcap & apply
    651 	capng_update(CAPNG_DROP, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
    652 				CAP_SETPCAP);
    653 	rc = capng_apply(CAPNG_SELECT_CAPS);
    654 	if (rc < 0)
    655 		return -9;
    656 
    657 	// Done
    658 	m.state = CAPNG_UPDATED;
    659 	return 0;
    660 }
    661 
    662 int capng_lock(void)
    663 {
    664 #ifdef PR_SET_SECUREBITS
    665 	int rc = prctl(PR_SET_SECUREBITS,
    666 			1 << SECURE_NOROOT |
    667 			1 << SECURE_NOROOT_LOCKED |
    668 			1 << SECURE_NO_SETUID_FIXUP |
    669 			1 << SECURE_NO_SETUID_FIXUP_LOCKED, 0, 0, 0);
    670 	if (rc)
    671 		return -1;
    672 #endif
    673 
    674 	return 0;
    675 }
    676 
    677 // -1 - error, 0 - no caps, 1 partial caps, 2 full caps
    678 capng_results_t capng_have_capabilities(capng_select_t set)
    679 {
    680 	int empty = 0, full = 0;
    681 
    682 	// First, try to init with current set
    683 	if (m.state < CAPNG_INIT)
    684 		capng_get_caps_process();
    685 
    686 	// If we still don't have anything, error out
    687 	if (m.state < CAPNG_INIT)
    688 		return CAPNG_FAIL;
    689 
    690 	if (set & CAPNG_SELECT_CAPS) {
    691 		if (m.cap_ver == 1) {
    692 			if (m.data.v1.effective == 0)
    693 				empty = 1;
    694 			// after fill, 30 bits starts from upper to lower
    695 			else if (m.data.v1.effective == 0x7FFFFFFFU)
    696 				full = 1;
    697 			// actual capabilities read from system
    698 			else if (m.data.v1.effective == 0xFFFFFEFFU)
    699 				full = 1;
    700 			else
    701 				return CAPNG_PARTIAL;
    702 		} else {
    703 			if (m.data.v3[0].effective == 0)
    704 				empty = 1;
    705 			else if (m.data.v3[0].effective == 0xFFFFFFFFU)
    706 				full = 1;
    707 			else
    708 				return CAPNG_PARTIAL;
    709 			if ((m.data.v3[1].effective & UPPER_MASK) == 0)
    710 				empty = 1;
    711 			else if ((m.data.v3[1].effective & UPPER_MASK) ==
    712 							UPPER_MASK)
    713 				full = 1;
    714 			else
    715 				return CAPNG_PARTIAL;
    716 		}
    717 	}
    718 #ifdef PR_CAPBSET_DROP
    719 	if (set & CAPNG_SELECT_BOUNDS) {
    720 		if (m.bounds[0] == 0)
    721 			empty = 1;
    722 		else if (m.bounds[0] == 0xFFFFFFFFU)
    723 			full = 1;
    724 		else
    725 			return CAPNG_PARTIAL;
    726 		if ((m.bounds[1] & UPPER_MASK) == 0)
    727 			empty = 1;
    728 		else if ((m.bounds[1] & UPPER_MASK) == UPPER_MASK)
    729 			full = 1;
    730 		else
    731 			return CAPNG_PARTIAL;
    732 	}
    733 #endif
    734 
    735 	if (empty == 1 && full == 0)
    736 		return CAPNG_NONE;
    737 	else if (empty == 0 && full == 1)
    738 		return CAPNG_FULL;
    739 
    740 	return CAPNG_PARTIAL;
    741 }
    742 
    743 static int check_effective(unsigned int capability, unsigned int idx)
    744 {
    745 	return MASK(capability) & m.data.v3[idx].effective ? 1 : 0;
    746 }
    747 
    748 static int check_permitted(unsigned int capability, unsigned int idx)
    749 {
    750 	return MASK(capability) & m.data.v3[idx].permitted ? 1 : 0;
    751 }
    752 
    753 static int check_inheritable(unsigned int capability, unsigned int idx)
    754 {
    755 	return MASK(capability) & m.data.v3[idx].inheritable ? 1 : 0;
    756 }
    757 
    758 static int bounds_bit_check(unsigned int capability, unsigned int idx)
    759 {
    760 #ifdef PR_CAPBSET_DROP
    761 	return MASK(capability) & m.bounds[idx] ? 1 : 0;
    762 #else
    763 	return 0;
    764 #endif
    765 }
    766 
    767 static int v1_check(unsigned int capability, __u32 data)
    768 {
    769 	return MASK(capability) & data ? 1 : 0;
    770 }
    771 
    772 int capng_have_capability(capng_type_t which, unsigned int capability)
    773 {
    774 	// First, try to init with current set
    775 	if (m.state < CAPNG_INIT)
    776 		capng_get_caps_process();
    777 
    778 	// If we still don't have anything, error out
    779 	if (m.state < CAPNG_INIT)
    780 		return CAPNG_FAIL;
    781 	if (m.cap_ver == 1 && capability > 31)
    782 		return 0;
    783 	if (!cap_valid(capability))
    784 		return 0;
    785 
    786 	if (m.cap_ver == 1) {
    787 		if (which == CAPNG_EFFECTIVE)
    788 			return v1_check(capability, m.data.v1.effective);
    789 		else if (which == CAPNG_PERMITTED)
    790 			return v1_check(capability, m.data.v1.permitted);
    791 		else if (which == CAPNG_INHERITABLE)
    792 			return v1_check(capability, m.data.v1.inheritable);
    793 	} else {
    794 		unsigned int idx;
    795 
    796 		if (capability > 31) {
    797 			idx = capability>>5;
    798 			capability %= 32;
    799 		} else
    800 			idx = 0;
    801 
    802 		if (which == CAPNG_EFFECTIVE)
    803 			return check_effective(capability, idx);
    804 		else if (which == CAPNG_PERMITTED)
    805 			return check_permitted(capability, idx);
    806 		else if (which == CAPNG_INHERITABLE)
    807 			return check_inheritable(capability, idx);
    808 		else if (which == CAPNG_BOUNDING_SET)
    809 			return bounds_bit_check(capability, idx);
    810 	}
    811 	return 0;
    812 }
    813 
    814 char *capng_print_caps_numeric(capng_print_t where, capng_select_t set)
    815 {
    816 	char *ptr = NULL;
    817 
    818 	if (m.state < CAPNG_INIT)
    819 		return ptr;
    820 
    821 	if (where == CAPNG_PRINT_STDOUT) {
    822 		if (set & CAPNG_SELECT_CAPS) {
    823 			if (m.cap_ver == 1) {
    824 				printf( "Effective:    %08X\n"
    825 					"Permitted:    %08X\n"
    826 					"Inheritable:  %08X\n",
    827 					m.data.v1.effective,
    828 					m.data.v1.permitted,
    829 					m.data.v1.inheritable);
    830 			} else {
    831 				printf( "Effective:    %08X, %08X\n"
    832 					"Permitted:    %08X, %08X\n"
    833 					"Inheritable:  %08X, %08X\n",
    834 					m.data.v3[1].effective & UPPER_MASK,
    835 					m.data.v3[0].effective,
    836 					m.data.v3[1].permitted & UPPER_MASK,
    837 					m.data.v3[0].permitted,
    838 					m.data.v3[1].inheritable & UPPER_MASK,
    839 					m.data.v3[0].inheritable);
    840 
    841 			}
    842 		}
    843 #ifdef PR_CAPBSET_DROP
    844 		if (set & CAPNG_SELECT_BOUNDS)
    845 			printf("Bounding Set: %08X, %08X\n",
    846 				m.bounds[1] & UPPER_MASK, m.bounds[0]);
    847 #endif
    848 	} else if (where == CAPNG_PRINT_BUFFER) {
    849 		if (set & CAPNG_SELECT_CAPS) {
    850 			// Make it big enough for bounding set, too
    851 			ptr = malloc(160);
    852 			if (m.cap_ver == 1) {
    853 				snprintf(ptr, 160,
    854 					"Effective:   %08X\n"
    855 					"Permitted:   %08X\n"
    856 					"Inheritable: %08X\n",
    857 					m.data.v1.effective,
    858 					m.data.v1.permitted,
    859 					m.data.v1.inheritable);
    860 			} else {
    861 				snprintf(ptr, 160,
    862 					"Effective:   %08X, %08X\n"
    863 					"Permitted:   %08X, %08X\n"
    864 					"Inheritable: %08X, %08X\n",
    865 					m.data.v3[1].effective & UPPER_MASK,
    866 					m.data.v3[0].effective,
    867 					m.data.v3[1].permitted & UPPER_MASK,
    868 					m.data.v3[0].permitted,
    869 					m.data.v3[1].inheritable & UPPER_MASK,
    870 					m.data.v3[0].inheritable);
    871 			}
    872 		}
    873 		if (set & CAPNG_SELECT_BOUNDS) {
    874 #ifdef PR_CAPBSET_DROP
    875 			char *s;
    876 			if (ptr == NULL ){
    877 				ptr = malloc(40);
    878 				if (ptr == NULL)
    879 					return ptr;
    880 				*ptr = 0;
    881 				s = ptr;
    882 			} else
    883 				s = ptr + strlen(ptr);
    884 			snprintf(s, 40, "Bounding Set: %08X, %08X\n",
    885 					m.bounds[1] & UPPER_MASK, m.bounds[0]);
    886 #endif
    887 		}
    888 	}
    889 
    890 	return ptr;
    891 }
    892 
    893 char *capng_print_caps_text(capng_print_t where, capng_type_t which)
    894 {
    895 	unsigned int i;
    896 	int once = 0, cnt = 0;
    897 	char *ptr = NULL;
    898 
    899 	if (m.state < CAPNG_INIT)
    900 		return ptr;
    901 
    902 	for (i=0; i<=CAP_LAST_CAP; i++) {
    903 		if (capng_have_capability(which, i)) {
    904 			const char *n = capng_capability_to_name(i);
    905 			if (n == NULL)
    906 				n = "unknown";
    907 			if (where == CAPNG_PRINT_STDOUT) {
    908 				if (once == 0) {
    909 					printf("%s", n);
    910 					once++;
    911 				} else
    912 					printf(", %s", n);
    913 			} else if (where == CAPNG_PRINT_BUFFER) {
    914 				int len;
    915 				if (once == 0) {
    916 					ptr = malloc(CAP_LAST_CAP*18);
    917 					if (ptr == NULL)
    918 						return ptr;
    919 					len = sprintf(ptr+cnt, "%s", n);
    920 					once++;
    921 				} else
    922 					len = sprintf(ptr+cnt, ", %s", n);
    923 				if (len > 0)
    924 					cnt+=len;
    925 			}
    926 		}
    927 	}
    928 	if (once == 0) {
    929 		if (where == CAPNG_PRINT_STDOUT)
    930 			printf("none");
    931 		else
    932 			ptr = strdup("none");
    933 	}
    934 	return ptr;
    935 }
    936 
    937 void *capng_save_state(void)
    938 {
    939 	void *ptr = malloc(sizeof(m));
    940 	if (ptr)
    941 		memcpy(ptr, &m, sizeof(m));
    942 	return ptr;
    943 }
    944 
    945 void capng_restore_state(void **state)
    946 {
    947 	if (state) {
    948 		void *ptr = *state;
    949 		if (ptr)
    950 			memcpy(&m, ptr, sizeof(m));
    951 		free(ptr);
    952 		*state = NULL;
    953 	}
    954 }
    955 
    956