11d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich/* libcap-ng.c -- 21d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * Copyright 2009-10 Red Hat Inc., Durham, North Carolina. 31d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * All Rights Reserved. 41d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * 51d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * This library is free software; you can redistribute it and/or 61d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * modify it under the terms of the GNU Lesser General Public 71d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * License as published by the Free Software Foundation; either 81d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * version 2.1 of the License, or (at your option) any later version. 91d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * 101d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * This library is distributed in the hope that it will be useful, 111d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * but WITHOUT ANY WARRANTY; without even the implied warranty of 121d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 131d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * Lesser General Public License for more details. 141d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * 151d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * You should have received a copy of the GNU Lesser General Public 161d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * License along with this library; if not, write to the Free Software 171d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 181d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * 191d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * Authors: 201d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * Steve Grubb <sgrubb@redhat.com> 211d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich */ 221d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 231d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include "config.h" 241d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include "cap-ng.h" 251d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include <string.h> 261d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include <stdarg.h> 271d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include <stdio.h> 281d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#if !defined(ANDROID) 291d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include <stdio_ext.h> 301d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 311d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include <stdlib.h> 321d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include <sys/prctl.h> 331d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include <grp.h> 341d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include <sys/stat.h> 351d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include <stdarg.h> 361d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include <errno.h> 371d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include <byteswap.h> 381d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#ifdef HAVE_SYSCALL_H 391d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include <sys/syscall.h> 401d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 411d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#ifdef HAVE_LINUX_SECUREBITS_H 421d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include <linux/securebits.h> 431d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 441d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 451d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich/* 461d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * Some milestones of when things became available: 471d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * 2.6.24 kernel XATTR_NAME_CAPS 481d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * 2.6.25 kernel PR_CAPBSET_DROP, CAPABILITY_VERSION_2 491d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * 2.6.26 kernel PR_SET_SECUREBITS, SECURE_*_LOCKED, VERSION_3 501d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich */ 511d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 521d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich/* External syscall prototypes */ 531d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichextern int capset(cap_user_header_t header, cap_user_data_t data); 541d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichextern int capget(cap_user_header_t header, const cap_user_data_t data); 551d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 561d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich// Local defines 571d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#define MASK(x) (1U << (x)) 581d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#ifdef PR_CAPBSET_DROP 591d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#define UPPER_MASK ~(unsigned)((~0U)<<(CAP_LAST_CAP-31)) 601d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#else 611d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich// For v1 systems UPPER_MASK will never be used 621d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#define UPPER_MASK (unsigned)(~0U) 631d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 641d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 651d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich// Re-define cap_valid so its uniform between V1 and V3 661d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#undef cap_valid 671d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#define cap_valid(x) ((x) <= CAP_LAST_CAP) 681d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 691d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich// If we don't have the xattr library, then we can't 701d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich// compile-in file system capabilities 711d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#ifndef HAVE_ATTR_XATTR_H 721d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#undef VFS_CAP_U32 731d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 741d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 751d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#ifdef VFS_CAP_U32 761d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich #include <attr/xattr.h> 771d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich #if __BYTE_ORDER == __BIG_ENDIAN 781d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich #define FIXUP(x) bswap_32(x) 791d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich #else 801d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich #define FIXUP(x) (x) 811d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich #endif 821d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 831d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 841d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#ifndef _LINUX_CAPABILITY_VERSION_1 851d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#define _LINUX_CAPABILITY_VERSION_1 0x19980330 861d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 871d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#ifndef _LINUX_CAPABILITY_VERSION_2 881d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#define _LINUX_CAPABILITY_VERSION_2 0x20071026 891d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 901d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#ifndef _LINUX_CAPABILITY_VERSION_3 911d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#define _LINUX_CAPABILITY_VERSION_3 0x20080522 921d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 931d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 941d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich// This public API went private in the 2.6.36 kernel - hope it never changes 951d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#ifndef XATTR_CAPS_SUFFIX 961d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#define XATTR_CAPS_SUFFIX "capability" 971d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 981d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#ifndef XATTR_SECURITY_PREFIX 991d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#define XATTR_SECURITY_PREFIX "security." 1001d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 1011d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#ifndef XATTR_NAME_CAPS 1021d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#define XATTR_NAME_CAPS XATTR_SECURITY_PREFIX XATTR_CAPS_SUFFIX 1031d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 1041d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 1051d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 1061d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich/* Child processes can't get caps back */ 1071d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#ifndef SECURE_NOROOT 1081d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#define SECURE_NOROOT 0 1091d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 1101d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#ifndef SECURE_NOROOT_LOCKED 1111d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#define SECURE_NOROOT_LOCKED 1 /* make bit-0 immutable */ 1121d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 1131d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich/* Setuid apps run by uid 0 don't get caps back */ 1141d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#ifndef SECURE_NO_SETUID_FIXUP 1151d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#define SECURE_NO_SETUID_FIXUP 2 1161d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 1171d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#ifndef SECURE_NO_SETUID_FIXUP_LOCKED 1181d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#define SECURE_NO_SETUID_FIXUP_LOCKED 3 /* make bit-2 immutable */ 1191d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 1201d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 1211d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich// States: new, allocated, initted, updated, applied 1221d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichtypedef enum { CAPNG_NEW, CAPNG_ERROR, CAPNG_ALLOCATED, CAPNG_INIT, 1231d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich CAPNG_UPDATED, CAPNG_APPLIED } capng_states_t; 1241d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 1251d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich// Create an easy data struct out of the kernel definitions 1261d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichtypedef union { 1271d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich struct __user_cap_data_struct v1; 1281d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich struct __user_cap_data_struct v3[2]; 1291d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} cap_data_t; 1301d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 1311d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich// This struct keeps all state info 1321d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichstruct cap_ng 1331d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich{ 1341d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich int cap_ver; 1351d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich struct __user_cap_header_struct hdr; 1361d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich cap_data_t data; 1371d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich capng_states_t state; 1381d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich __u32 bounds[2]; 1391d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich}; 1401d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 1411d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich// Global variables with per thread uniqueness 1421d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichstatic __thread struct cap_ng m = { 1, 1431d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich {0, 0}, 1441d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich { {0, 0, 0} }, 1451d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich CAPNG_NEW, 1461d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich {0, 0} }; 1471d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 1481d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 1491d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichstatic void init(void) 1501d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich{ 1511d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (m.state != CAPNG_NEW) 1521d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return; 1531d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 1541d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich memset(&m.hdr, 0, sizeof(m.hdr)); 1551d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich (void)capget(&m.hdr, NULL); // Returns -EINVAL 1561d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (m.hdr.version == _LINUX_CAPABILITY_VERSION_3 || 1571d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.hdr.version == _LINUX_CAPABILITY_VERSION_2) { 1581d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.cap_ver = 3; 1591d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } else if (m.hdr.version == _LINUX_CAPABILITY_VERSION_1) { 1601d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.cap_ver = 1; 1611d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } else { 1621d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.state = CAPNG_ERROR; 1631d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return; 1641d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 1651d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 1661d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich memset(&m.data, 0, sizeof(cap_data_t)); 1671d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#ifdef HAVE_SYSCALL_H 1681d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.hdr.pid = (unsigned)syscall(__NR_gettid); 1691d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#else 1701d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.hdr.pid = (unsigned)getpid(); 1711d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 1721d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.state = CAPNG_ALLOCATED; 1731d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} 1741d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 1751d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichvoid capng_clear(capng_select_t set) 1761d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich{ 1771d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (m.state == CAPNG_NEW) 1781d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich init(); 1791d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (m.state == CAPNG_ERROR) 1801d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return; 1811d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 1821d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (set & CAPNG_SELECT_CAPS) 1831d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich memset(&m.data, 0, sizeof(cap_data_t)); 1841d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#ifdef PR_CAPBSET_DROP 1851d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (set & CAPNG_SELECT_BOUNDS) 1861d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich memset(m.bounds, 0, sizeof(m.bounds)); 1871d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 1881d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.state = CAPNG_INIT; 1891d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} 1901d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 1911d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichvoid capng_fill(capng_select_t set) 1921d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich{ 1931d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (m.state == CAPNG_NEW) 1941d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich init(); 1951d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (m.state == CAPNG_ERROR) 1961d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return; 1971d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 1981d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (set & CAPNG_SELECT_CAPS) { 1991d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (m.cap_ver == 1) { 2001d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v1.effective = 0x7FFFFFFFU; 2011d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v1.permitted = 0x7FFFFFFFU; 2021d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v1.inheritable = 0; 2031d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } else { 2041d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v3[0].effective = 0xFFFFFFFFU; 2051d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v3[0].permitted = 0xFFFFFFFFU; 2061d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v3[0].inheritable = 0; 2071d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v3[1].effective = 0xFFFFFFFFU; 2081d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v3[1].permitted = 0xFFFFFFFFU; 2091d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v3[1].inheritable = 0; 2101d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 2111d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 2121d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#ifdef PR_CAPBSET_DROP 2131d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (set & CAPNG_SELECT_BOUNDS) { 2141d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich unsigned i; 2151d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich for (i=0; i<sizeof(m.bounds)/sizeof(__u32); i++) 2161d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.bounds[i] = 0xFFFFFFFFU; 2171d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 2181d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 2191d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.state = CAPNG_INIT; 2201d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} 2211d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 2221d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichvoid capng_setpid(int pid) 2231d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich{ 2241d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (m.state == CAPNG_NEW) 2251d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich init(); 2261d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (m.state == CAPNG_ERROR) 2271d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return; 2281d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 2291d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.hdr.pid = pid; 2301d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} 2311d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 2321d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#ifdef PR_CAPBSET_DROP 2331d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichstatic int get_bounding_set(void) 2341d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich{ 2351d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich char buf[64]; 2361d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich FILE *f; 2371d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 2381d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich snprintf(buf, sizeof(buf), "/proc/%u/status", m.hdr.pid ? m.hdr.pid : 2391d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#ifdef HAVE_SYSCALL_H 2401d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich (unsigned)syscall(__NR_gettid)); 2411d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#else 2421d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich (unsigned)getpid(); 2431d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 2441d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich f = fopen(buf, "re"); 2451d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (f == NULL) 2461d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return -1; 2471d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#if !defined(ANDROID) 2481d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich __fsetlocking(f, FSETLOCKING_BYCALLER); 2491d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 2501d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich while (fgets(buf, sizeof(buf), f)) { 2511d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (strncmp(buf, "CapB", 4)) 2521d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich continue; 2531d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich sscanf(buf, "CapBnd: %08x%08x", &m.bounds[1], &m.bounds[0]); 2541d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich fclose(f); 2551d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return 0; 2561d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 2571d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich fclose(f); 2581d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return -1; 2591d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} 2601d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 2611d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 2621d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichint capng_get_caps_process(void) 2631d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich{ 2641d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich int rc; 2651d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 2661d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (m.state == CAPNG_NEW) 2671d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich init(); 2681d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (m.state == CAPNG_ERROR) 2691d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return -1; 2701d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 2711d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich rc = capget((cap_user_header_t)&m.hdr, (cap_user_data_t)&m.data); 2721d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (rc == 0) { 2731d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.state = CAPNG_INIT; 2741d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#ifdef PR_CAPBSET_DROP 2751d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich rc = get_bounding_set(); 2761d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (rc < 0) 2771d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.state = CAPNG_ERROR; 2781d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 2791d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 2801d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 2811d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return rc; 2821d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} 2831d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 2841d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#ifdef VFS_CAP_U32 2851d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichstatic int load_data(const struct vfs_cap_data *filedata, int size) 2861d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich{ 2871d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich unsigned int magic; 2881d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 2891d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (m.cap_ver == 1) 2901d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return -1; // Should never get here but just in case 2911d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 2921d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich magic = FIXUP(filedata->magic_etc); 2931d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich switch (magic & VFS_CAP_REVISION_MASK) 2941d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich { 2951d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich case VFS_CAP_REVISION_1: 2961d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.cap_ver = 1; 2971d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (size != XATTR_CAPS_SZ_1) 2981d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return -1; 2991d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich break; 3001d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich case VFS_CAP_REVISION_2: 3011d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.cap_ver = 2; 3021d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (size != XATTR_CAPS_SZ_2) 3031d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return -1; 3041d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich break; 3051d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich default: 3061d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return -1; 3071d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 3081d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 3091d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich // Now stuff the data structures 3101d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v3[0].permitted = FIXUP(filedata->data[0].permitted); 3111d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v3[1].permitted = FIXUP(filedata->data[1].permitted); 3121d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v3[0].inheritable = FIXUP(filedata->data[0].inheritable); 3131d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v3[1].inheritable = FIXUP(filedata->data[1].inheritable); 3141d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (magic & VFS_CAP_FLAGS_EFFECTIVE) { 3151d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v3[0].effective = 3161d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v3[0].permitted | m.data.v3[0].inheritable; 3171d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v3[1].effective = 3181d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v3[1].permitted | m.data.v3[1].inheritable; 3191d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } else { 3201d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v3[0].effective = 0; 3211d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v3[1].effective = 0; 3221d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 3231d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return 0; 3241d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} 3251d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 3261d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 3271d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichint capng_get_caps_fd(int fd) 3281d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich{ 3291d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#ifndef VFS_CAP_U32 3301d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return -1; 3311d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#else 3321d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich int rc; 3331d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich struct vfs_cap_data filedata; 3341d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 3351d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (m.state == CAPNG_NEW) 3361d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich init(); 3371d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (m.state == CAPNG_ERROR) 3381d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return -1; 3391d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 3401d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich rc = fgetxattr(fd, XATTR_NAME_CAPS, &filedata, sizeof(filedata)); 3411d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (rc <= 0) 3421d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return -1; 3431d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 3441d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich rc = load_data(&filedata, rc); 3451d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (rc == 0) 3461d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.state = CAPNG_INIT; 3471d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 3481d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return rc; 3491d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 3501d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} 3511d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 3521d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichstatic void v1_update(capng_act_t action, unsigned int capability, __u32 *data) 3531d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich{ 3541d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (action == CAPNG_ADD) 3551d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich *data |= MASK(capability); 3561d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich else 3571d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich *data &= ~(MASK(capability)); 3581d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} 3591d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 3601d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichstatic void update_effective(capng_act_t action, unsigned int capability, 3611d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich unsigned int idx) 3621d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich{ 3631d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (action == CAPNG_ADD) 3641d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v3[idx].effective |= MASK(capability); 3651d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich else 3661d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v3[idx].effective &= ~(MASK(capability)); 3671d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} 3681d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 3691d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichstatic void update_permitted(capng_act_t action, unsigned int capability, 3701d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich unsigned int idx) 3711d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich{ 3721d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (action == CAPNG_ADD) 3731d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v3[idx].permitted |= MASK(capability); 3741d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich else 3751d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v3[idx].permitted &= ~(MASK(capability)); 3761d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} 3771d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 3781d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichstatic void update_inheritable(capng_act_t action, unsigned int capability, 3791d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich unsigned int idx) 3801d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich{ 3811d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (action == CAPNG_ADD) 3821d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v3[idx].inheritable |= MASK(capability); 3831d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich else 3841d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v3[idx].inheritable &= ~(MASK(capability)); 3851d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} 3861d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 3871d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichstatic void update_bounding_set(capng_act_t action, unsigned int capability, 3881d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich unsigned int idx) 3891d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich{ 3901d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#ifdef PR_CAPBSET_DROP 3911d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (action == CAPNG_ADD) 3921d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.bounds[idx] |= MASK(capability); 3931d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich else 3941d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.bounds[idx] &= ~(MASK(capability)); 3951d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 3961d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} 3971d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 3981d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichint capng_update(capng_act_t action, capng_type_t type, unsigned int capability) 3991d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich{ 4001d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich // Before updating, we expect that the data is initialized to something 4011d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (m.state < CAPNG_INIT) 4021d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return -1; 4031d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (!cap_valid(capability)) { 4041d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich errno = EINVAL; 4051d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return -1; 4061d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 4071d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 4081d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (m.cap_ver == 1) { 4091d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (CAPNG_EFFECTIVE & type) 4101d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich v1_update(action, capability, &m.data.v1.effective); 4111d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (CAPNG_PERMITTED & type) 4121d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich v1_update(action, capability, &m.data.v1.permitted); 4131d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (CAPNG_INHERITABLE & type) 4141d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich v1_update(action, capability, &m.data.v1.inheritable); 4151d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } else { 4161d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich int idx; 4171d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 4181d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (capability > 31) { 4191d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich idx = capability>>5; 4201d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich capability %= 32; 4211d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } else 4221d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich idx = 0; 4231d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 4241d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (CAPNG_EFFECTIVE & type) 4251d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich update_effective(action, capability, idx); 4261d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (CAPNG_PERMITTED & type) 4271d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich update_permitted(action, capability, idx); 4281d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (CAPNG_INHERITABLE & type) 4291d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich update_inheritable(action, capability, idx); 4301d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (CAPNG_BOUNDING_SET & type) 4311d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich update_bounding_set(action, capability, idx); 4321d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 4331d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 4341d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.state = CAPNG_UPDATED; 4351d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return 0; 4361d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} 4371d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 4381d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichint capng_updatev(capng_act_t action, capng_type_t type, 4391d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich unsigned int capability, ...) 4401d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich{ 4411d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich int rc; 4421d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich unsigned int cap; 4431d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich va_list ap; 4441d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 4451d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich rc = capng_update(action, type, capability); 4461d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (rc) 4471d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return rc; 4481d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich va_start(ap, capability); 4491d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich cap = va_arg(ap, unsigned int); 4501d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich while (cap_valid(cap)) { 4511d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich rc = capng_update(action, type, cap); 4521d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (rc) 4531d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich break; 4541d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich cap = va_arg(ap, unsigned int); 4551d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 4561d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich va_end(ap); 4571d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 4581d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich // See if planned exit or invalid 4591d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (cap == (unsigned)-1) 4601d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich rc = 0; 4611d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich else { 4621d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich rc = -1; 4631d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich errno = EINVAL; 4641d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 4651d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 4661d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return rc; 4671d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} 4681d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 4691d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichint capng_apply(capng_select_t set) 4701d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich{ 4711d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich int rc = -1; 4721d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 4731d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich // Before updating, we expect that the data is initialized to something 4741d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (m.state < CAPNG_INIT) 4751d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return -1; 4761d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 4771d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (set & CAPNG_SELECT_BOUNDS) { 4781d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#ifdef PR_CAPBSET_DROP 4791d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich void *s = capng_save_state(); 4801d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich capng_get_caps_process(); 4811d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (capng_have_capability(CAPNG_EFFECTIVE, CAP_SETPCAP)) { 4821d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich int i; 4831d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich capng_restore_state(&s); 4841d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich rc = 0; 4851d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich for (i=0; i <= CAP_LAST_CAP && rc == 0; i++) 4861d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (capng_have_capability(CAPNG_BOUNDING_SET, 4871d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich i) == 0) 4881d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich rc = prctl(PR_CAPBSET_DROP, i, 0, 0, 0); 4891d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (rc == 0) 4901d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.state = CAPNG_APPLIED; 4911d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } else 4921d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich capng_restore_state(&s); 4931d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#else 4941d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich rc = 0; 4951d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 4961d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 4971d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (set & CAPNG_SELECT_CAPS) { 4981d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich rc = capset((cap_user_header_t)&m.hdr, 4991d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich (cap_user_data_t)&m.data); 5001d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (rc == 0) 5011d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.state = CAPNG_APPLIED; 5021d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 5031d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return rc; 5041d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} 5051d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 5061d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#ifdef VFS_CAP_U32 5071d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichstatic int save_data(struct vfs_cap_data *filedata, int *size) 5081d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich{ 5091d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich // Now stuff the data structures 5101d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (m.cap_ver == 1) { 5111d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich filedata->data[0].permitted = FIXUP(m.data.v1.permitted); 5121d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich filedata->data[0].inheritable = FIXUP(m.data.v1.inheritable); 5131d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich filedata->magic_etc = FIXUP(VFS_CAP_REVISION_1); 5141d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich *size = XATTR_CAPS_SZ_1; 5151d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } else { 5161d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich int eff; 5171d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 5181d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (m.data.v3[0].effective || m.data.v3[1].effective) 5191d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich eff = VFS_CAP_FLAGS_EFFECTIVE; 5201d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich else 5211d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich eff = 0; 5221d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich filedata->data[0].permitted = FIXUP(m.data.v3[0].permitted); 5231d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich filedata->data[0].inheritable = FIXUP(m.data.v3[0].inheritable); 5241d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich filedata->data[1].permitted = FIXUP(m.data.v3[1].permitted); 5251d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich filedata->data[1].inheritable = FIXUP(m.data.v3[1].inheritable); 5261d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich filedata->magic_etc = FIXUP(VFS_CAP_REVISION_2 | eff); 5271d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich *size = XATTR_CAPS_SZ_2; 5281d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 5291d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 5301d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return 0; 5311d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} 5321d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 5331d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 5341d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichint capng_apply_caps_fd(int fd) 5351d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich{ 5361d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#ifndef VFS_CAP_U32 5371d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return -1; 5381d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#else 5391d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich int rc, size; 5401d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich struct vfs_cap_data filedata; 5411d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich struct stat buf; 5421d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 5431d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich // Before updating, we expect that the data is initialized to something 5441d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (m.state < CAPNG_INIT) 5451d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return -1; 5461d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 5471d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (fstat(fd, &buf) != 0) 5481d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return -1; 5491d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (S_ISLNK(buf.st_mode) || !S_ISREG(buf.st_mode)) { 5501d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich errno = EINVAL; 5511d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return -1; 5521d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 5531d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (capng_have_capabilities(CAPNG_SELECT_CAPS) == CAPNG_NONE) 5541d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich rc = fremovexattr(fd, XATTR_NAME_CAPS); 5551d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich else { 5561d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich save_data(&filedata, &size); 5571d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich rc = fsetxattr(fd, XATTR_NAME_CAPS, &filedata, size, 0); 5581d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 5591d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 5601d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (rc == 0) 5611d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.state = CAPNG_APPLIED; 5621d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 5631d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return rc; 5641d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 5651d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} 5661d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 5671d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich// Change uids keeping/removing only certain capabilities 5681d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich// flag to drop supp groups 5691d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichint capng_change_id(int uid, int gid, capng_flags_t flag) 5701d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich{ 5711d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich int rc, need_setgid, need_setuid; 5721d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 5731d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich // Before updating, we expect that the data is initialized to something 5741d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (m.state < CAPNG_INIT) 5751d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return -1; 5761d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 5771d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich // Check the current capabilities 5781d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#ifdef PR_CAPBSET_DROP 5791d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich // If newer kernel, we need setpcap to change the bounding set 5801d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (capng_have_capability(CAPNG_EFFECTIVE, CAP_SETPCAP) == 0 && 5811d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich flag & CAPNG_CLEAR_BOUNDING) 5821d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich capng_update(CAPNG_ADD, 5831d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich CAPNG_EFFECTIVE|CAPNG_PERMITTED, CAP_SETPCAP); 5841d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 5851d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (gid == -1 || capng_have_capability(CAPNG_EFFECTIVE, CAP_SETGID)) 5861d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich need_setgid = 0; 5871d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich else { 5881d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich need_setgid = 1; 5891d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich capng_update(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED, 5901d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich CAP_SETGID); 5911d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 5921d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (uid == -1 || capng_have_capability(CAPNG_EFFECTIVE, CAP_SETUID)) 5931d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich need_setuid = 0; 5941d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich else { 5951d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich need_setuid = 1; 5961d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich capng_update(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED, 5971d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich CAP_SETUID); 5981d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 5991d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 6001d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich // Tell system we want to keep caps across uid change 6011d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) 6021d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return -2; 6031d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 6041d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich // Change to the temp capabilities 6051d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich rc = capng_apply(CAPNG_SELECT_CAPS); 6061d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (rc < 0) 6071d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return -3; 6081d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 6091d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich // Clear bounding set if needed while we have CAP_SETPCAP 6101d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (flag & CAPNG_CLEAR_BOUNDING) { 6111d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich capng_clear(CAPNG_BOUNDING_SET); 6121d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich rc = capng_apply(CAPNG_SELECT_BOUNDS); 6131d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (rc) 6141d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return -8; 6151d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 6161d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 6171d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich // Change gid 6181d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (gid != -1) { 6191d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich rc = setresgid(gid, gid, gid); 6201d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (rc) 6211d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return -4; 6221d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 6231d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 6241d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich // See if we need to unload supplemental groups 6251d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if ((flag & CAPNG_DROP_SUPP_GRP) && gid != -1) { 6261d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (setgroups(0, NULL)) 6271d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return -5; 6281d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 6291d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 6301d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich // Change uid 6311d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (uid != -1) { 6321d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich rc = setresuid(uid, uid, uid); 6331d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (rc) 6341d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return -6; 6351d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 6361d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 6371d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich // Tell it we are done keeping capabilities 6381d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich rc = prctl(PR_SET_KEEPCAPS, 0, 0, 0, 0); 6391d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (rc) 6401d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return -7; 6411d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 6421d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich // Now throw away CAP_SETPCAP so no more changes 6431d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (need_setgid) 6441d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich capng_update(CAPNG_DROP, CAPNG_EFFECTIVE|CAPNG_PERMITTED, 6451d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich CAP_SETGID); 6461d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (need_setuid) 6471d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich capng_update(CAPNG_DROP, CAPNG_EFFECTIVE|CAPNG_PERMITTED, 6481d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich CAP_SETUID); 6491d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 6501d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich // Now drop setpcap & apply 6511d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich capng_update(CAPNG_DROP, CAPNG_EFFECTIVE|CAPNG_PERMITTED, 6521d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich CAP_SETPCAP); 6531d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich rc = capng_apply(CAPNG_SELECT_CAPS); 6541d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (rc < 0) 6551d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return -9; 6561d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 6571d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich // Done 6581d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.state = CAPNG_UPDATED; 6591d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return 0; 6601d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} 6611d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 6621d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichint capng_lock(void) 6631d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich{ 6641d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#ifdef PR_SET_SECUREBITS 6651d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich int rc = prctl(PR_SET_SECUREBITS, 6661d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 1 << SECURE_NOROOT | 6671d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 1 << SECURE_NOROOT_LOCKED | 6681d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 1 << SECURE_NO_SETUID_FIXUP | 6691d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 1 << SECURE_NO_SETUID_FIXUP_LOCKED, 0, 0, 0); 6701d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (rc) 6711d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return -1; 6721d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 6731d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 6741d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return 0; 6751d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} 6761d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 6771d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich// -1 - error, 0 - no caps, 1 partial caps, 2 full caps 6781d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichcapng_results_t capng_have_capabilities(capng_select_t set) 6791d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich{ 6801d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich int empty = 0, full = 0; 6811d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 6821d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich // First, try to init with current set 6831d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (m.state < CAPNG_INIT) 6841d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich capng_get_caps_process(); 6851d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 6861d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich // If we still don't have anything, error out 6871d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (m.state < CAPNG_INIT) 6881d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return CAPNG_FAIL; 6891d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 6901d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (set & CAPNG_SELECT_CAPS) { 6911d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (m.cap_ver == 1) { 6921d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (m.data.v1.effective == 0) 6931d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich empty = 1; 6941d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich // after fill, 30 bits starts from upper to lower 6951d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich else if (m.data.v1.effective == 0x7FFFFFFFU) 6961d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich full = 1; 6971d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich // actual capabilities read from system 6981d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich else if (m.data.v1.effective == 0xFFFFFEFFU) 6991d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich full = 1; 7001d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich else 7011d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return CAPNG_PARTIAL; 7021d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } else { 7031d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (m.data.v3[0].effective == 0) 7041d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich empty = 1; 7051d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich else if (m.data.v3[0].effective == 0xFFFFFFFFU) 7061d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich full = 1; 7071d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich else 7081d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return CAPNG_PARTIAL; 7091d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if ((m.data.v3[1].effective & UPPER_MASK) == 0) 7101d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich empty = 1; 7111d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich else if ((m.data.v3[1].effective & UPPER_MASK) == 7121d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich UPPER_MASK) 7131d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich full = 1; 7141d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich else 7151d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return CAPNG_PARTIAL; 7161d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 7171d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 7181d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#ifdef PR_CAPBSET_DROP 7191d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (set & CAPNG_SELECT_BOUNDS) { 7201d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (m.bounds[0] == 0) 7211d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich empty = 1; 7221d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich else if (m.bounds[0] == 0xFFFFFFFFU) 7231d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich full = 1; 7241d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich else 7251d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return CAPNG_PARTIAL; 7261d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if ((m.bounds[1] & UPPER_MASK) == 0) 7271d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich empty = 1; 7281d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich else if ((m.bounds[1] & UPPER_MASK) == UPPER_MASK) 7291d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich full = 1; 7301d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich else 7311d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return CAPNG_PARTIAL; 7321d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 7331d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 7341d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 7351d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (empty == 1 && full == 0) 7361d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return CAPNG_NONE; 7371d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich else if (empty == 0 && full == 1) 7381d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return CAPNG_FULL; 7391d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 7401d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return CAPNG_PARTIAL; 7411d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} 7421d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 7431d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichstatic int check_effective(unsigned int capability, unsigned int idx) 7441d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich{ 7451d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return MASK(capability) & m.data.v3[idx].effective ? 1 : 0; 7461d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} 7471d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 7481d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichstatic int check_permitted(unsigned int capability, unsigned int idx) 7491d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich{ 7501d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return MASK(capability) & m.data.v3[idx].permitted ? 1 : 0; 7511d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} 7521d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 7531d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichstatic int check_inheritable(unsigned int capability, unsigned int idx) 7541d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich{ 7551d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return MASK(capability) & m.data.v3[idx].inheritable ? 1 : 0; 7561d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} 7571d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 7581d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichstatic int bounds_bit_check(unsigned int capability, unsigned int idx) 7591d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich{ 7601d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#ifdef PR_CAPBSET_DROP 7611d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return MASK(capability) & m.bounds[idx] ? 1 : 0; 7621d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#else 7631d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return 0; 7641d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 7651d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} 7661d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 7671d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichstatic int v1_check(unsigned int capability, __u32 data) 7681d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich{ 7691d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return MASK(capability) & data ? 1 : 0; 7701d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} 7711d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 7721d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichint capng_have_capability(capng_type_t which, unsigned int capability) 7731d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich{ 7741d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich // First, try to init with current set 7751d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (m.state < CAPNG_INIT) 7761d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich capng_get_caps_process(); 7771d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 7781d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich // If we still don't have anything, error out 7791d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (m.state < CAPNG_INIT) 7801d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return CAPNG_FAIL; 7811d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (m.cap_ver == 1 && capability > 31) 7821d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return 0; 7831d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (!cap_valid(capability)) 7841d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return 0; 7851d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 7861d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (m.cap_ver == 1) { 7871d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (which == CAPNG_EFFECTIVE) 7881d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return v1_check(capability, m.data.v1.effective); 7891d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich else if (which == CAPNG_PERMITTED) 7901d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return v1_check(capability, m.data.v1.permitted); 7911d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich else if (which == CAPNG_INHERITABLE) 7921d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return v1_check(capability, m.data.v1.inheritable); 7931d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } else { 7941d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich unsigned int idx; 7951d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 7961d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (capability > 31) { 7971d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich idx = capability>>5; 7981d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich capability %= 32; 7991d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } else 8001d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich idx = 0; 8011d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 8021d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (which == CAPNG_EFFECTIVE) 8031d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return check_effective(capability, idx); 8041d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich else if (which == CAPNG_PERMITTED) 8051d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return check_permitted(capability, idx); 8061d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich else if (which == CAPNG_INHERITABLE) 8071d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return check_inheritable(capability, idx); 8081d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich else if (which == CAPNG_BOUNDING_SET) 8091d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return bounds_bit_check(capability, idx); 8101d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 8111d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return 0; 8121d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} 8131d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 8141d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichchar *capng_print_caps_numeric(capng_print_t where, capng_select_t set) 8151d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich{ 8161d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich char *ptr = NULL; 8171d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 8181d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (m.state < CAPNG_INIT) 8191d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return ptr; 8201d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 8211d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (where == CAPNG_PRINT_STDOUT) { 8221d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (set & CAPNG_SELECT_CAPS) { 8231d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (m.cap_ver == 1) { 8241d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf( "Effective: %08X\n" 8251d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich "Permitted: %08X\n" 8261d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich "Inheritable: %08X\n", 8271d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v1.effective, 8281d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v1.permitted, 8291d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v1.inheritable); 8301d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } else { 8311d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf( "Effective: %08X, %08X\n" 8321d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich "Permitted: %08X, %08X\n" 8331d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich "Inheritable: %08X, %08X\n", 8341d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v3[1].effective & UPPER_MASK, 8351d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v3[0].effective, 8361d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v3[1].permitted & UPPER_MASK, 8371d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v3[0].permitted, 8381d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v3[1].inheritable & UPPER_MASK, 8391d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v3[0].inheritable); 8401d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 8411d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 8421d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 8431d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#ifdef PR_CAPBSET_DROP 8441d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (set & CAPNG_SELECT_BOUNDS) 8451d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("Bounding Set: %08X, %08X\n", 8461d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.bounds[1] & UPPER_MASK, m.bounds[0]); 8471d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 8481d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } else if (where == CAPNG_PRINT_BUFFER) { 8491d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (set & CAPNG_SELECT_CAPS) { 8501d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich // Make it big enough for bounding set, too 8511d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich ptr = malloc(160); 8521d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (m.cap_ver == 1) { 8531d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich snprintf(ptr, 160, 8541d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich "Effective: %08X\n" 8551d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich "Permitted: %08X\n" 8561d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich "Inheritable: %08X\n", 8571d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v1.effective, 8581d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v1.permitted, 8591d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v1.inheritable); 8601d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } else { 8611d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich snprintf(ptr, 160, 8621d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich "Effective: %08X, %08X\n" 8631d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich "Permitted: %08X, %08X\n" 8641d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich "Inheritable: %08X, %08X\n", 8651d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v3[1].effective & UPPER_MASK, 8661d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v3[0].effective, 8671d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v3[1].permitted & UPPER_MASK, 8681d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v3[0].permitted, 8691d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v3[1].inheritable & UPPER_MASK, 8701d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.data.v3[0].inheritable); 8711d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 8721d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 8731d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (set & CAPNG_SELECT_BOUNDS) { 8741d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#ifdef PR_CAPBSET_DROP 8751d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich char *s; 8761d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (ptr == NULL ){ 8771d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich ptr = malloc(40); 8781d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (ptr == NULL) 8791d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return ptr; 8801d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich *ptr = 0; 8811d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich s = ptr; 8821d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } else 8831d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich s = ptr + strlen(ptr); 8841d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich snprintf(s, 40, "Bounding Set: %08X, %08X\n", 8851d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich m.bounds[1] & UPPER_MASK, m.bounds[0]); 8861d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 8871d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 8881d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 8891d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 8901d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return ptr; 8911d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} 8921d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 8931d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichchar *capng_print_caps_text(capng_print_t where, capng_type_t which) 8941d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich{ 8951d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich unsigned int i; 8961d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich int once = 0, cnt = 0; 8971d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich char *ptr = NULL; 8981d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 8991d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (m.state < CAPNG_INIT) 9001d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return ptr; 9011d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 9021d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich for (i=0; i<=CAP_LAST_CAP; i++) { 9031d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (capng_have_capability(which, i)) { 9041d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich const char *n = capng_capability_to_name(i); 9051d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (n == NULL) 9061d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich n = "unknown"; 9071d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (where == CAPNG_PRINT_STDOUT) { 9081d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (once == 0) { 9091d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("%s", n); 9101d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich once++; 9111d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } else 9121d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf(", %s", n); 9131d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } else if (where == CAPNG_PRINT_BUFFER) { 9141d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich int len; 9151d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (once == 0) { 9161d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich ptr = malloc(CAP_LAST_CAP*18); 9171d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (ptr == NULL) 9181d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return ptr; 9191d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich len = sprintf(ptr+cnt, "%s", n); 9201d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich once++; 9211d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } else 9221d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich len = sprintf(ptr+cnt, ", %s", n); 9231d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (len > 0) 9241d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich cnt+=len; 9251d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 9261d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 9271d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 9281d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (once == 0) { 9291d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (where == CAPNG_PRINT_STDOUT) 9301d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich printf("none"); 9311d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich else 9321d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich ptr = strdup("none"); 9331d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 9341d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return ptr; 9351d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} 9361d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 9371d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichvoid *capng_save_state(void) 9381d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich{ 9391d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich void *ptr = malloc(sizeof(m)); 9401d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (ptr) 9411d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich memcpy(ptr, &m, sizeof(m)); 9421d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return ptr; 9431d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} 9441d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 9451d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichvoid capng_restore_state(void **state) 9461d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich{ 9471d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (state) { 9481d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich void *ptr = *state; 9491d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (ptr) 9501d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich memcpy(&m, ptr, sizeof(m)); 9511d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich free(ptr); 9521d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich *state = NULL; 9531d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 9541d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} 9551d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 956