diff options
author | Andrew Morgan <morgan@kernel.org> | 2007-07-18 00:02:08 -0700 |
---|---|---|
committer | Andrew Morgan <morgan@kernel.org> | 2007-08-13 23:33:12 -0700 |
commit | e6033df7d6f7f913a1807964b770daf7f3567d96 (patch) | |
tree | 9ce41a914064fac2f497d4b0acc43728c4c8f084 | |
parent | cd27cfaf1b6559296e2cbd357079f93f438b1458 (diff) | |
download | libcap-e6033df7d6f7f913a1807964b770daf7f3567d96.tar.gz |
Add tentitive support for filesystem capabilities with 2.6.23-mm kernels
-rw-r--r-- | libcap/Makefile | 12 | ||||
-rw-r--r-- | libcap/_makenames.c | 2 | ||||
-rw-r--r-- | libcap/cap_file.c | 111 | ||||
-rw-r--r-- | libcap/cap_sys.c | 20 | ||||
-rw-r--r-- | libcap/include/sys/capability.h | 3 | ||||
-rw-r--r-- | progs/Makefile | 7 | ||||
-rw-r--r-- | progs/getcap.c (renamed from progs/old/getcap.c) | 6 | ||||
-rw-r--r-- | progs/old/execcap.c (renamed from progs/execcap.c) | 0 | ||||
-rw-r--r-- | progs/old/setpcaps.c (renamed from progs/setpcaps.c) | 0 | ||||
-rw-r--r-- | progs/old/sucap.c (renamed from progs/sucap.c) | 0 | ||||
-rw-r--r-- | progs/setcap.c (renamed from progs/old/setcap.c) | 6 |
11 files changed, 130 insertions, 37 deletions
diff --git a/libcap/Makefile b/libcap/Makefile index f381d6a..61aab78 100644 --- a/libcap/Makefile +++ b/libcap/Makefile @@ -10,15 +10,13 @@ LIBNAME=$(LIBTITLE).so STALIBNAME=$(LIBTITLE).a # -FILES=cap_alloc cap_proc cap_extint cap_flag cap_text - -# for later when there is filesystem support for cap's: -#FILES += cap_file +FILES=cap_alloc cap_proc cap_extint cap_flag cap_text cap_sys cap_file INCLS=libcap.h cap_names.h $(INCS) OBJS=$(addsuffix .o, $(FILES)) MAJLIBNAME=$(LIBNAME).$(VERSION) MINLIBNAME=$(MAJLIBNAME).$(MINOR) +LDFLAGS+=-lattr all: $(MINLIBNAME) $(STALIBNAME) @@ -45,6 +43,12 @@ $(MINLIBNAME): $(OBJS) %.o: %.c $(INCLS) $(CC) $(CFLAGS) -c $< -o $@ +<<<<<<< HEAD:libcap/Makefile +======= +cap_sys.o: cap_sys.c $(INCLS) + $(CC) $(IPATH) -fPIC -Wall -O2 -c $< -o $@ + +>>>>>>> Add tentitive support for filesystem capabilities with 2.6.23-mm kernels:libcap/Makefile install: all mkdir -p -m 0755 $(INCDIR)/sys install -m 0644 include/sys/capability.h $(INCDIR)/sys diff --git a/libcap/_makenames.c b/libcap/_makenames.c index 61a7c47..212f0b4 100644 --- a/libcap/_makenames.c +++ b/libcap/_makenames.c @@ -7,7 +7,7 @@ #include <stdio.h> #include <stdlib.h> -#include <linux/capability.h> +#include <sys/capability.h> /* * #include 'sed' generated array diff --git a/libcap/cap_file.c b/libcap/cap_file.c index 85d72cb..d5c8aa7 100644 --- a/libcap/cap_file.c +++ b/libcap/cap_file.c @@ -1,11 +1,73 @@ /* - * Copyright (c) 1997 Andrew G Morgan <morgan@kernel.org> + * Copyright (c) 1997,2007 Andrew G Morgan <morgan@kernel.org> * * This file deals with setting capabilities on files. */ +#include <sys/types.h> +#include <attr/xattr.h> +#include <byteswap.h> + +#define XATTR_SECURITY_PREFIX "security." + #include "libcap.h" +#if __BYTE_ORDER == __BIG_ENDIAN +#define FIXUP_32BITS(x) bswap_32(x) +#else +#define FIXUP_32BITS(x) (x) +#endif + +static cap_t _fcaps_load(struct vfs_cap_data *rawvfscap, cap_t result) +{ + __u32 magic_etc; + + magic_etc = FIXUP_32BITS(rawvfscap->magic_etc); + switch (magic_etc & VFS_CAP_REVISION_MASK) { + case VFS_CAP_REVISION_1: + result->set.inheritable = + FIXUP_32BITS(rawvfscap->data[0].inheritable); + result->set.permitted = + FIXUP_32BITS(rawvfscap->data[0].permitted); + if (magic_etc & VFS_CAP_FLAGS_EFFECTIVE) { + result->set.effective = + result->set.inheritable | result->set.permitted; + } + break; + default: + cap_free(result); + result = NULL; + } + + return result; +} + +static int _fcaps_save(struct vfs_cap_data *rawvfscap, cap_t cap_d) +{ + if (!good_cap_t(cap_d)) { + errno = EINVAL; + return -1; + } + + _cap_debug("setting named file capabilities"); + + if (cap_d->set.effective == 0) { + rawvfscap->magic_etc = FIXUP_32BITS(VFS_CAP_REVISION); + } else if (cap_d->set.effective + ^ (cap_d->set.inheritable|cap_d->set.permitted)) { + errno = EINVAL; + return -1; + } else { + rawvfscap->magic_etc + = FIXUP_32BITS(VFS_CAP_REVISION|VFS_CAP_FLAGS_EFFECTIVE); + } + + rawvfscap->data[0].permitted = FIXUP_32BITS(cap_d->set.permitted); + rawvfscap->data[0].inheritable = FIXUP_32BITS(cap_d->set.inheritable); + + return 0; /* success */ +} + /* * Get the capabilities of an open file, as specified by its file * descriptor. @@ -18,16 +80,18 @@ cap_t cap_get_fd(int fildes) /* allocate a new capability set */ result = cap_init(); if (result) { + struct vfs_cap_data rawvfscap; + _cap_debug("getting fildes capabilities"); /* fill the capability sets via a system call */ - if (_fgetfilecap(fildes, sizeof(struct __cap_s), - &result->set[CAP_INHERITABLE], - &result->set[CAP_PERMITTED], - &result->set[CAP_EFFECTIVE] )) { + if (sizeof(rawvfscap) != fgetxattr(fildes, XATTR_NAME_CAPS, + &rawvfscap, sizeof(rawvfscap))) { cap_free(result); result = NULL; } + + result = _fcaps_load(&rawvfscap, result); } return result; @@ -44,15 +108,18 @@ cap_t cap_get_file(const char *filename) /* allocate a new capability set */ result = cap_init(); if (result) { - _cap_debug("getting named file capabilities"); + struct vfs_cap_data rawvfscap; + + _cap_debug("getting filename capabilities"); /* fill the capability sets via a system call */ - if (_getfilecap(filename, sizeof(struct __cap_s), - &result->set[CAP_INHERITABLE], - &result->set[CAP_PERMITTED], - &result->set[CAP_EFFECTIVE] )) + if (sizeof(rawvfscap) != getxattr(filename, XATTR_NAME_CAPS, + &rawvfscap, sizeof(rawvfscap))) { cap_free(result); result = NULL; + } + + result = _fcaps_load(&rawvfscap, result); } return result; @@ -65,16 +132,16 @@ cap_t cap_get_file(const char *filename) int cap_set_fd(int fildes, cap_t cap_d) { - if (!good_cap_t(cap_d)) { - errno = EINVAL; + struct vfs_cap_data rawvfscap; + + if (_fcaps_save(&rawvfscap, cap_d) != 0) { return -1; } _cap_debug("setting fildes capabilities"); - return _fsetfilecap(fildes, sizeof(struct __cap_s), - &cap_d->set[CAP_INHERITABLE], - &cap_d->set[CAP_PERMITTED], - &cap_d->set[CAP_EFFECTIVE] ); + + return fsetxattr(fildes, XATTR_NAME_CAPS, &rawvfscap, + sizeof(rawvfscap), 0); } /* @@ -83,15 +150,13 @@ int cap_set_fd(int fildes, cap_t cap_d) int cap_set_file(const char *filename, cap_t cap_d) { - if (!good_cap_t(cap_d)) { - errno = EINVAL; + struct vfs_cap_data rawvfscap; + + if (_fcaps_save(&rawvfscap, cap_d) != 0) { return -1; } _cap_debug("setting filename capabilities"); - return _setfilecap(filename, sizeof(struct __cap_s), - &cap_d->set[CAP_INHERITABLE], - &cap_d->set[CAP_PERMITTED], - &cap_d->set[CAP_EFFECTIVE] ); + return setxattr(filename, XATTR_NAME_CAPS, &rawvfscap, + sizeof(rawvfscap), 0); } - diff --git a/libcap/cap_sys.c b/libcap/cap_sys.c new file mode 100644 index 0000000..1aadef2 --- /dev/null +++ b/libcap/cap_sys.c @@ -0,0 +1,20 @@ +/* + * Copyright (c) 1997-8 Andrew G. Morgan <morgan@kernel.org> + * + * This file contains the system calls for getting and setting + * capabilities + */ + +#define user /* for more recent 2.6 kernels */ + +#include <linux/unistd.h> +#include <sys/capability.h> + +_syscall2(int, capget, + cap_user_header_t, header, + cap_user_data_t, data) + +_syscall2(int, capset, + cap_user_header_t, header, + const cap_user_data_t, data) + diff --git a/libcap/include/sys/capability.h b/libcap/include/sys/capability.h index 736061d..b9d2636 100644 --- a/libcap/include/sys/capability.h +++ b/libcap/include/sys/capability.h @@ -1,7 +1,6 @@ /* * <sys/capability.h> * - * * Copyright (C) 1997 Aleph One * Copyright (C) 1997-8 Andrew G. Morgan <morgan@kernel.org> * @@ -29,6 +28,8 @@ extern "C" { */ #define _LINUX_TYPES_H #define _LINUX_FS_H +#define __LINUX_COMPILER_H +#define __user typedef unsigned int __u32; diff --git a/progs/Makefile b/progs/Makefile index 4caf90c..8058cfa 100644 --- a/progs/Makefile +++ b/progs/Makefile @@ -4,15 +4,12 @@ include $(topdir)/Make.Rules # # Programs: all of the examples that we will compile # -PROGS=getpcaps setpcaps execcap sucap - -# when we have filecaps... -#PROGS+=getcap setcap +PROGS=getpcaps getcap setcap all: $(PROGS) $(PROGS): %: %.o - $(CC) $(COPTFLAG) $(LDFLAGS) -o $@ $< $(LIBS) + $(CC) --static $(COPTFLAG) $(LDFLAGS) -o $@ $< $(LIBS) %.o: %.c $(INCS) $(CC) $(CFLAGS) -c $< -o $@ diff --git a/progs/old/getcap.c b/progs/getcap.c index 7561f1c..a647b61 100644 --- a/progs/old/getcap.c +++ b/progs/getcap.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 Andrew G. Morgan <morgan@kernel.org> + * Copyright (c) 1997,2007 Andrew G. Morgan <morgan@kernel.org> * * This displays the capabilities of a given file. */ @@ -7,6 +7,7 @@ #include <errno.h> #include <stdio.h> #include <string.h> +#include <stdlib.h> #include <sys/capability.h> static void usage(void) @@ -43,6 +44,9 @@ int main(int argc, char **argv) result = cap_to_text(cap_d, &length); fprintf(stderr, "Capabilities for `%s':\n%s\n", *argv, result); + + cap_free(result); + cap_free(cap_d); } return 0; diff --git a/progs/execcap.c b/progs/old/execcap.c index 330cc93..330cc93 100644 --- a/progs/execcap.c +++ b/progs/old/execcap.c diff --git a/progs/setpcaps.c b/progs/old/setpcaps.c index 3720fce..3720fce 100644 --- a/progs/setpcaps.c +++ b/progs/old/setpcaps.c diff --git a/progs/sucap.c b/progs/old/sucap.c index 366a093..366a093 100644 --- a/progs/sucap.c +++ b/progs/old/sucap.c diff --git a/progs/old/setcap.c b/progs/setcap.c index ebf8608..d4a2ee4 100644 --- a/progs/old/setcap.c +++ b/progs/setcap.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 Andrew G. Morgan <morgan@kernel.org> + * Copyright (c) 1997,2007 Andrew G. Morgan <morgan@kernel.org> * * This sets the capabilities of a given file. */ @@ -7,6 +7,7 @@ #include <errno.h> #include <stdio.h> #include <string.h> +#include <stdlib.h> #include <sys/capability.h> #include <unistd.h> @@ -97,13 +98,14 @@ int main(int argc, char **argv) usage(); retval = cap_set_file(*++argv, cap_d); - if (retval != 0) { fprintf(stderr, "Failed to set capabilities on file `%s'\n" " (%s)\n", argv[0], strerror(errno)); usage(); } + + cap_free(cap_d); } return 0; |