Avoid memory allocation while opening smackfs files.
authorRafal Krypa <r.krypa@samsung.com>
Tue, 3 Dec 2013 14:58:57 +0000 (15:58 +0100)
committerJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Wed, 18 Dec 2013 19:29:38 +0000 (21:29 +0200)
Using openat() on pre-opened smackfs directory eliminates need to
construct absolute path to a smackfs file before opening it.

Other than it improves availability because file descriptor is kept
open to the mount point throughout the life-cycle of the process.
And it also improves security because as long as the file descriptor
is valid, files really come from SmackFS.

[jsakkine: updated commit message]

Signed-off-by: Rafal Krypa <r.krypa@samsung.com>
libsmack/init.c
libsmack/libsmack.c

index 4b9a283..9fb45e5 100644 (file)
 #define OLDSMACKFSMNT  "/smack"
 
 char *smackfs_mnt = NULL;
+int smackfs_mnt_dirfd = -1;
 
 static int verify_smackfs_mnt(const char *mnt)
 {
        struct statfs sfbuf;
        int rc;
+       int fd;
+
+       fd = open(mnt, O_RDONLY, 0);
+       if (fd < 0)
+               return -1;
 
        do {
-               rc = statfs(mnt, &sfbuf);
+               rc = fstatfs(fd, &sfbuf);
        } while (rc < 0 && errno == EINTR);
 
        if (rc == 0) {
@@ -53,13 +59,16 @@ static int verify_smackfs_mnt(const char *mnt)
                        struct statvfs vfsbuf;
                        rc = statvfs(mnt, &vfsbuf);
                        if (rc == 0) {
-                               if (!(vfsbuf.f_flag & ST_RDONLY))
+                               if (!(vfsbuf.f_flag & ST_RDONLY)) {
                                        smackfs_mnt = strdup(mnt);
-                               return 0;
+                                       smackfs_mnt_dirfd = fd;
+                                       return 0;
+                               }
                        }
                }
        }
 
+       close(fd);
        return -1;
 }
 
index 1d3899c..d5ba7dd 100644 (file)
@@ -32,7 +32,6 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <unistd.h>
-#include <limits.h>
 #include <sys/xattr.h>
 
 #define SELF_LABEL_FILE "/proc/self/attr/current"
@@ -63,6 +62,7 @@
 #define DICT_HASH_SIZE 4096
 
 extern char *smackfs_mnt;
+extern int smackfs_mnt_dirfd;
 
 struct label_dict {
        char **labels;
@@ -329,19 +329,16 @@ int smack_have_access(const char *subject, const char *object,
        int ret;
        int fd;
        int access2 = 1;
-       char path[PATH_MAX];
 
-       if (!smackfs_mnt)
-               return -1; 
+       if (smackfs_mnt_dirfd < 0)
+               return -1;
 
-       snprintf(path, sizeof path, "%s/access2", smackfs_mnt);
-       fd = open(path, O_RDWR);
+       fd = openat(smackfs_mnt_dirfd, "access2", O_RDWR);
        if (fd < 0) {
                if (errno != ENOENT)
                        return -1;
                
-               snprintf(path, sizeof path, "%s/access", smackfs_mnt);
-               fd = open(path, O_RDWR);
+               fd = openat(smackfs_mnt_dirfd, "access", O_RDWR);
                if (fd < 0)
                        return -1;
                access2 = 0;
@@ -412,14 +409,12 @@ int smack_cipso_apply(struct smack_cipso *cipso)
        char buf[CIPSO_MAX_SIZE];
        int fd;
        int i;
-       char path[PATH_MAX];
        int offset;
 
-       if (!smackfs_mnt)
+       if (smackfs_mnt_dirfd < 0)
                return -1;
 
-       snprintf(path, sizeof path, "%s/cipso2", smackfs_mnt);
-       fd = open(path, O_WRONLY);
+       fd = openat(smackfs_mnt_dirfd, "cipso2", O_WRONLY);
        if (fd < 0)
                return -1;
 
@@ -636,14 +631,15 @@ int smack_revoke_subject(const char *subject)
        int ret;
        int fd;
        int len;
-       char path[PATH_MAX];
+
+       if (smackfs_mnt_dirfd < 0)
+               return -1;
 
        len = get_label(NULL, subject);
        if (len < 0)
                return -1;
 
-       snprintf(path, sizeof path, "%s/revoke-subject", smackfs_mnt);
-       fd = open(path, O_WRONLY);
+       fd = openat(smackfs_mnt_dirfd, "revoke-subject", O_WRONLY);
        if (fd < 0)
                return -1;
 
@@ -664,27 +660,23 @@ static int accesses_apply(struct smack_accesses *handle, int clear)
        int load_fd;
        int change_fd;
        int load2 = 1;
-       char path[PATH_MAX];
 
-       if (!smackfs_mnt)
+       if (smackfs_mnt_dirfd < 0)
                return -1;
 
-       snprintf(path, sizeof path, "%s/load2", smackfs_mnt);
-       load_fd = open(path, O_WRONLY);
+       load_fd = openat(smackfs_mnt_dirfd, "load2", O_WRONLY);
        if (load_fd < 0) {
                if (errno != ENOENT)
                        return -1;
                /* fallback */
-               snprintf(path, sizeof path, "%s/load", smackfs_mnt);
-               load_fd = open(path, O_WRONLY);
+               load_fd = openat(smackfs_mnt_dirfd, "load", O_WRONLY);
                /* Try to continue if the file doesn't exist, we might not need it. */
                if (load_fd < 0 && errno != ENOENT)
                        return -1;
                load2 = 0;
        }
 
-       snprintf(path, sizeof path, "%s/change-rule", smackfs_mnt);
-       change_fd = open(path, O_WRONLY);
+       change_fd = openat(smackfs_mnt_dirfd, "change-rule", O_WRONLY);
        /* Try to continue if the file doesn't exist, we might not need it. */
        if (change_fd < 0 && errno != ENOENT) {
                ret = -1;