Revision 758e8e38

b/Makefile.objs
35 35
net-nested-$(CONFIG_VDE) += vde.o
36 36
net-obj-y += $(addprefix net/, $(net-nested-y))
37 37

  
38
fsdev-nested-$(CONFIG_LINUX) = qemu-fsdev.o
39
fsdev-obj-$(CONFIG_LINUX) += $(addprefix fsdev/, $(fsdev-nested-y))
38
fsdev-nested-$(CONFIG_VIRTFS) = qemu-fsdev.o
39
fsdev-obj-$(CONFIG_VIRTFS) += $(addprefix fsdev/, $(fsdev-nested-y))
40 40

  
41 41
######################################################################
42 42
# libqemu_common.a: Target independent part of system emulation. The
......
233 233
adlib.o fmopl.o: QEMU_CFLAGS += -DBUILD_Y8950=0
234 234
hw-obj-$(CONFIG_SOUND) += $(sound-obj-y)
235 235

  
236
hw-obj-$(CONFIG_LINUX) += virtio-9p-debug.o virtio-9p-local.o
236
hw-obj-$(CONFIG_VIRTFS) += virtio-9p-debug.o virtio-9p-local.o
237 237

  
238 238
######################################################################
239 239
# libdis
b/Makefile.target
169 169
obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o
170 170
obj-y += vhost_net.o
171 171
obj-$(CONFIG_VHOST_NET) += vhost.o
172
obj-$(CONFIG_LINUX) += virtio-9p.o
172
obj-$(CONFIG_VIRTFS) += virtio-9p.o
173 173
obj-y += rwhandler.o
174 174
obj-$(CONFIG_KVM) += kvm.o kvm-all.o
175 175
obj-$(CONFIG_NO_KVM) += kvm-stub.o
b/configure
270 270
vnc_sasl=""
271 271
xen=""
272 272
linux_aio=""
273
attr=""
273 274
vhost_net=""
274 275

  
275 276
gprof="no"
......
671 672
  ;;
672 673
  --enable-linux-aio) linux_aio="yes"
673 674
  ;;
675
  --disable-attr) attr="no"
676
  ;;
677
  --enable-attr) attr="yes"
678
  ;;
674 679
  --enable-io-thread) io_thread="yes"
675 680
  ;;
676 681
  --disable-blobs) blobs="no"
......
858 863
echo "  --enable-vde             enable support for vde network"
859 864
echo "  --disable-linux-aio      disable Linux AIO support"
860 865
echo "  --enable-linux-aio       enable Linux AIO support"
866
echo "  --disable-attr           disables attr and xattr support"
867
echo "  --enable-attr            enable attr and xattr support"
861 868
echo "  --enable-io-thread       enable IO thread"
862 869
echo "  --disable-blobs          disable installing provided firmware blobs"
863 870
echo "  --kerneldir=PATH         look for kernel includes in PATH"
......
1646 1653
fi
1647 1654

  
1648 1655
##########################################
1656
# attr probe
1657

  
1658
if test "$attr" != "no" ; then
1659
  cat > $TMPC <<EOF
1660
#include <stdio.h>
1661
#include <sys/types.h>
1662
#include <attr/xattr.h>
1663
int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }
1664
EOF
1665
  if compile_prog "" "-lattr" ; then
1666
    attr=yes
1667
    LIBS="-lattr $LIBS"
1668
  else
1669
    if test "$attr" = "yes" ; then
1670
      feature_not_found "ATTR"
1671
    fi
1672
    attr=no
1673
  fi
1674
fi
1675

  
1676
##########################################
1649 1677
# iovec probe
1650 1678
cat > $TMPC <<EOF
1651 1679
#include <sys/types.h>
......
2079 2107
echo "vde support       $vde"
2080 2108
echo "IO thread         $io_thread"
2081 2109
echo "Linux AIO support $linux_aio"
2110
echo "ATTR/XATTR support $attr"
2082 2111
echo "Install blobs     $blobs"
2083 2112
echo "KVM support       $kvm"
2084 2113
echo "fdt support       $fdt"
......
2280 2309
if test "$linux_aio" = "yes" ; then
2281 2310
  echo "CONFIG_LINUX_AIO=y" >> $config_host_mak
2282 2311
fi
2312
if test "$attr" = "yes" ; then
2313
  echo "CONFIG_ATTR=y" >> $config_host_mak
2314
fi
2315
if test "$linux" = "yes" ; then
2316
  if test "$attr" = "yes" ; then
2317
    echo "CONFIG_VIRTFS=y" >> $config_host_mak
2318
  fi
2319
fi
2283 2320
if test "$blobs" = "yes" ; then
2284 2321
  echo "INSTALL_BLOBS=yes" >> $config_host_mak
2285 2322
fi
b/hw/file-op-9p.h
18 18
#include <utime.h>
19 19
#include <sys/stat.h>
20 20
#include <sys/uio.h>
21
#include <sys/vfs.h>
22
#define SM_LOCAL_MODE_BITS    0600
23
#define SM_LOCAL_DIR_MODE_BITS    0700
24

  
25
typedef enum
26
{
27
    SM_PASSTHROUGH = 1, /* uid/gid set on fileserver files */
28
    SM_MAPPED,  /* uid/gid part of xattr */
29
} SecModel;
30

  
31
typedef struct FsCred
32
{
33
    uid_t   fc_uid;
34
    gid_t   fc_gid;
35
    mode_t  fc_mode;
36
    dev_t   fc_rdev;
37
} FsCred;
21 38

  
22 39
typedef struct FsContext
23 40
{
24 41
    char *fs_root;
42
    SecModel fs_sm;
25 43
    uid_t uid;
26 44
} FsContext;
27 45

  
46
extern void cred_init(FsCred *);
47

  
28 48
typedef struct FileOperations
29 49
{
30 50
    int (*lstat)(FsContext *, const char *, struct stat *);
b/hw/virtio-9p-local.c
17 17
#include <grp.h>
18 18
#include <sys/socket.h>
19 19
#include <sys/un.h>
20
#include <attr/xattr.h>
20 21

  
21 22
static const char *rpath(FsContext *ctx, const char *path)
22 23
{
......
31 32
    return lstat(rpath(ctx, path), stbuf);
32 33
}
33 34

  
34
static int local_setuid(FsContext *ctx, uid_t uid)
35
static int local_set_xattr(const char *path, FsCred *credp)
35 36
{
36
    struct passwd *pw;
37
    gid_t groups[33];
38
    int ngroups;
39
    static uid_t cur_uid = -1;
40

  
41
    if (cur_uid == uid) {
42
        return 0;
43
    }
44

  
45
    if (setreuid(0, 0)) {
46
        return -1;
47
    }
48

  
49
    pw = getpwuid(uid);
50
    if (pw == NULL) {
51
        return -1;
52
    }
53

  
54
    ngroups = 33;
55
    if (getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups) == -1) {
56
        return -1;
37
    int err;
38
    if (credp->fc_uid != -1) {
39
        err = setxattr(path, "user.virtfs.uid", &credp->fc_uid, sizeof(uid_t),
40
                0);
41
        if (err) {
42
            return err;
43
        }
57 44
    }
58

  
59
    if (setgroups(ngroups, groups)) {
60
        return -1;
45
    if (credp->fc_gid != -1) {
46
        err = setxattr(path, "user.virtfs.gid", &credp->fc_gid, sizeof(gid_t),
47
                0);
48
        if (err) {
49
            return err;
50
        }
61 51
    }
62

  
63
    if (setregid(-1, pw->pw_gid)) {
64
        return -1;
52
    if (credp->fc_mode != -1) {
53
        err = setxattr(path, "user.virtfs.mode", &credp->fc_mode,
54
                sizeof(mode_t), 0);
55
        if (err) {
56
            return err;
57
        }
65 58
    }
66

  
67
    if (setreuid(-1, uid)) {
68
        return -1;
59
    if (credp->fc_rdev != -1) {
60
        err = setxattr(path, "user.virtfs.rdev", &credp->fc_rdev,
61
                sizeof(dev_t), 0);
62
        if (err) {
63
            return err;
64
        }
69 65
    }
70

  
71
    cur_uid = uid;
72

  
73 66
    return 0;
74 67
}
75 68

  
......
183 176
    return open(rpath(ctx, path), flags, mode);
184 177
}
185 178

  
179

  
186 180
static int local_symlink(FsContext *ctx, const char *oldpath,
187 181
                            const char *newpath)
188 182
{
......
259 253

  
260 254
static int local_fsync(FsContext *ctx, int fd)
261 255
{
256
    if (0) /* Just to supress the warning. Will be removed in next patch. */
257
        (void)local_set_xattr(NULL, NULL);
262 258
    return fsync(fd);
263 259
}
264 260

  
265 261
FileOperations local_ops = {
266 262
    .lstat = local_lstat,
267
    .setuid = local_setuid,
268 263
    .readlink = local_readlink,
269 264
    .close = local_close,
270 265
    .closedir = local_closedir,
b/hw/virtio-9p.c
67 67
    return ret;
68 68
}
69 69

  
70
static int v9fs_do_lstat(V9fsState *s, V9fsString *path, struct stat *stbuf)
70
void cred_init(FsCred *credp)
71 71
{
72
    return s->ops->lstat(&s->ctx, path->data, stbuf);
72
    credp->fc_uid = -1;
73
    credp->fc_gid = -1;
74
    credp->fc_mode = -1;
75
    credp->fc_rdev = -1;
73 76
}
74 77

  
75
static int v9fs_do_setuid(V9fsState *s, uid_t uid)
78
static int v9fs_do_lstat(V9fsState *s, V9fsString *path, struct stat *stbuf)
76 79
{
77
    return s->ops->setuid(&s->ctx, uid);
80
    return s->ops->lstat(&s->ctx, path->data, stbuf);
78 81
}
79 82

  
80 83
static ssize_t v9fs_do_readlink(V9fsState *s, V9fsString *path, V9fsString *buf)
......
348 351

  
349 352
    for (f = s->fid_list; f; f = f->next) {
350 353
        if (f->fid == fid) {
351
            v9fs_do_setuid(s, f->uid);
352 354
            return f;
353 355
        }
354 356
    }
......
2253 2255
        exit(1);
2254 2256
    }
2255 2257

  
2256
    if (!strcmp(fse->security_model, "passthrough") &&
2257
                !strcmp(fse->security_model, "mapped")) {
2258
    if (!strcmp(fse->security_model, "passthrough")) {
2259
        /* Files on the Fileserver set to client user credentials */
2260
        s->ctx.fs_sm = SM_PASSTHROUGH;
2261
    } else if (!strcmp(fse->security_model, "mapped")) {
2262
        /* Files on the fileserver are set to QEMU credentials.
2263
         * Client user credentials are saved in extended attributes.
2264
         */
2265
        s->ctx.fs_sm = SM_MAPPED;
2266
    } else {
2258 2267
        /* user haven't specified a correct security option */
2259 2268
        fprintf(stderr, "one of the following must be specified as the"
2260 2269
                "security option:\n\t security_model=passthrough \n\t "
b/hw/virtio-pci.c
641 641
    return 0;
642 642
}
643 643

  
644
#ifdef CONFIG_LINUX
644
#ifdef CONFIG_VIRTFS
645 645
static int virtio_9p_init_pci(PCIDevice *pci_dev)
646 646
{
647 647
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
......
712 712
        },
713 713
        .qdev.reset = virtio_pci_reset,
714 714
    },{
715
#ifdef CONFIG_LINUX
715
#ifdef CONFIG_VIRTFS
716 716
        .qdev.name = "virtio-9p-pci",
717 717
        .qdev.size = sizeof(VirtIOPCIProxy),
718 718
        .init      = virtio_9p_init_pci,
b/vl.c
147 147
#include "qemu-config.h"
148 148
#include "qemu-objects.h"
149 149
#include "qemu-options.h"
150
#ifdef CONFIG_LINUX
150
#ifdef CONFIG_VIRTFS
151 151
#include "fsdev/qemu-fsdev.h"
152 152
#endif
153 153

  
......
1532 1532
    return 0;
1533 1533
}
1534 1534

  
1535
#ifdef CONFIG_LINUX
1535
#ifdef CONFIG_VIRTFS
1536 1536
static int fsdev_init_func(QemuOpts *opts, void *opaque)
1537 1537
{
1538 1538
    int ret;
......
2281 2281
                    exit(1);
2282 2282
                }
2283 2283
                break;
2284
#ifdef CONFIG_LINUX
2284
#ifdef CONFIG_VIRTFS
2285 2285
            case QEMU_OPTION_fsdev:
2286 2286
                opts = qemu_opts_parse(&qemu_fsdev_opts, optarg, 1);
2287 2287
                if (!opts) {
......
2705 2705

  
2706 2706
    if (qemu_opts_foreach(&qemu_chardev_opts, chardev_init_func, NULL, 1) != 0)
2707 2707
        exit(1);
2708
#ifdef CONFIG_LINUX
2708
#ifdef CONFIG_VIRTFS
2709 2709
    if (qemu_opts_foreach(&qemu_fsdev_opts, fsdev_init_func, NULL, 1) != 0) {
2710 2710
        exit(1);
2711 2711
    }

Also available in: Unified diff