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