aboutsummaryrefslogtreecommitdiff
path: root/libcap/cap_file.c
diff options
context:
space:
mode:
authorAndrew G. Morgan <morgan@kernel.org>2007-12-30 16:56:29 -0800
committerJorge Lucangeli Obes <jorgelo@google.com>2015-09-03 14:13:03 -0700
commitd7571cb19f4edbb30db6db63b0569d4056273a7f (patch)
treeabd1ba3c46e2c3352ec65fa59be68c392b123f32 /libcap/cap_file.c
parentf88ecb591cfdce00e46780a2adba55009840cbe8 (diff)
downloadlibcap-d7571cb19f4edbb30db6db63b0569d4056273a7f.tar.gz
Filesystem capabilities are only meaningful on regular files.
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>
Diffstat (limited to 'libcap/cap_file.c')
-rw-r--r--libcap/cap_file.c24
1 files changed, 24 insertions, 0 deletions
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");