diff options
author | Fathi Boudra <fathi.boudra@linaro.org> | 2013-03-30 21:18:24 +0200 |
---|---|---|
committer | Fathi Boudra <fathi.boudra@linaro.org> | 2013-03-30 21:18:24 +0200 |
commit | 050a840ead5e51a1a9f3bffe89cc89077b2f35ed (patch) | |
tree | 36d8e48e23b64a07a914b3b34d568c747915b560 /fsdev | |
parent | 17d4e9b1e2d6d32da51278a4165621af99bade02 (diff) |
Imported Upstream version 1.4.0-2013.03upstream/1.4.0-2013.03
Diffstat (limited to 'fsdev')
-rw-r--r-- | fsdev/Makefile.objs | 9 | ||||
-rw-r--r-- | fsdev/qemu-fsdev-dummy.c | 11 | ||||
-rw-r--r-- | fsdev/qemu-fsdev-opts.c | 85 | ||||
-rw-r--r-- | fsdev/qemu-fsdev.c | 14 | ||||
-rw-r--r-- | fsdev/qemu-fsdev.h | 2 | ||||
-rw-r--r-- | fsdev/virtfs-proxy-helper.c | 101 | ||||
-rw-r--r-- | fsdev/virtio-9p-marshal.c | 4 |
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) { |