aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Morgan <morgan@kernel.org>2007-07-18 00:02:08 -0700
committerAndrew Morgan <morgan@kernel.org>2007-08-13 23:33:12 -0700
commite6033df7d6f7f913a1807964b770daf7f3567d96 (patch)
tree9ce41a914064fac2f497d4b0acc43728c4c8f084
parentcd27cfaf1b6559296e2cbd357079f93f438b1458 (diff)
downloadlibcap-e6033df7d6f7f913a1807964b770daf7f3567d96.tar.gz
Add tentitive support for filesystem capabilities with 2.6.23-mm kernels
-rw-r--r--libcap/Makefile12
-rw-r--r--libcap/_makenames.c2
-rw-r--r--libcap/cap_file.c111
-rw-r--r--libcap/cap_sys.c20
-rw-r--r--libcap/include/sys/capability.h3
-rw-r--r--progs/Makefile7
-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;