aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew G. Morgan <morgan@kernel.org>2007-12-30 16:56:29 -0800
committerAndrew G. Morgan <morgan@kernel.org>2007-12-30 16:59:28 -0800
commitdf44db730f904c9fb1fdb83ab7f78abe8bd62844 (patch)
treeabd1ba3c46e2c3352ec65fa59be68c392b123f32
parent1e81b2c4070596060be05b3f200990ccf88aed13 (diff)
downloadlibcap-df44db730f904c9fb1fdb83ab7f78abe8bd62844.tar.gz
Filesystem capabilities are only meaningful on regular files.libcap-2.04
Do not support putting capabilies on symlinks and directories. You can get around this with an older version of libcap, or using the raw xattr API, but there is little point; the kernel only pays attention to file capabilities when it exec()s a file. Bug report: Chris Friedhoff Suggested fix: Serge E. Hallyn Signed-off-by: Andrew G. Morgan <morgan@kernel.org>
-rw-r--r--Make.Rules2
-rw-r--r--libcap/cap_file.c24
-rw-r--r--progs/setcap.c2
3 files changed, 27 insertions, 1 deletions
diff --git a/Make.Rules b/Make.Rules
index 2014f38..0ffabe4 100644
--- a/Make.Rules
+++ b/Make.Rules
@@ -41,7 +41,7 @@ LIBDIR=$(FAKEROOT)$(lib_prefix)/$(lib)
# common defines for libcap
LIBTITLE=libcap
VERSION=2
-MINOR=03
+MINOR=04
#
# Compilation specifics
diff --git a/libcap/cap_file.c b/libcap/cap_file.c
index d7a2da7..c025bf5 100644
--- a/libcap/cap_file.c
+++ b/libcap/cap_file.c
@@ -7,6 +7,8 @@
#include <sys/types.h>
#include <attr/xattr.h>
#include <byteswap.h>
+#include <sys/stat.h>
+#include <unistd.h>
#define XATTR_SECURITY_PREFIX "security."
@@ -227,6 +229,17 @@ int cap_set_fd(int fildes, cap_t cap_d)
{
struct vfs_cap_data rawvfscap;
int sizeofcaps;
+ struct stat buf;
+
+ if (fstat(fildes, &buf) != 0) {
+ _cap_debug("unable to stat file descriptor %d", fildes);
+ return -1;
+ }
+ if (S_ISLNK(buf.st_mode) || !S_ISREG(buf.st_mode)) {
+ _cap_debug("file descriptor %d for non-regular file", fildes);
+ errno = EINVAL;
+ return -1;
+ }
if (cap_d == NULL) {
_cap_debug("deleting fildes capabilities");
@@ -248,6 +261,17 @@ int cap_set_file(const char *filename, cap_t cap_d)
{
struct vfs_cap_data rawvfscap;
int sizeofcaps;
+ struct stat buf;
+
+ if (lstat(filename, &buf) != 0) {
+ _cap_debug("unable to stat file [%s]", filename);
+ return -1;
+ }
+ if (S_ISLNK(buf.st_mode) || !S_ISREG(buf.st_mode)) {
+ _cap_debug("file [%s] is not a regular file", filename);
+ errno = EINVAL;
+ return -1;
+ }
if (cap_d == NULL) {
_cap_debug("removing filename capabilities");
diff --git a/progs/setcap.c b/progs/setcap.c
index dc13c06..0501a9d 100644
--- a/progs/setcap.c
+++ b/progs/setcap.c
@@ -16,6 +16,8 @@ static void usage(void)
fprintf(stderr,
"usage: setcap [-q] (-r|-|<caps>) <filename> "
"[ ... (-r|-|<capsN>) <filenameN> ]\n"
+ "\n"
+ " Note <filename> must be a regular (non-symlink) file.\n"
);
exit(1);
}