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