From: Vivek Goyal <vgoyal@redhat.com>
To: qemu-devel@nongnu.org, virtio-fs@redhat.com
Cc: vgoyal@redhat.com
Subject: [Virtio-fs] [PATCH v4 5/9] virtiofsd, fuse_lowlevel.c: Add capability to parse security context
Date: Mon, 24 Jan 2022 16:24:51 -0500 [thread overview]
Message-ID: <20220124212455.83968-6-vgoyal@redhat.com> (raw)
In-Reply-To: <20220124212455.83968-1-vgoyal@redhat.com>
Add capability to enable and parse security context as sent by client
and put into fuse_req. Filesystems now can get security context from
request and set it on files during creation.
Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
---
tools/virtiofsd/fuse_common.h | 5 ++
tools/virtiofsd/fuse_i.h | 7 +++
tools/virtiofsd/fuse_lowlevel.c | 95 ++++++++++++++++++++++++++++++++-
3 files changed, 106 insertions(+), 1 deletion(-)
diff --git a/tools/virtiofsd/fuse_common.h b/tools/virtiofsd/fuse_common.h
index 6f8a988202..bf46954dab 100644
--- a/tools/virtiofsd/fuse_common.h
+++ b/tools/virtiofsd/fuse_common.h
@@ -377,6 +377,11 @@ struct fuse_file_info {
*/
#define FUSE_CAP_SETXATTR_EXT (1 << 29)
+/**
+ * Indicates that file server supports creating file security context
+ */
+#define FUSE_CAP_SECURITY_CTX (1ULL << 32)
+
/**
* Ioctl flags
*
diff --git a/tools/virtiofsd/fuse_i.h b/tools/virtiofsd/fuse_i.h
index 492e002181..a5572fa4ae 100644
--- a/tools/virtiofsd/fuse_i.h
+++ b/tools/virtiofsd/fuse_i.h
@@ -15,6 +15,12 @@
struct fv_VuDev;
struct fv_QueueInfo;
+struct fuse_security_context {
+ const char *name;
+ uint32_t ctxlen;
+ const void *ctx;
+};
+
struct fuse_req {
struct fuse_session *se;
uint64_t unique;
@@ -35,6 +41,7 @@ struct fuse_req {
} u;
struct fuse_req *next;
struct fuse_req *prev;
+ struct fuse_security_context secctx;
};
struct fuse_notify_req {
diff --git a/tools/virtiofsd/fuse_lowlevel.c b/tools/virtiofsd/fuse_lowlevel.c
index f3f5e70be6..0bb6f7f316 100644
--- a/tools/virtiofsd/fuse_lowlevel.c
+++ b/tools/virtiofsd/fuse_lowlevel.c
@@ -886,11 +886,59 @@ static void do_readlink(fuse_req_t req, fuse_ino_t nodeid,
}
}
+static int parse_secctx_fill_req(fuse_req_t req, struct fuse_mbuf_iter *iter)
+{
+ struct fuse_secctx_header *fsecctx_header;
+ struct fuse_secctx *fsecctx;
+ const void *secctx;
+ const char *name;
+
+ fsecctx_header = fuse_mbuf_iter_advance(iter, sizeof(*fsecctx_header));
+ if (!fsecctx_header) {
+ return -EINVAL;
+ }
+
+ /*
+ * As of now maximum of one security context is supported. It can
+ * change in future though.
+ */
+ if (fsecctx_header->nr_secctx > 1) {
+ return -EINVAL;
+ }
+
+ /* No security context sent. Maybe no LSM supports it */
+ if (!fsecctx_header->nr_secctx) {
+ return 0;
+ }
+
+ fsecctx = fuse_mbuf_iter_advance(iter, sizeof(*fsecctx));
+ if (!fsecctx) {
+ return -EINVAL;
+ }
+
+ name = fuse_mbuf_iter_advance_str(iter);
+ if (!name) {
+ return -EINVAL;
+ }
+
+ secctx = fuse_mbuf_iter_advance(iter, fsecctx->size);
+ if (!secctx) {
+ return -EINVAL;
+ }
+
+ req->secctx.name = name;
+ req->secctx.ctx = secctx;
+ req->secctx.ctxlen = fsecctx->size;
+ return 0;
+}
+
static void do_mknod(fuse_req_t req, fuse_ino_t nodeid,
struct fuse_mbuf_iter *iter)
{
struct fuse_mknod_in *arg;
const char *name;
+ bool secctx_enabled = req->se->conn.want & FUSE_CAP_SECURITY_CTX;
+ int err;
arg = fuse_mbuf_iter_advance(iter, sizeof(*arg));
name = fuse_mbuf_iter_advance_str(iter);
@@ -901,6 +949,13 @@ static void do_mknod(fuse_req_t req, fuse_ino_t nodeid,
req->ctx.umask = arg->umask;
+ if (secctx_enabled) {
+ err = parse_secctx_fill_req(req, iter);
+ if (err) {
+ fuse_reply_err(req, -err);
+ }
+ }
+
if (req->se->op.mknod) {
req->se->op.mknod(req, nodeid, name, arg->mode, arg->rdev);
} else {
@@ -913,6 +968,8 @@ static void do_mkdir(fuse_req_t req, fuse_ino_t nodeid,
{
struct fuse_mkdir_in *arg;
const char *name;
+ bool secctx_enabled = req->se->conn.want & FUSE_CAP_SECURITY_CTX;
+ int err;
arg = fuse_mbuf_iter_advance(iter, sizeof(*arg));
name = fuse_mbuf_iter_advance_str(iter);
@@ -923,6 +980,13 @@ static void do_mkdir(fuse_req_t req, fuse_ino_t nodeid,
req->ctx.umask = arg->umask;
+ if (secctx_enabled) {
+ err = parse_secctx_fill_req(req, iter);
+ if (err) {
+ fuse_reply_err(req, err);
+ }
+ }
+
if (req->se->op.mkdir) {
req->se->op.mkdir(req, nodeid, name, arg->mode);
} else {
@@ -969,12 +1033,21 @@ static void do_symlink(fuse_req_t req, fuse_ino_t nodeid,
{
const char *name = fuse_mbuf_iter_advance_str(iter);
const char *linkname = fuse_mbuf_iter_advance_str(iter);
+ bool secctx_enabled = req->se->conn.want & FUSE_CAP_SECURITY_CTX;
+ int err;
if (!name || !linkname) {
fuse_reply_err(req, EINVAL);
return;
}
+ if (secctx_enabled) {
+ err = parse_secctx_fill_req(req, iter);
+ if (err) {
+ fuse_reply_err(req, err);
+ }
+ }
+
if (req->se->op.symlink) {
req->se->op.symlink(req, linkname, nodeid, name);
} else {
@@ -1048,6 +1121,8 @@ static void do_link(fuse_req_t req, fuse_ino_t nodeid,
static void do_create(fuse_req_t req, fuse_ino_t nodeid,
struct fuse_mbuf_iter *iter)
{
+ bool secctx_enabled = req->se->conn.want & FUSE_CAP_SECURITY_CTX;
+
if (req->se->op.create) {
struct fuse_create_in *arg;
struct fuse_file_info fi;
@@ -1060,6 +1135,15 @@ static void do_create(fuse_req_t req, fuse_ino_t nodeid,
return;
}
+ if (secctx_enabled) {
+ int err;
+ err = parse_secctx_fill_req(req, iter);
+ if (err) {
+ fuse_reply_err(req, err);
+ return;
+ }
+ }
+
memset(&fi, 0, sizeof(fi));
fi.flags = arg->flags;
fi.kill_priv = arg->open_flags & FUSE_OPEN_KILL_SUIDGID;
@@ -2009,6 +2093,9 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid,
if (flags & FUSE_SETXATTR_EXT) {
se->conn.capable |= FUSE_CAP_SETXATTR_EXT;
}
+ if (flags & FUSE_SECURITY_CTX) {
+ se->conn.capable |= FUSE_CAP_SECURITY_CTX;
+ }
#ifdef HAVE_SPLICE
#ifdef HAVE_VMSPLICE
se->conn.capable |= FUSE_CAP_SPLICE_WRITE | FUSE_CAP_SPLICE_MOVE;
@@ -2148,8 +2235,14 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid,
outarg.flags |= FUSE_SETXATTR_EXT;
}
+ if (se->conn.want & FUSE_CAP_SECURITY_CTX) {
+ /* bits 32..63 get shifted down 32 bits into the flags2 field */
+ outarg.flags2 |= FUSE_SECURITY_CTX >> 32;
+ }
+
fuse_log(FUSE_LOG_DEBUG, " INIT: %u.%u\n", outarg.major, outarg.minor);
- fuse_log(FUSE_LOG_DEBUG, " flags=0x%08x\n", outarg.flags);
+ fuse_log(FUSE_LOG_DEBUG, " flags2=0x%08x flags=0x%08x\n", outarg.flags2,
+ outarg.flags);
fuse_log(FUSE_LOG_DEBUG, " max_readahead=0x%08x\n", outarg.max_readahead);
fuse_log(FUSE_LOG_DEBUG, " max_write=0x%08x\n", outarg.max_write);
fuse_log(FUSE_LOG_DEBUG, " max_background=%i\n", outarg.max_background);
--
2.31.1
WARNING: multiple messages have this Message-ID (diff)
From: Vivek Goyal <vgoyal@redhat.com>
To: qemu-devel@nongnu.org, virtio-fs@redhat.com
Cc: mszeredi@redhat.com, stefanha@redhat.com, dgilbert@redhat.com,
vgoyal@redhat.com
Subject: [PATCH v4 5/9] virtiofsd, fuse_lowlevel.c: Add capability to parse security context
Date: Mon, 24 Jan 2022 16:24:51 -0500 [thread overview]
Message-ID: <20220124212455.83968-6-vgoyal@redhat.com> (raw)
In-Reply-To: <20220124212455.83968-1-vgoyal@redhat.com>
Add capability to enable and parse security context as sent by client
and put into fuse_req. Filesystems now can get security context from
request and set it on files during creation.
Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
---
tools/virtiofsd/fuse_common.h | 5 ++
tools/virtiofsd/fuse_i.h | 7 +++
tools/virtiofsd/fuse_lowlevel.c | 95 ++++++++++++++++++++++++++++++++-
3 files changed, 106 insertions(+), 1 deletion(-)
diff --git a/tools/virtiofsd/fuse_common.h b/tools/virtiofsd/fuse_common.h
index 6f8a988202..bf46954dab 100644
--- a/tools/virtiofsd/fuse_common.h
+++ b/tools/virtiofsd/fuse_common.h
@@ -377,6 +377,11 @@ struct fuse_file_info {
*/
#define FUSE_CAP_SETXATTR_EXT (1 << 29)
+/**
+ * Indicates that file server supports creating file security context
+ */
+#define FUSE_CAP_SECURITY_CTX (1ULL << 32)
+
/**
* Ioctl flags
*
diff --git a/tools/virtiofsd/fuse_i.h b/tools/virtiofsd/fuse_i.h
index 492e002181..a5572fa4ae 100644
--- a/tools/virtiofsd/fuse_i.h
+++ b/tools/virtiofsd/fuse_i.h
@@ -15,6 +15,12 @@
struct fv_VuDev;
struct fv_QueueInfo;
+struct fuse_security_context {
+ const char *name;
+ uint32_t ctxlen;
+ const void *ctx;
+};
+
struct fuse_req {
struct fuse_session *se;
uint64_t unique;
@@ -35,6 +41,7 @@ struct fuse_req {
} u;
struct fuse_req *next;
struct fuse_req *prev;
+ struct fuse_security_context secctx;
};
struct fuse_notify_req {
diff --git a/tools/virtiofsd/fuse_lowlevel.c b/tools/virtiofsd/fuse_lowlevel.c
index f3f5e70be6..0bb6f7f316 100644
--- a/tools/virtiofsd/fuse_lowlevel.c
+++ b/tools/virtiofsd/fuse_lowlevel.c
@@ -886,11 +886,59 @@ static void do_readlink(fuse_req_t req, fuse_ino_t nodeid,
}
}
+static int parse_secctx_fill_req(fuse_req_t req, struct fuse_mbuf_iter *iter)
+{
+ struct fuse_secctx_header *fsecctx_header;
+ struct fuse_secctx *fsecctx;
+ const void *secctx;
+ const char *name;
+
+ fsecctx_header = fuse_mbuf_iter_advance(iter, sizeof(*fsecctx_header));
+ if (!fsecctx_header) {
+ return -EINVAL;
+ }
+
+ /*
+ * As of now maximum of one security context is supported. It can
+ * change in future though.
+ */
+ if (fsecctx_header->nr_secctx > 1) {
+ return -EINVAL;
+ }
+
+ /* No security context sent. Maybe no LSM supports it */
+ if (!fsecctx_header->nr_secctx) {
+ return 0;
+ }
+
+ fsecctx = fuse_mbuf_iter_advance(iter, sizeof(*fsecctx));
+ if (!fsecctx) {
+ return -EINVAL;
+ }
+
+ name = fuse_mbuf_iter_advance_str(iter);
+ if (!name) {
+ return -EINVAL;
+ }
+
+ secctx = fuse_mbuf_iter_advance(iter, fsecctx->size);
+ if (!secctx) {
+ return -EINVAL;
+ }
+
+ req->secctx.name = name;
+ req->secctx.ctx = secctx;
+ req->secctx.ctxlen = fsecctx->size;
+ return 0;
+}
+
static void do_mknod(fuse_req_t req, fuse_ino_t nodeid,
struct fuse_mbuf_iter *iter)
{
struct fuse_mknod_in *arg;
const char *name;
+ bool secctx_enabled = req->se->conn.want & FUSE_CAP_SECURITY_CTX;
+ int err;
arg = fuse_mbuf_iter_advance(iter, sizeof(*arg));
name = fuse_mbuf_iter_advance_str(iter);
@@ -901,6 +949,13 @@ static void do_mknod(fuse_req_t req, fuse_ino_t nodeid,
req->ctx.umask = arg->umask;
+ if (secctx_enabled) {
+ err = parse_secctx_fill_req(req, iter);
+ if (err) {
+ fuse_reply_err(req, -err);
+ }
+ }
+
if (req->se->op.mknod) {
req->se->op.mknod(req, nodeid, name, arg->mode, arg->rdev);
} else {
@@ -913,6 +968,8 @@ static void do_mkdir(fuse_req_t req, fuse_ino_t nodeid,
{
struct fuse_mkdir_in *arg;
const char *name;
+ bool secctx_enabled = req->se->conn.want & FUSE_CAP_SECURITY_CTX;
+ int err;
arg = fuse_mbuf_iter_advance(iter, sizeof(*arg));
name = fuse_mbuf_iter_advance_str(iter);
@@ -923,6 +980,13 @@ static void do_mkdir(fuse_req_t req, fuse_ino_t nodeid,
req->ctx.umask = arg->umask;
+ if (secctx_enabled) {
+ err = parse_secctx_fill_req(req, iter);
+ if (err) {
+ fuse_reply_err(req, err);
+ }
+ }
+
if (req->se->op.mkdir) {
req->se->op.mkdir(req, nodeid, name, arg->mode);
} else {
@@ -969,12 +1033,21 @@ static void do_symlink(fuse_req_t req, fuse_ino_t nodeid,
{
const char *name = fuse_mbuf_iter_advance_str(iter);
const char *linkname = fuse_mbuf_iter_advance_str(iter);
+ bool secctx_enabled = req->se->conn.want & FUSE_CAP_SECURITY_CTX;
+ int err;
if (!name || !linkname) {
fuse_reply_err(req, EINVAL);
return;
}
+ if (secctx_enabled) {
+ err = parse_secctx_fill_req(req, iter);
+ if (err) {
+ fuse_reply_err(req, err);
+ }
+ }
+
if (req->se->op.symlink) {
req->se->op.symlink(req, linkname, nodeid, name);
} else {
@@ -1048,6 +1121,8 @@ static void do_link(fuse_req_t req, fuse_ino_t nodeid,
static void do_create(fuse_req_t req, fuse_ino_t nodeid,
struct fuse_mbuf_iter *iter)
{
+ bool secctx_enabled = req->se->conn.want & FUSE_CAP_SECURITY_CTX;
+
if (req->se->op.create) {
struct fuse_create_in *arg;
struct fuse_file_info fi;
@@ -1060,6 +1135,15 @@ static void do_create(fuse_req_t req, fuse_ino_t nodeid,
return;
}
+ if (secctx_enabled) {
+ int err;
+ err = parse_secctx_fill_req(req, iter);
+ if (err) {
+ fuse_reply_err(req, err);
+ return;
+ }
+ }
+
memset(&fi, 0, sizeof(fi));
fi.flags = arg->flags;
fi.kill_priv = arg->open_flags & FUSE_OPEN_KILL_SUIDGID;
@@ -2009,6 +2093,9 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid,
if (flags & FUSE_SETXATTR_EXT) {
se->conn.capable |= FUSE_CAP_SETXATTR_EXT;
}
+ if (flags & FUSE_SECURITY_CTX) {
+ se->conn.capable |= FUSE_CAP_SECURITY_CTX;
+ }
#ifdef HAVE_SPLICE
#ifdef HAVE_VMSPLICE
se->conn.capable |= FUSE_CAP_SPLICE_WRITE | FUSE_CAP_SPLICE_MOVE;
@@ -2148,8 +2235,14 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid,
outarg.flags |= FUSE_SETXATTR_EXT;
}
+ if (se->conn.want & FUSE_CAP_SECURITY_CTX) {
+ /* bits 32..63 get shifted down 32 bits into the flags2 field */
+ outarg.flags2 |= FUSE_SECURITY_CTX >> 32;
+ }
+
fuse_log(FUSE_LOG_DEBUG, " INIT: %u.%u\n", outarg.major, outarg.minor);
- fuse_log(FUSE_LOG_DEBUG, " flags=0x%08x\n", outarg.flags);
+ fuse_log(FUSE_LOG_DEBUG, " flags2=0x%08x flags=0x%08x\n", outarg.flags2,
+ outarg.flags);
fuse_log(FUSE_LOG_DEBUG, " max_readahead=0x%08x\n", outarg.max_readahead);
fuse_log(FUSE_LOG_DEBUG, " max_write=0x%08x\n", outarg.max_write);
fuse_log(FUSE_LOG_DEBUG, " max_background=%i\n", outarg.max_background);
--
2.31.1
next prev parent reply other threads:[~2022-01-24 21:24 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-01-24 21:24 [Virtio-fs] [PATCH v4 0/9] virtiofsd: Add support for file security context at creation Vivek Goyal
2022-01-24 21:24 ` Vivek Goyal
2022-01-24 21:24 ` [Virtio-fs] [PATCH v4 1/9] linux-headers: Update headers to v5.17-rc1 Vivek Goyal
2022-01-24 21:24 ` Vivek Goyal
2022-01-27 17:21 ` [Virtio-fs] " Dr. David Alan Gilbert
2022-01-27 17:21 ` Dr. David Alan Gilbert
2022-01-27 18:06 ` [Virtio-fs] " Vivek Goyal
2022-01-27 18:06 ` Vivek Goyal
2022-01-27 19:42 ` [Virtio-fs] " Dr. David Alan Gilbert
2022-01-27 19:42 ` Dr. David Alan Gilbert
2022-01-24 21:24 ` [Virtio-fs] [PATCH v4 2/9] virtiofsd: Fix breakage due to fuse_init_in size change Vivek Goyal
2022-01-24 21:24 ` Vivek Goyal
2022-01-27 17:17 ` [Virtio-fs] " Dr. David Alan Gilbert
2022-01-27 17:17 ` Dr. David Alan Gilbert
2022-01-24 21:24 ` [Virtio-fs] [PATCH v4 3/9] virtiofsd: Parse extended "struct fuse_init_in" Vivek Goyal
2022-01-24 21:24 ` Vivek Goyal
2022-01-27 17:50 ` [Virtio-fs] " Dr. David Alan Gilbert
2022-01-27 17:50 ` Dr. David Alan Gilbert
2022-01-27 18:21 ` [Virtio-fs] " Vivek Goyal
2022-01-27 18:21 ` Vivek Goyal
2022-01-24 21:24 ` [Virtio-fs] [PATCH v4 4/9] virtiofsd: Extend size of fuse_conn_info->capable and ->want fields Vivek Goyal
2022-01-24 21:24 ` Vivek Goyal
2022-01-27 17:53 ` [Virtio-fs] " Dr. David Alan Gilbert
2022-01-27 17:53 ` Dr. David Alan Gilbert
2022-01-27 18:31 ` [Virtio-fs] " Vivek Goyal
2022-01-27 18:31 ` Vivek Goyal
2022-01-24 21:24 ` Vivek Goyal [this message]
2022-01-24 21:24 ` [PATCH v4 5/9] virtiofsd, fuse_lowlevel.c: Add capability to parse security context Vivek Goyal
2022-01-24 21:24 ` [Virtio-fs] [PATCH v4 6/9] virtiofsd: Move core file creation code in separate function Vivek Goyal
2022-01-24 21:24 ` Vivek Goyal
2022-01-27 19:50 ` [Virtio-fs] " Dr. David Alan Gilbert
2022-01-27 19:50 ` Dr. David Alan Gilbert
2022-01-24 21:24 ` [Virtio-fs] [PATCH v4 7/9] virtiofsd: Create new file with fscreate set Vivek Goyal
2022-01-24 21:24 ` Vivek Goyal
2022-01-24 21:24 ` [Virtio-fs] [PATCH v4 8/9] virtiofsd: Create new file using O_TMPFILE and set security context Vivek Goyal
2022-01-24 21:24 ` Vivek Goyal
2022-01-24 21:24 ` [Virtio-fs] [PATCH v4 9/9] virtiofsd: Add an option to enable/disable security label Vivek Goyal
2022-01-24 21:24 ` Vivek Goyal
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220124212455.83968-6-vgoyal@redhat.com \
--to=vgoyal@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=virtio-fs@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.