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