aboutsummaryrefslogtreecommitdiff
path: root/fsdev
diff options
context:
space:
mode:
authorFathi Boudra <fathi.boudra@linaro.org>2013-03-30 21:18:24 +0200
committerFathi Boudra <fathi.boudra@linaro.org>2013-03-30 21:18:24 +0200
commit050a840ead5e51a1a9f3bffe89cc89077b2f35ed (patch)
tree36d8e48e23b64a07a914b3b34d568c747915b560 /fsdev
parent17d4e9b1e2d6d32da51278a4165621af99bade02 (diff)
Imported Upstream version 1.4.0-2013.03upstream/1.4.0-2013.03
Diffstat (limited to 'fsdev')
-rw-r--r--fsdev/Makefile.objs9
-rw-r--r--fsdev/qemu-fsdev-dummy.c11
-rw-r--r--fsdev/qemu-fsdev-opts.c85
-rw-r--r--fsdev/qemu-fsdev.c14
-rw-r--r--fsdev/qemu-fsdev.h2
-rw-r--r--fsdev/virtfs-proxy-helper.c101
-rw-r--r--fsdev/virtio-9p-marshal.c4
7 files changed, 166 insertions, 60 deletions
diff --git a/fsdev/Makefile.objs b/fsdev/Makefile.objs
index cb1e250..206289c 100644
--- a/fsdev/Makefile.objs
+++ b/fsdev/Makefile.objs
@@ -1,9 +1,10 @@
ifeq ($(CONFIG_REALLY_VIRTFS),y)
common-obj-y = qemu-fsdev.o virtio-9p-marshal.o
-
-# Toplevel always builds this; targets without virtio will put it in
-# common-obj-y
-extra-obj-y = qemu-fsdev-dummy.o
else
common-obj-y = qemu-fsdev-dummy.o
endif
+common-obj-y += qemu-fsdev-opts.o
+
+# Toplevel always builds this; targets without virtio will put it in
+# common-obj-y
+common-obj-$(CONFIG_ALL) += qemu-fsdev-dummy.o
diff --git a/fsdev/qemu-fsdev-dummy.c b/fsdev/qemu-fsdev-dummy.c
index 300f275..7dc2630 100644
--- a/fsdev/qemu-fsdev-dummy.c
+++ b/fsdev/qemu-fsdev-dummy.c
@@ -13,17 +13,10 @@
#include <stdio.h>
#include <string.h>
#include "qemu-fsdev.h"
-#include "qemu-config.h"
-#include "module.h"
+#include "qemu/config-file.h"
+#include "qemu/module.h"
int qemu_fsdev_add(QemuOpts *opts)
{
return 0;
}
-
-static void fsdev_register_config(void)
-{
- qemu_add_opts(&qemu_fsdev_opts);
- qemu_add_opts(&qemu_virtfs_opts);
-}
-machine_init(fsdev_register_config);
diff --git a/fsdev/qemu-fsdev-opts.c b/fsdev/qemu-fsdev-opts.c
new file mode 100644
index 0000000..6311c7a
--- /dev/null
+++ b/fsdev/qemu-fsdev-opts.c
@@ -0,0 +1,85 @@
+/*
+ * Virtio 9p
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * later. See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/config-file.h"
+#include "qemu/option.h"
+#include "qemu/module.h"
+
+static QemuOptsList qemu_fsdev_opts = {
+ .name = "fsdev",
+ .implied_opt_name = "fsdriver",
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_fsdev_opts.head),
+ .desc = {
+ {
+ .name = "fsdriver",
+ .type = QEMU_OPT_STRING,
+ }, {
+ .name = "path",
+ .type = QEMU_OPT_STRING,
+ }, {
+ .name = "security_model",
+ .type = QEMU_OPT_STRING,
+ }, {
+ .name = "writeout",
+ .type = QEMU_OPT_STRING,
+ }, {
+ .name = "readonly",
+ .type = QEMU_OPT_BOOL,
+
+ }, {
+ .name = "socket",
+ .type = QEMU_OPT_STRING,
+ }, {
+ .name = "sock_fd",
+ .type = QEMU_OPT_NUMBER,
+ },
+
+ { /*End of list */ }
+ },
+};
+
+static QemuOptsList qemu_virtfs_opts = {
+ .name = "virtfs",
+ .implied_opt_name = "fsdriver",
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_virtfs_opts.head),
+ .desc = {
+ {
+ .name = "fsdriver",
+ .type = QEMU_OPT_STRING,
+ }, {
+ .name = "path",
+ .type = QEMU_OPT_STRING,
+ }, {
+ .name = "mount_tag",
+ .type = QEMU_OPT_STRING,
+ }, {
+ .name = "security_model",
+ .type = QEMU_OPT_STRING,
+ }, {
+ .name = "writeout",
+ .type = QEMU_OPT_STRING,
+ }, {
+ .name = "readonly",
+ .type = QEMU_OPT_BOOL,
+ }, {
+ .name = "socket",
+ .type = QEMU_OPT_STRING,
+ }, {
+ .name = "sock_fd",
+ .type = QEMU_OPT_NUMBER,
+ },
+
+ { /*End of list */ }
+ },
+};
+
+static void fsdev_register_config(void)
+{
+ qemu_add_opts(&qemu_fsdev_opts);
+ qemu_add_opts(&qemu_virtfs_opts);
+}
+machine_init(fsdev_register_config);
diff --git a/fsdev/qemu-fsdev.c b/fsdev/qemu-fsdev.c
index e20202a..6eaf36d 100644
--- a/fsdev/qemu-fsdev.c
+++ b/fsdev/qemu-fsdev.c
@@ -13,10 +13,10 @@
#include <stdio.h>
#include <string.h>
#include "qemu-fsdev.h"
-#include "qemu-queue.h"
-#include "osdep.h"
+#include "qemu/queue.h"
+#include "qemu/osdep.h"
#include "qemu-common.h"
-#include "qemu-config.h"
+#include "qemu/config-file.h"
static QTAILQ_HEAD(FsDriverEntry_head, FsDriverListEntry) fsdriver_entries =
QTAILQ_HEAD_INITIALIZER(fsdriver_entries);
@@ -97,11 +97,3 @@ FsDriverEntry *get_fsdev_fsentry(char *id)
}
return NULL;
}
-
-static void fsdev_register_config(void)
-{
- qemu_add_opts(&qemu_fsdev_opts);
- qemu_add_opts(&qemu_virtfs_opts);
-}
-machine_init(fsdev_register_config);
-
diff --git a/fsdev/qemu-fsdev.h b/fsdev/qemu-fsdev.h
index 1af1f54..9fa45bf 100644
--- a/fsdev/qemu-fsdev.h
+++ b/fsdev/qemu-fsdev.h
@@ -12,7 +12,7 @@
*/
#ifndef QEMU_FSDEV_H
#define QEMU_FSDEV_H
-#include "qemu-option.h"
+#include "qemu/option.h"
#include "file-op-9p.h"
diff --git a/fsdev/virtfs-proxy-helper.c b/fsdev/virtfs-proxy-helper.c
index f9a8270..36f6616 100644
--- a/fsdev/virtfs-proxy-helper.c
+++ b/fsdev/virtfs-proxy-helper.c
@@ -21,8 +21,8 @@
#include <linux/magic.h>
#endif
#include "qemu-common.h"
-#include "qemu_socket.h"
-#include "qemu-xattr.h"
+#include "qemu/sockets.h"
+#include "qemu/xattr.h"
#include "virtio-9p-marshal.h"
#include "hw/9pfs/virtio-9p-proxy.h"
#include "fsdev/virtio-9p-marshal.h"
@@ -272,31 +272,76 @@ static int send_status(int sockfd, struct iovec *iovec, int status)
/*
* from man 7 capabilities, section
* Effect of User ID Changes on Capabilities:
- * 4. If the file system user ID is changed from 0 to nonzero (see setfsuid(2))
- * then the following capabilities are cleared from the effective set:
- * CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_DAC_READ_SEARCH, CAP_FOWNER, CAP_FSETID,
- * CAP_LINUX_IMMUTABLE (since Linux 2.2.30), CAP_MAC_OVERRIDE, and CAP_MKNOD
- * (since Linux 2.2.30). If the file system UID is changed from nonzero to 0,
- * then any of these capabilities that are enabled in the permitted set
- * are enabled in the effective set.
+ * If the effective user ID is changed from nonzero to 0, then the permitted
+ * set is copied to the effective set. If the effective user ID is changed
+ * from 0 to nonzero, then all capabilities are are cleared from the effective
+ * set.
+ *
+ * The setfsuid/setfsgid man pages warn that changing the effective user ID may
+ * expose the program to unwanted signals, but this is not true anymore: for an
+ * unprivileged (without CAP_KILL) program to send a signal, the real or
+ * effective user ID of the sending process must equal the real or saved user
+ * ID of the target process. Even when dropping privileges, it is enough to
+ * keep the saved UID to a "privileged" value and virtfs-proxy-helper won't
+ * be exposed to signals. So just use setresuid/setresgid.
*/
-static int setfsugid(int uid, int gid)
+static int setugid(int uid, int gid, int *suid, int *sgid)
{
+ int retval;
+
/*
- * We still need DAC_OVERRIDE because we don't change
+ * We still need DAC_OVERRIDE because we don't change
* supplementary group ids, and hence may be subjected DAC rules
*/
cap_value_t cap_list[] = {
CAP_DAC_OVERRIDE,
};
- setfsgid(gid);
- setfsuid(uid);
+ *suid = geteuid();
+ *sgid = getegid();
+
+ if (setresgid(-1, gid, *sgid) == -1) {
+ retval = -errno;
+ goto err_out;
+ }
+
+ if (setresuid(-1, uid, *suid) == -1) {
+ retval = -errno;
+ goto err_sgid;
+ }
if (uid != 0 || gid != 0) {
- return do_cap_set(cap_list, ARRAY_SIZE(cap_list), 0);
+ if (do_cap_set(cap_list, ARRAY_SIZE(cap_list), 0) < 0) {
+ retval = -errno;
+ goto err_suid;
+ }
}
return 0;
+
+err_suid:
+ if (setresuid(-1, *suid, *suid) == -1) {
+ abort();
+ }
+err_sgid:
+ if (setresgid(-1, *sgid, *sgid) == -1) {
+ abort();
+ }
+err_out:
+ return retval;
+}
+
+/*
+ * This is used to reset the ugid back with the saved values
+ * There is nothing much we can do checking error values here.
+ */
+static void resetugid(int suid, int sgid)
+{
+ if (setresgid(-1, sgid, sgid) == -1) {
+ abort();
+ }
+ if (setresuid(-1, suid, suid) == -1) {
+ abort();
+ }
}
/*
@@ -578,18 +623,15 @@ static int do_create_others(int type, struct iovec *iovec)
v9fs_string_init(&path);
v9fs_string_init(&oldpath);
- cur_uid = geteuid();
- cur_gid = getegid();
retval = proxy_unmarshal(iovec, offset, "dd", &uid, &gid);
if (retval < 0) {
return retval;
}
offset += retval;
- retval = setfsugid(uid, gid);
+ retval = setugid(uid, gid, &cur_uid, &cur_gid);
if (retval < 0) {
- retval = -errno;
- goto err_out;
+ goto unmarshal_err_out;
}
switch (type) {
case T_MKNOD:
@@ -619,9 +661,10 @@ static int do_create_others(int type, struct iovec *iovec)
}
err_out:
+ resetugid(cur_uid, cur_gid);
+unmarshal_err_out:
v9fs_string_free(&path);
v9fs_string_free(&oldpath);
- setfsugid(cur_uid, cur_gid);
return retval;
}
@@ -641,24 +684,16 @@ static int do_create(struct iovec *iovec)
if (ret < 0) {
goto unmarshal_err_out;
}
- cur_uid = geteuid();
- cur_gid = getegid();
- ret = setfsugid(uid, gid);
+ ret = setugid(uid, gid, &cur_uid, &cur_gid);
if (ret < 0) {
- /*
- * On failure reset back to the
- * old uid/gid
- */
- ret = -errno;
- goto err_out;
+ goto unmarshal_err_out;
}
ret = open(path.data, flags, mode);
if (ret < 0) {
ret = -errno;
}
-err_out:
- setfsugid(cur_uid, cur_gid);
+ resetugid(cur_uid, cur_gid);
unmarshal_err_out:
v9fs_string_free(&path);
return ret;
@@ -1004,7 +1039,7 @@ int main(int argc, char **argv)
}
switch (c) {
case 'p':
- rpath = strdup(optarg);
+ rpath = g_strdup(optarg);
break;
case 'n':
is_daemon = false;
@@ -1013,7 +1048,7 @@ int main(int argc, char **argv)
sock = atoi(optarg);
break;
case 's':
- sock_name = strdup(optarg);
+ sock_name = g_strdup(optarg);
break;
case 'u':
own_u = atoi(optarg);
diff --git a/fsdev/virtio-9p-marshal.c b/fsdev/virtio-9p-marshal.c
index bf980bf..20f308b 100644
--- a/fsdev/virtio-9p-marshal.c
+++ b/fsdev/virtio-9p-marshal.c
@@ -22,9 +22,9 @@
#include <stdint.h>
#include <errno.h>
-#include "compiler.h"
+#include "qemu/compiler.h"
#include "virtio-9p-marshal.h"
-#include "bswap.h"
+#include "qemu/bswap.h"
void v9fs_string_free(V9fsString *str)
{