Virtiofsd pull 2021-10-26

New 'unsupported' feature for xattr mapping
   Good for hiding selinux
 
 Plus some tidy ups and error handling.
 Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEERfXHG0oMt/uXep+pBRYzHrxb/ecFAmF32FwACgkQBRYzHrxb
 /ecd7g/+JiFBnOhP6a8Vh2L5P4juGRVDHibKmT7FlQIBga47Cn6EtUTRBlI12aKl
 LVOrEkicpEeg1f/xMJRICO/XSDfH6NTz1VPJtofpIdK9+vLr6Ny5An2VtO4zgPxq
 1dswxGlr2qt1rxyXtiuC9FI+7zKpz8ynvDFPGVWmfnJBY8UIPb7fAxoL/+yM5x0M
 1xI33xCzpzXvQMXRiB8fmH9F+kmF/HInz4hcZktuL/36bqFGeCkj15vdtfTuH+h9
 qecSUmgBIPK+nYchjvbt0EeTO4jABc48Pmd7f7HHk7HkJc5r5iaMMXA+JTTcT37L
 AE4EAdS9DhUr8XMMYf+1NC3UE0YrYg4PRWScdS5bmF9xwxaMklNDZUpmLylVJQ5F
 QCoLUZQBEPaYnwAqrB5djQsxYDaKSk46ezeqeo8lbmyMU6hNe6l51V5k1e1YhDI/
 0j4maCk36Ma7aWGJGOKxZE1tT2mqkLtAe/cWb8tqwy0L7MJ8kJ8JgQYqc12HlRuL
 6wtakDjLjxMLEQ3dqqgu+SjqxdMvhL/siqyYJTsrohSYlQmWmZwXkcL54fNDy6+k
 NDLtb502R7piM3VdM7yqQEL+5Z4w6u5Rgeklo8xb6hWiS0gEdgsyC069SHLKRE4+
 jxp9izFOzUqFDpxv7aWT7CkzwFkJgIE9Grn00GBwVeYWT5oenhA=
 =HDue
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/dagrh/tags/pull-virtiofs-20211026' into staging

Virtiofsd pull 2021-10-26

New 'unsupported' feature for xattr mapping
  Good for hiding selinux

Plus some tidy ups and error handling.
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>

# gpg: Signature made Tue 26 Oct 2021 03:28:44 AM PDT
# gpg:                using RSA key 45F5C71B4A0CB7FB977A9FA90516331EBC5BFDE7
# gpg: Good signature from "Dr. David Alan Gilbert (RH2) <dgilbert@redhat.com>" [full]

* remotes/dagrh/tags/pull-virtiofs-20211026:
  virtiofsd: Error on bad socket group name
  virtiofsd: Add a helper to stop all queues
  virtiofsd: Add a helper to send element on virtqueue
  virtiofsd: Remove unused virtio_fs_config definition
  virtiofsd: xattr mapping add a new type "unsupported"

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
master
Richard Henderson 2021-10-26 07:38:41 -07:00
commit 931ce30859
3 changed files with 58 additions and 45 deletions

View File

@ -183,6 +183,12 @@ Using ':' as the separator a rule is of the form:
'ok' as either an explicit terminator or for special handling of certain
patterns.
- 'unsupported' - If a client tries to use a name matching 'key' it's
denied using ENOTSUP; when the server passes an attribute
name matching 'prepend' it's hidden. In many ways it's use is very like
'ok' as either an explicit terminator or for special handling of certain
patterns.
**key** is a string tested as a prefix on an attribute name originating
on the client. It maybe empty in which case a 'client' rule
will always match on client names.

View File

@ -82,12 +82,6 @@ struct fv_VuDev {
struct fv_QueueInfo **qi;
};
/* From spec */
struct virtio_fs_config {
char tag[36];
uint32_t num_queues;
};
/* Callback from libvhost-user */
static uint64_t fv_get_features(VuDev *dev)
{
@ -249,6 +243,21 @@ static void vu_dispatch_unlock(struct fv_VuDev *vud)
assert(ret == 0);
}
static void vq_send_element(struct fv_QueueInfo *qi, VuVirtqElement *elem,
ssize_t len)
{
struct fuse_session *se = qi->virtio_dev->se;
VuDev *dev = &se->virtio_dev->dev;
VuVirtq *q = vu_get_queue(dev, qi->qidx);
vu_dispatch_rdlock(qi->virtio_dev);
pthread_mutex_lock(&qi->vq_lock);
vu_queue_push(dev, q, elem, len);
vu_queue_notify(dev, q);
pthread_mutex_unlock(&qi->vq_lock);
vu_dispatch_unlock(qi->virtio_dev);
}
/*
* Called back by ll whenever it wants to send a reply/message back
* The 1st element of the iov starts with the fuse_out_header
@ -259,8 +268,6 @@ int virtio_send_msg(struct fuse_session *se, struct fuse_chan *ch,
{
FVRequest *req = container_of(ch, FVRequest, ch);
struct fv_QueueInfo *qi = ch->qi;
VuDev *dev = &se->virtio_dev->dev;
VuVirtq *q = vu_get_queue(dev, qi->qidx);
VuVirtqElement *elem = &req->elem;
int ret = 0;
@ -302,13 +309,7 @@ int virtio_send_msg(struct fuse_session *se, struct fuse_chan *ch,
copy_iov(iov, count, in_sg, in_num, tosend_len);
vu_dispatch_rdlock(qi->virtio_dev);
pthread_mutex_lock(&qi->vq_lock);
vu_queue_push(dev, q, elem, tosend_len);
vu_queue_notify(dev, q);
pthread_mutex_unlock(&qi->vq_lock);
vu_dispatch_unlock(qi->virtio_dev);
vq_send_element(qi, elem, tosend_len);
req->reply_sent = true;
err:
@ -327,8 +328,6 @@ int virtio_send_data_iov(struct fuse_session *se, struct fuse_chan *ch,
{
FVRequest *req = container_of(ch, FVRequest, ch);
struct fv_QueueInfo *qi = ch->qi;
VuDev *dev = &se->virtio_dev->dev;
VuVirtq *q = vu_get_queue(dev, qi->qidx);
VuVirtqElement *elem = &req->elem;
int ret = 0;
g_autofree struct iovec *in_sg_cpy = NULL;
@ -436,12 +435,7 @@ int virtio_send_data_iov(struct fuse_session *se, struct fuse_chan *ch,
out_sg->len = tosend_len;
}
vu_dispatch_rdlock(qi->virtio_dev);
pthread_mutex_lock(&qi->vq_lock);
vu_queue_push(dev, q, elem, tosend_len);
vu_queue_notify(dev, q);
pthread_mutex_unlock(&qi->vq_lock);
vu_dispatch_unlock(qi->virtio_dev);
vq_send_element(qi, elem, tosend_len);
req->reply_sent = true;
return 0;
}
@ -453,7 +447,6 @@ static void fv_queue_worker(gpointer data, gpointer user_data)
{
struct fv_QueueInfo *qi = user_data;
struct fuse_session *se = qi->virtio_dev->se;
struct VuDev *dev = &qi->virtio_dev->dev;
FVRequest *req = data;
VuVirtqElement *elem = &req->elem;
struct fuse_buf fbuf = {};
@ -595,17 +588,9 @@ out:
/* If the request has no reply, still recycle the virtqueue element */
if (!req->reply_sent) {
struct VuVirtq *q = vu_get_queue(dev, qi->qidx);
fuse_log(FUSE_LOG_DEBUG, "%s: elem %d no reply sent\n", __func__,
elem->index);
vu_dispatch_rdlock(qi->virtio_dev);
pthread_mutex_lock(&qi->vq_lock);
vu_queue_push(dev, q, elem, 0);
vu_queue_notify(dev, q);
pthread_mutex_unlock(&qi->vq_lock);
vu_dispatch_unlock(qi->virtio_dev);
vq_send_element(qi, elem, 0);
}
pthread_mutex_destroy(&req->ch.lock);
@ -755,6 +740,18 @@ static void fv_queue_cleanup_thread(struct fv_VuDev *vud, int qidx)
vud->qi[qidx] = NULL;
}
static void stop_all_queues(struct fv_VuDev *vud)
{
for (int i = 0; i < vud->nqueues; i++) {
if (!vud->qi[i]) {
continue;
}
fuse_log(FUSE_LOG_INFO, "%s: Stopping queue %d thread\n", __func__, i);
fv_queue_cleanup_thread(vud, i);
}
}
/* Callback from libvhost-user on start or stop of a queue */
static void fv_queue_set_started(VuDev *dev, int qidx, bool started)
{
@ -885,15 +882,7 @@ int virtio_loop(struct fuse_session *se)
* Make sure all fv_queue_thread()s quit on exit, as we're about to
* free virtio dev and fuse session, no one should access them anymore.
*/
for (int i = 0; i < se->virtio_dev->nqueues; i++) {
if (!se->virtio_dev->qi[i]) {
continue;
}
fuse_log(FUSE_LOG_INFO, "%s: Stopping queue %d thread\n", __func__, i);
fv_queue_cleanup_thread(se->virtio_dev, i);
}
stop_all_queues(se->virtio_dev);
fuse_log(FUSE_LOG_INFO, "%s: Exit\n", __func__);
return 0;
@ -999,6 +988,13 @@ static int fv_create_listen_socket(struct fuse_session *se)
"vhost socket failed to set group to %s (%d): %m\n",
se->vu_socket_group, g->gr_gid);
}
} else {
fuse_log(FUSE_LOG_ERR,
"vhost socket: unable to find group '%s'\n",
se->vu_socket_group);
close(listen_sock);
umask(old_umask);
return -1;
}
}
umask(old_umask);

View File

@ -2465,6 +2465,11 @@ static void lo_flock(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi,
* Automatically reversed on read
*/
#define XATTR_MAP_FLAG_PREFIX (1 << 2)
/*
* The attribute is unsupported;
* ENOTSUP on write, hidden on read.
*/
#define XATTR_MAP_FLAG_UNSUPPORTED (1 << 3)
/* scopes */
/* Apply rule to get/set/remove */
@ -2636,6 +2641,8 @@ static void parse_xattrmap(struct lo_data *lo)
tmp_entry.flags |= XATTR_MAP_FLAG_OK;
} else if (strstart(map, "bad", &map)) {
tmp_entry.flags |= XATTR_MAP_FLAG_BAD;
} else if (strstart(map, "unsupported", &map)) {
tmp_entry.flags |= XATTR_MAP_FLAG_UNSUPPORTED;
} else if (strstart(map, "map", &map)) {
/*
* map is sugar that adds a number of rules, and must be
@ -2646,8 +2653,8 @@ static void parse_xattrmap(struct lo_data *lo)
} else {
fuse_log(FUSE_LOG_ERR,
"%s: Unexpected type;"
"Expecting 'prefix', 'ok', 'bad' or 'map' in rule %zu\n",
__func__, lo->xattr_map_nentries);
"Expecting 'prefix', 'ok', 'bad', 'unsupported' or 'map'"
" in rule %zu\n", __func__, lo->xattr_map_nentries);
exit(1);
}
@ -2749,6 +2756,9 @@ static int xattr_map_client(const struct lo_data *lo, const char *client_name,
if (cur_entry->flags & XATTR_MAP_FLAG_BAD) {
return -EPERM;
}
if (cur_entry->flags & XATTR_MAP_FLAG_UNSUPPORTED) {
return -ENOTSUP;
}
if (cur_entry->flags & XATTR_MAP_FLAG_OK) {
/* Unmodified name */
return 0;
@ -2788,7 +2798,8 @@ static int xattr_map_server(const struct lo_data *lo, const char *server_name,
if ((cur_entry->flags & XATTR_MAP_FLAG_SERVER) &&
(strstart(server_name, cur_entry->prepend, &end))) {
if (cur_entry->flags & XATTR_MAP_FLAG_BAD) {
if (cur_entry->flags & XATTR_MAP_FLAG_BAD ||
cur_entry->flags & XATTR_MAP_FLAG_UNSUPPORTED) {
return -ENODATA;
}
if (cur_entry->flags & XATTR_MAP_FLAG_OK) {