The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxcfs/pull/102

This e-mail was sent by the LXC bot, direct replies will not reach the author
unless they happen to be subscribed to this list.

=== Description (from pull-request) ===
Signed-off-by: Serge Hallyn <serge.hal...@ubuntu.com>
From f0e1f78fa64e4b6eceafbcc243721e9e8d3be492 Mon Sep 17 00:00:00 2001
From: Serge Hallyn <serge.hal...@ubuntu.com>
Date: Mon, 21 Mar 2016 17:42:04 -0700
Subject: [PATCH] implement access(2)

Signed-off-by: Serge Hallyn <serge.hal...@ubuntu.com>
---
 bindings.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 bindings.h |  2 ++
 lxcfs.c    | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 114 insertions(+), 1 deletion(-)

diff --git a/bindings.c b/bindings.c
index a16722c..44cc316 100644
--- a/bindings.c
+++ b/bindings.c
@@ -1770,6 +1770,60 @@ int cg_open(const char *path, struct fuse_file_info *fi)
        return ret;
 }
 
+int cg_access(const char *path, int mode)
+{
+       const char *cgroup;
+       char *last = NULL, *path1, *path2, * cgdir = NULL, *controller;
+       struct cgfs_files *k = NULL;
+       struct fuse_context *fc = fuse_get_context();
+       int ret;
+
+       if (!fc)
+               return -EIO;
+
+       controller = pick_controller_from_path(fc, path);
+       if (!controller)
+               return -EIO;
+       cgroup = find_cgroup_in_path(path);
+       if (!cgroup)
+               return -EINVAL;
+
+       get_cgdir_and_path(cgroup, &cgdir, &last);
+       if (!last) {
+               path1 = "/";
+               path2 = cgdir;
+       } else {
+               path1 = cgdir;
+               path2 = last;
+       }
+
+       k = cgfs_get_key(controller, path1, path2);
+       if (!k) {
+               ret = -EINVAL;
+               goto out;
+       }
+       free_key(k);
+
+       pid_t initpid = lookup_initpid_in_store(fc->pid);
+       if (initpid <= 0)
+               initpid = fc->pid;
+       if (!caller_may_see_dir(initpid, controller, path1)) {
+               ret = -ENOENT;
+               goto out;
+       }
+       if (!fc_may_access(fc, controller, path1, path2, mode)) {
+               // should never get here
+               ret = -EACCES;
+               goto out;
+       }
+
+       ret = 0;
+
+out:
+       free(cgdir);
+       return ret;
+}
+
 int cg_release(const char *path, struct fuse_file_info *fi)
 {
        struct file_info *f = (struct file_info *)fi->fh;
@@ -3759,6 +3813,14 @@ int proc_open(const char *path, struct fuse_file_info 
*fi)
        return 0;
 }
 
+int proc_access(const char *path, int mask)
+{
+       /* these are all read-only */
+       if ((mask & ~R_OK) != 0)
+               return -EPERM;
+       return 0;
+}
+
 int proc_release(const char *path, struct fuse_file_info *fi)
 {
        struct file_info *f = (struct file_info *)fi->fh;
diff --git a/bindings.h b/bindings.h
index 9164659..3d3bf41 100644
--- a/bindings.h
+++ b/bindings.h
@@ -16,6 +16,7 @@ extern int cg_read(const char *path, char *buf, size_t size, 
off_t offset,
 extern int cg_opendir(const char *path, struct fuse_file_info *fi);
 extern int cg_getattr(const char *path, struct stat *sb);
 extern int cg_open(const char *path, struct fuse_file_info *fi);
+extern int cg_access(const char *path, int mode);
 
 extern int proc_getattr(const char *path, struct stat *sb);
 extern int proc_readdir(const char *path, void *buf, fuse_fill_dir_t filler, 
off_t offset,
@@ -24,3 +25,4 @@ extern int proc_release(const char *path, struct 
fuse_file_info *fi);
 extern int proc_open(const char *path, struct fuse_file_info *fi);
 extern int proc_read(const char *path, char *buf, size_t size, off_t offset,
                struct fuse_file_info *fi);
+extern int proc_access(const char *path, int mask);
diff --git a/lxcfs.c b/lxcfs.c
index c53906c..6f37052 100644
--- a/lxcfs.c
+++ b/lxcfs.c
@@ -309,6 +309,21 @@ static int do_cg_open(const char *path, struct 
fuse_file_info *fi)
        return cg_open(path, fi);
 }
 
+static int do_cg_access(const char *path, int mode)
+{
+       int (*cg_access)(const char *path, int mode);
+       char *error;
+       dlerror();    /* Clear any existing error */
+       cg_access = (int (*)(const char *, int mode)) dlsym(dlopen_handle, 
"cg_access");
+       error = dlerror();
+       if (error != NULL) {
+               fprintf(stderr, "cg_access: %s\n", error);
+               return -1;
+       }
+
+       return cg_access(path, mode);
+}
+
 static int do_proc_open(const char *path, struct fuse_file_info *fi)
 {
        int (*proc_open)(const char *path, struct fuse_file_info *fi);
@@ -324,6 +339,21 @@ static int do_proc_open(const char *path, struct 
fuse_file_info *fi)
        return proc_open(path, fi);
 }
 
+static int do_proc_access(const char *path, int mode)
+{
+       int (*proc_access)(const char *path, int mode);
+       char *error;
+       dlerror();    /* Clear any existing error */
+       proc_access = (int (*)(const char *, int mode)) dlsym(dlopen_handle, 
"proc_access");
+       error = dlerror();
+       if (error != NULL) {
+               fprintf(stderr, "proc_access: %s\n", error);
+               return -1;
+       }
+
+       return proc_access(path, mode);
+}
+
 static int do_cg_release(const char *path, struct fuse_file_info *fi)
 {
        int (*cg_release)(const char *path, struct fuse_file_info *fi);
@@ -455,6 +485,25 @@ static int lxcfs_readdir(const char *path, void *buf, 
fuse_fill_dir_t filler, of
        return -EINVAL;
 }
 
+static int lxcfs_access(const char *path, int mode)
+{
+       int ret;
+       if (strncmp(path, "/cgroup", 7) == 0) {
+               up_users();
+               ret = do_cg_access(path, mode);
+               down_users();
+               return ret;
+       }
+       if (strncmp(path, "/proc", 5) == 0) {
+               up_users();
+               ret = do_proc_access(path, mode);
+               down_users();
+               return ret;
+       }
+
+       return -EINVAL;
+}
+
 static int lxcfs_releasedir(const char *path, struct fuse_file_info *fi)
 {
        int ret;
@@ -652,7 +701,7 @@ const struct fuse_operations lxcfs_ops = {
        .fsyncdir = NULL,
        .init = NULL,
        .destroy = NULL,
-       .access = NULL,
+       .access = lxcfs_access,
        .create = NULL,
        .ftruncate = NULL,
        .fgetattr = NULL,
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to