Commit 454d7dc9 authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/gkurz/tags/for-upstream' into staging



- fixes a minor bug that could possibly prevent old guests to remove
  directories
- makes default permissions for new files configurable from the cmdline
  when using mapped security modes
- handle transport errors
- g_malloc()+memcpy() converted to g_memdup()

# gpg: Signature made Thu 29 Jun 2017 14:12:42 BST
# gpg:                using DSA key 0x02FC3AEB0101DBC2
# gpg: Good signature from "Greg Kurz <groug@kaod.org>"
# gpg:                 aka "Greg Kurz <groug@free.fr>"
# gpg:                 aka "Greg Kurz <gkurz@linux.vnet.ibm.com>"
# gpg:                 aka "Gregory Kurz (Groug) <groug@free.fr>"
# gpg:                 aka "[jpeg image of size 3330]"
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 2BD4 3B44 535E C0A7 9894  DBA2 02FC 3AEB 0101 DBC2

* remotes/gkurz/tags/for-upstream:
  9pfs: handle transport errors in pdu_complete()
  xen-9pfs: disconnect if buffers are misconfigured
  virtio-9p: break device if buffers are misconfigured
  virtio-9p: message header is 7-byte long
  virtio-9p: record element after sanity checks
  9pfs: replace g_malloc()+memcpy() with g_memdup()
  9pfs: local: Add support for custom fmode/dmode in 9ps mapped security modes
  9pfs: local: remove: use correct path component

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents e7206249 06a37db7
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -76,6 +76,8 @@ typedef struct FsDriverEntry {
    int export_flags;
    FileOperations *ops;
    FsThrottle fst;
    mode_t fmode;
    mode_t dmode;
} FsDriverEntry;

typedef struct FsContext
@@ -88,6 +90,8 @@ typedef struct FsContext
    FsThrottle *fst;
    /* fs driver specific data */
    void *private;
    mode_t fmode;
    mode_t dmode;
} FsContext;

typedef struct V9fsPath {
+12 −0
Original line number Diff line number Diff line
@@ -38,6 +38,12 @@ static QemuOptsList qemu_fsdev_opts = {
        }, {
            .name = "sock_fd",
            .type = QEMU_OPT_NUMBER,
        }, {
            .name = "fmode",
            .type = QEMU_OPT_NUMBER,
        }, {
            .name = "dmode",
            .type = QEMU_OPT_NUMBER,
        },

        THROTTLE_OPTS,
@@ -75,6 +81,12 @@ static QemuOptsList qemu_virtfs_opts = {
        }, {
            .name = "sock_fd",
            .type = QEMU_OPT_NUMBER,
        }, {
            .name = "fmode",
            .type = QEMU_OPT_NUMBER,
        }, {
            .name = "dmode",
            .type = QEMU_OPT_NUMBER,
        },

        { /*End of list */ }
+22 −5
Original line number Diff line number Diff line
@@ -633,7 +633,7 @@ static int local_mknod(FsContext *fs_ctx, V9fsPath *dir_path,

    if (fs_ctx->export_flags & V9FS_SM_MAPPED ||
        fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
        err = mknodat(dirfd, name, SM_LOCAL_MODE_BITS | S_IFREG, 0);
        err = mknodat(dirfd, name, fs_ctx->fmode | S_IFREG, 0);
        if (err == -1) {
            goto out;
        }
@@ -685,7 +685,7 @@ static int local_mkdir(FsContext *fs_ctx, V9fsPath *dir_path,

    if (fs_ctx->export_flags & V9FS_SM_MAPPED ||
        fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
        err = mkdirat(dirfd, name, SM_LOCAL_DIR_MODE_BITS);
        err = mkdirat(dirfd, name, fs_ctx->dmode);
        if (err == -1) {
            goto out;
        }
@@ -786,7 +786,7 @@ static int local_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name,
    /* Determine the security model */
    if (fs_ctx->export_flags & V9FS_SM_MAPPED ||
        fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
        fd = openat_file(dirfd, name, flags, SM_LOCAL_MODE_BITS);
        fd = openat_file(dirfd, name, flags, fs_ctx->fmode);
        if (fd == -1) {
            goto out;
        }
@@ -849,7 +849,7 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath,
        ssize_t oldpath_size, write_size;

        fd = openat_file(dirfd, name, O_CREAT | O_EXCL | O_RDWR,
                         SM_LOCAL_MODE_BITS);
                         fs_ctx->fmode);
        if (fd == -1) {
            goto out;
        }
@@ -1100,7 +1100,7 @@ static int local_remove(FsContext *ctx, const char *path)
        goto out;
    }

    if (fstatat(dirfd, path, &stbuf, AT_SYMLINK_NOFOLLOW) < 0) {
    if (fstatat(dirfd, name, &stbuf, AT_SYMLINK_NOFOLLOW) < 0) {
        goto err_out;
    }

@@ -1467,6 +1467,23 @@ static int local_parse_opts(QemuOpts *opts, struct FsDriverEntry *fse)
        return -1;
    }

    if (fse->export_flags & V9FS_SM_MAPPED ||
        fse->export_flags & V9FS_SM_MAPPED_FILE) {
        fse->fmode =
            qemu_opt_get_number(opts, "fmode", SM_LOCAL_MODE_BITS) & 0777;
        fse->dmode =
            qemu_opt_get_number(opts, "dmode", SM_LOCAL_DIR_MODE_BITS) & 0777;
    } else {
        if (qemu_opt_find(opts, "fmode")) {
            error_report("fmode is only valid for mapped 9p modes");
            return -1;
        }
        if (qemu_opt_find(opts, "dmode")) {
            error_report("dmode is only valid for mapped 9p modes");
            return -1;
        }
    }

    fse->path = g_strdup(path);

    return 0;
+1 −2
Original line number Diff line number Diff line
@@ -494,8 +494,7 @@ static int synth_name_to_path(FsContext *ctx, V9fsPath *dir_path,
    }
out:
    /* Copy the node pointer to fid */
    target->data = g_malloc(sizeof(void *));
    memcpy(target->data, &node, sizeof(void *));
    target->data = g_memdup(&node, sizeof(void *));
    target->size = sizeof(void *);
    return 0;
}
+19 −9
Original line number Diff line number Diff line
@@ -624,15 +624,11 @@ void pdu_free(V9fsPDU *pdu)
    QLIST_INSERT_HEAD(&s->free_list, pdu, next);
}

/*
 * We don't do error checking for pdu_marshal/unmarshal here
 * because we always expect to have enough space to encode
 * error details
 */
static void coroutine_fn pdu_complete(V9fsPDU *pdu, ssize_t len)
{
    int8_t id = pdu->id + 1; /* Response */
    V9fsState *s = pdu->s;
    int ret;

    if (len < 0) {
        int err = -len;
@@ -644,11 +640,19 @@ static void coroutine_fn pdu_complete(V9fsPDU *pdu, ssize_t len)
            str.data = strerror(err);
            str.size = strlen(str.data);

            len += pdu_marshal(pdu, len, "s", &str);
            ret = pdu_marshal(pdu, len, "s", &str);
            if (ret < 0) {
                goto out_notify;
            }
            len += ret;
            id = P9_RERROR;
        }

        len += pdu_marshal(pdu, len, "d", err);
        ret = pdu_marshal(pdu, len, "d", err);
        if (ret < 0) {
            goto out_notify;
        }
        len += ret;

        if (s->proto_version == V9FS_PROTO_2000L) {
            id = P9_RLERROR;
@@ -657,12 +661,15 @@ static void coroutine_fn pdu_complete(V9fsPDU *pdu, ssize_t len)
    }

    /* fill out the header */
    pdu_marshal(pdu, 0, "dbw", (int32_t)len, id, pdu->tag);
    if (pdu_marshal(pdu, 0, "dbw", (int32_t)len, id, pdu->tag) < 0) {
        goto out_notify;
    }

    /* keep these in sync */
    pdu->size = len;
    pdu->id = id;

out_notify:
    pdu->s->transport->push_and_notify(pdu);

    /* Now wakeup anybody waiting in flush for this request */
@@ -1664,7 +1671,7 @@ static void v9fs_init_qiov_from_pdu(QEMUIOVector *qiov, V9fsPDU *pdu,
    unsigned int niov;

    if (is_write) {
        pdu->s->transport->init_out_iov_from_pdu(pdu, &iov, &niov);
        pdu->s->transport->init_out_iov_from_pdu(pdu, &iov, &niov, size + skip);
    } else {
        pdu->s->transport->init_in_iov_from_pdu(pdu, &iov, &niov, size + skip);
    }
@@ -3533,6 +3540,9 @@ int v9fs_device_realize_common(V9fsState *s, Error **errp)

    s->ops = fse->ops;

    s->ctx.fmode = fse->fmode;
    s->ctx.dmode = fse->dmode;

    s->fid_list = NULL;
    qemu_co_rwlock_init(&s->rename_lock);

Loading