[lxc-devel] [lxcfs/master] implement access(2)
hallyn on Github
lxc-bot at linuxcontainers.org
Tue Mar 22 00:51:00 UTC 2016
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 355 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20160322/a5fbf9ca/attachment.bin>
-------------- next part --------------
From f0e1f78fa64e4b6eceafbcc243721e9e8d3be492 Mon Sep 17 00:00:00 2001
From: Serge Hallyn <serge.hallyn at ubuntu.com>
Date: Mon, 21 Mar 2016 17:42:04 -0700
Subject: [PATCH] implement access(2)
Signed-off-by: Serge Hallyn <serge.hallyn at 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,
More information about the lxc-devel
mailing list