~ubuntu-branches/ubuntu/wily/libcap-ng/wily-proposed

« back to all changes in this revision

Viewing changes to src/cap-ng.c

  • Committer: Bazaar Package Importer
  • Author(s): Pierre Chifflier
  • Date: 2009-09-10 01:41:27 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20090910014127-2ys2x32tx7w3yg5m
Tags: 0.6.1-1
* New upstream release (Closes: #545556)
* Bump Standards Version to 3.8.3 (no changes)
* Set package priority to optional (Closes: #545558)
* Add new bonary package for Python bindings

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
#include <stdarg.h>
34
34
#include <errno.h>
35
35
#include <byteswap.h>
 
36
#ifdef HAVE_LINUX_SECUREBITS_H
 
37
#include <linux/securebits.h>
 
38
#endif
 
39
 
 
40
/*
 
41
 * Some milestones of when things became available:
 
42
 * 2.6.24 kernel        XATTR_NAME_CAPS
 
43
 * 2.6.25 kernel        PR_CAPBSET_DROP, CAPABILITY_VERSION_2
 
44
 * 2.6.26 kernel        PR_SET_SECUREBITS, SECURE_*_LOCKED, VERSION_3
 
45
 */
36
46
 
37
47
/* External syscall prototypes */
38
48
extern int capset(cap_user_header_t header, cap_user_data_t data);
42
52
#define MASK(x) (1U << (x))
43
53
#ifdef PR_CAPBSET_DROP
44
54
#define UPPER_MASK ~(unsigned)((~0U)<<(CAP_LAST_CAP-31))
 
55
#else
 
56
// For v1 systems UPPER_MASK will never be used
 
57
#define UPPER_MASK (unsigned)(~0U)
45
58
#endif
46
59
 
47
60
// Re-define cap_valid so its uniform between V1 and V3
74
87
#define _LINUX_CAPABILITY_VERSION_3 0x20080522
75
88
#endif
76
89
 
 
90
/* Child processes can't get caps back */
77
91
#ifndef SECURE_NOROOT
78
 
#define SECURE_NOROOT                   0  /* children can't get caps back */
 
92
#define SECURE_NOROOT                   0
 
93
#endif
 
94
#ifndef SECURE_NOROOT_LOCKED
79
95
#define SECURE_NOROOT_LOCKED            1  /* make bit-0 immutable */
80
96
#endif
 
97
/* Setuid apps run by uid 0 don't get caps back */
 
98
#ifndef SECURE_NO_SETUID_FIXUP
 
99
#define SECURE_NO_SETUID_FIXUP          2  
 
100
#endif
 
101
#ifndef SECURE_NO_SETUID_FIXUP_LOCKED
 
102
#define SECURE_NO_SETUID_FIXUP_LOCKED   3  /* make bit-2 immutable */
 
103
#endif
 
104
 
81
105
 
82
106
// States: new, allocated, initted, updated, applied
83
107
typedef enum { CAPNG_NEW, CAPNG_ERROR, CAPNG_ALLOCATED, CAPNG_INIT,
154
178
 
155
179
        if (set & CAPNG_SELECT_CAPS) {
156
180
                if (m.cap_ver == 1) {
157
 
                        m.data.v1.effective = 0x7FFFFFFF;
158
 
                        m.data.v1.permitted = 0x7FFFFFFF;
 
181
                        m.data.v1.effective = 0x7FFFFFFFU;
 
182
                        m.data.v1.permitted = 0x7FFFFFFFU;
159
183
                        m.data.v1.inheritable = 0;
160
184
                } else {
161
 
                        m.data.v3[0].effective = 0xFFFFFFFF;
162
 
                        m.data.v3[0].permitted = 0xFFFFFFFF;
 
185
                        m.data.v3[0].effective = 0xFFFFFFFFU;
 
186
                        m.data.v3[0].permitted = 0xFFFFFFFFU;
163
187
                        m.data.v3[0].inheritable = 0;
164
 
                        m.data.v3[1].effective = 0xFFFFFFFF;
165
 
                        m.data.v3[1].permitted = 0xFFFFFFFF;
 
188
                        m.data.v3[1].effective = 0xFFFFFFFFU;
 
189
                        m.data.v3[1].permitted = 0xFFFFFFFFU;
166
190
                        m.data.v3[1].inheritable = 0;
167
191
                }
168
192
        }
170
194
        if (set & CAPNG_SELECT_BOUNDS) {
171
195
                unsigned i;
172
196
                for (i=0; i<sizeof(m.bounds)/sizeof(__u32); i++)
173
 
                        m.bounds[i] = 0xFFFFFFFF;
 
197
                        m.bounds[i] = 0xFFFFFFFFU;
174
198
        }
175
199
#endif
176
200
        m.state = CAPNG_INIT;
237
261
{
238
262
        unsigned int magic;
239
263
        
 
264
        if (m.cap_ver == 1)
 
265
                return -1;      // Should never get here but just in case
 
266
 
240
267
        magic = FIXUP(filedata->magic_etc);
241
268
        switch (magic & VFS_CAP_REVISION_MASK)
242
269
        {
255
282
        }
256
283
 
257
284
        // Now stuff the data structures
258
 
        if (m.cap_ver == 1) {
259
 
                m.data.v1.permitted = FIXUP(filedata->data[0].permitted);
260
 
                m.data.v1.inheritable = FIXUP(filedata->data[0].inheritable);
261
 
                m.data.v1.effective = m.data.v1.permitted |
262
 
                                                m.data.v1.inheritable;
 
285
        m.data.v3[0].permitted = FIXUP(filedata->data[0].permitted);
 
286
        m.data.v3[1].permitted = FIXUP(filedata->data[1].permitted);
 
287
        m.data.v3[0].inheritable = FIXUP(filedata->data[0].inheritable);
 
288
        m.data.v3[1].inheritable = FIXUP(filedata->data[1].inheritable);
 
289
        if (magic & VFS_CAP_FLAGS_EFFECTIVE) {
 
290
                m.data.v3[0].effective = 0xFFFFFFFFU;
 
291
                m.data.v3[1].effective = 0xFFFFFFFFU;
263
292
        } else {
264
 
                m.data.v3[0].permitted = FIXUP(filedata->data[0].permitted);
265
 
                m.data.v3[0].inheritable = FIXUP(filedata->data[0].inheritable);
266
 
                m.data.v3[0].effective = 
267
 
                        m.data.v3[0].permitted | m.data.v3[0].inheritable;
268
 
                m.data.v3[1].permitted = FIXUP(filedata->data[1].permitted);
269
 
                m.data.v3[1].inheritable = FIXUP(filedata->data[1].inheritable);
270
 
                if (magic & VFS_CAP_FLAGS_EFFECTIVE)
271
 
                        m.data.v3[1].effective = 
272
 
                            m.data.v3[1].permitted | m.data.v3[1].inheritable;
273
 
                else
274
 
                        m.data.v3[1].effective = 0;
 
293
                m.data.v3[0].effective = 0;
 
294
                m.data.v3[1].effective = 0;
275
295
        }
276
296
        return 0;
277
297
}
427
447
        if (m.state < CAPNG_INIT)
428
448
                return -1;
429
449
 
430
 
#ifdef PR_CAPBSET_DROP
431
450
        if (set & CAPNG_SELECT_BOUNDS) { 
 
451
#ifdef PR_CAPBSET_DROP
432
452
                void *s = capng_save_state();
433
453
                capng_get_caps_process();
434
454
                if (capng_have_capability(CAPNG_EFFECTIVE, CAP_SETPCAP)) {
443
463
                                m.state = CAPNG_APPLIED;
444
464
                } else
445
465
                        capng_restore_state(&s);
 
466
#else
 
467
                rc = 0;
 
468
#endif
446
469
        }
447
 
#endif
448
470
        if (set & CAPNG_SELECT_CAPS) {
449
471
                rc = capset((cap_user_header_t)&m.hdr,
450
472
                                (cap_user_data_t)&m.data);
526
548
                return -1;
527
549
 
528
550
        // Check the current capabilities
 
551
#ifdef PR_CAPBSET_DROP
 
552
        // If newer kernel, we need setpcap
529
553
        if (capng_have_capability(CAPNG_EFFECTIVE, CAP_SETPCAP) == 0)
530
554
                capng_update(CAPNG_ADD,
531
555
                                CAPNG_EFFECTIVE|CAPNG_PERMITTED, CAP_SETPCAP);
 
556
#endif
532
557
        if (gid == -1 || capng_have_capability(CAPNG_EFFECTIVE, CAP_SETGID))
533
558
                need_setgid = 0;
534
559
        else {
608
633
 
609
634
int capng_lock(void)
610
635
{
611
 
        int rc = 0;
612
 
 
613
636
#ifdef PR_SET_SECUREBITS
614
 
        rc = prctl(PR_SET_SECUREBITS, 1 << SECURE_NOROOT |
615
 
                                1 << SECURE_NOROOT_LOCKED);
 
637
        int rc = prctl(PR_SET_SECUREBITS,
 
638
                        1 << SECURE_NOROOT |
 
639
                        1 << SECURE_NOROOT_LOCKED |
 
640
                        1 << SECURE_NO_SETUID_FIXUP |
 
641
                        1 << SECURE_NO_SETUID_FIXUP_LOCKED);
616
642
        if (rc)
617
643
                return -1;
618
644
#endif
619
645
 
620
 
        return rc;
 
646
        return 0;
621
647
}
622
648
 
623
649
// -1 - error, 0 - no caps, 1 partial caps, 2 full caps
648
674
                } else {
649
675
                        if (m.data.v3[0].effective == 0)
650
676
                                empty = 1;
651
 
                        else if (m.data.v3[0].effective == 0xFFFFFFFF)
 
677
                        else if (m.data.v3[0].effective == 0xFFFFFFFFU)
652
678
                                full = 1;
653
679
                        else
654
680
                                return CAPNG_PARTIAL;
665
691
        if (set & CAPNG_SELECT_BOUNDS) {
666
692
                if (m.bounds[0] == 0)
667
693
                        empty = 1;
668
 
                else if (m.bounds[0] == 0xFFFFFFFF)
 
694
                else if (m.bounds[0] == 0xFFFFFFFFU)
669
695
                        full = 1;
670
696
                else
671
697
                        return CAPNG_PARTIAL;
688
714
 
689
715
static int check_effective(unsigned int capability, unsigned int idx)
690
716
{
691
 
        return MASK(capability) & m.data.v3[idx].effective;
 
717
        return MASK(capability) & m.data.v3[idx].effective ? 1 : 0;
692
718
}
693
719
 
694
720
static int check_permitted(unsigned int capability, unsigned int idx)
695
721
{
696
 
        return MASK(capability) & m.data.v3[idx].permitted;
 
722
        return MASK(capability) & m.data.v3[idx].permitted ? 1 : 0;
697
723
}
698
724
 
699
725
static int check_inheritable(unsigned int capability, unsigned int idx)
700
726
{
701
 
        return MASK(capability) & m.data.v3[idx].inheritable;
 
727
        return MASK(capability) & m.data.v3[idx].inheritable ? 1 : 0;
702
728
}
703
729
 
704
730
static int bounds_bit_check(unsigned int capability, unsigned int idx)
705
731
{
706
732
#ifdef PR_CAPBSET_DROP
707
 
        return MASK(capability) & m.bounds[idx];
 
733
        return MASK(capability) & m.bounds[idx] ? 1 : 0;
708
734
#else
709
735
        return 0;
710
736
#endif
712
738
 
713
739
static int v1_check(unsigned int capability, __u32 data)
714
740
{
715
 
        return MASK(capability) & data;
 
741
        return MASK(capability) & data ? 1 : 0;
716
742
}
717
743
 
718
744
int capng_have_capability(capng_type_t which, unsigned int capability)