mirror of https://github.com/xemu-project/xemu.git
Mostly bug fixes and code sanitization motivated by the upcoming
support for Darwin hosts. Thanks to Keno Fischer. -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEtIKLr5QxQM7yo0kQcdTV5YIvc9YFAlsZCWAACgkQcdTV5YIv c9blAg//U76b27YdGeYQoBVbNJpgOxz9aVfzHZccMRDFCaQypBa1IpJFwvho550a Xp8kTGJIzI/mEnTkiDTzaHXZusYCZwwlArY+3Qi3hygJh2vN7Yx/l9247NtWWTUC l9lXV5tFGkMwd0WH9wajyy+rFfLTQ5aFkc+mTrl2fcabYIMMztKXEz1LFS/bX8wO r/ezqp0AnNDB4rGGaHPhwAxwPw186hhsVOBpTRNgBlrxP4zrZ/Thhth7ORV10lMX koJVY4SmwvhpiozXU1a5RasiXizg0N/LlR2y3fBFZDr1znk0hcE4h/2AP2VJwSAp SJ5sq9QfDy3FEtHeDLQY6ypKhxh26mjLEGHkQG7E56kqjwnrsMnV/y2IJLpK7vvX FuQ1g/hQrB7hbvHGkTo4wW/01xoTKCqXDEMNNJhyjU2AoVjfsF3g0M/EB/UOrLlr 51YslBqBNIKQ0e/TIIz0ovyT4y9SGWZy3gpx7Ri4g4QG1NeV0QPj7XquclcvGo6k l7z7lauwdHfR/Koo0tfxsrHiircUCsJEDh0YmiWusqrMnN7TY3v9gzAUUgXN4JpU UyFtM86qrlBIA8X0pyaWICIyf9EGPn9xKgUQMtmvmAQopiCwtCUuF7+pau8Ahd6g cGo2WpyyOkcl1w5tmilrHH7omEFEFt6a5QmB0HUSEd+GtFUkJ+U= =30AO -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/gkurz/tags/for-upstream' into staging Mostly bug fixes and code sanitization motivated by the upcoming support for Darwin hosts. Thanks to Keno Fischer. # gpg: Signature made Thu 07 Jun 2018 11:30:56 BST # gpg: using RSA key 71D4D5E5822F73D6 # gpg: Good signature from "Greg Kurz <groug@kaod.org>" # gpg: aka "Gregory Kurz <gregory.kurz@free.fr>" # gpg: aka "[jpeg image of size 3330]" # Primary key fingerprint: B482 8BAF 9431 40CE F2A3 4910 71D4 D5E5 822F 73D6 * remotes/gkurz/tags/for-upstream: 9p: xattr: Properly translate xattrcreate flags 9p: Properly check/translate flags in unlinkat 9p: local: Avoid warning if FS_IOC_GETVERSION is not defined 9p: xattr: Fix crashes due to free of uninitialized value 9p: Move a couple xattr functions to 9p-util 9p: local: Properly set errp in fstatfs error path 9p: proxy: Fix size passed to `connect` Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
a674da0ab7
|
@ -559,19 +559,13 @@ static int handle_unlinkat(FsContext *ctx, V9fsPath *dir,
|
|||
{
|
||||
int dirfd, ret;
|
||||
HandleData *data = (HandleData *) ctx->private;
|
||||
int rflags;
|
||||
|
||||
dirfd = open_by_handle(data->mountfd, dir->data, O_PATH);
|
||||
if (dirfd < 0) {
|
||||
return dirfd;
|
||||
}
|
||||
|
||||
rflags = 0;
|
||||
if (flags & P9_DOTL_AT_REMOVEDIR) {
|
||||
rflags |= AT_REMOVEDIR;
|
||||
}
|
||||
|
||||
ret = unlinkat(dirfd, name, rflags);
|
||||
ret = unlinkat(dirfd, name, flags);
|
||||
|
||||
close(dirfd);
|
||||
return ret;
|
||||
|
|
|
@ -1373,10 +1373,10 @@ static int local_unlinkat(FsContext *ctx, V9fsPath *dir,
|
|||
return ret;
|
||||
}
|
||||
|
||||
#ifdef FS_IOC_GETVERSION
|
||||
static int local_ioc_getversion(FsContext *ctx, V9fsPath *path,
|
||||
mode_t st_mode, uint64_t *st_gen)
|
||||
{
|
||||
#ifdef FS_IOC_GETVERSION
|
||||
int err;
|
||||
V9fsFidOpenState fid_open;
|
||||
|
||||
|
@ -1395,30 +1395,21 @@ static int local_ioc_getversion(FsContext *ctx, V9fsPath *path,
|
|||
err = ioctl(fid_open.fd, FS_IOC_GETVERSION, st_gen);
|
||||
local_close(ctx, &fid_open);
|
||||
return err;
|
||||
#else
|
||||
errno = ENOTTY;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
static int local_init(FsContext *ctx, Error **errp)
|
||||
static int local_ioc_getversion_init(FsContext *ctx, LocalData *data, Error **errp)
|
||||
{
|
||||
struct statfs stbuf;
|
||||
LocalData *data = g_malloc(sizeof(*data));
|
||||
|
||||
data->mountfd = open(ctx->fs_root, O_DIRECTORY | O_RDONLY);
|
||||
if (data->mountfd == -1) {
|
||||
error_setg_errno(errp, errno, "failed to open '%s'", ctx->fs_root);
|
||||
goto err;
|
||||
}
|
||||
|
||||
#ifdef FS_IOC_GETVERSION
|
||||
struct statfs stbuf;
|
||||
|
||||
/*
|
||||
* use ioc_getversion only if the ioctl is definied
|
||||
*/
|
||||
if (fstatfs(data->mountfd, &stbuf) < 0) {
|
||||
close_preserve_errno(data->mountfd);
|
||||
goto err;
|
||||
error_setg_errno(errp, errno,
|
||||
"failed to stat file system at '%s'", ctx->fs_root);
|
||||
return -1;
|
||||
}
|
||||
switch (stbuf.f_type) {
|
||||
case EXT2_SUPER_MAGIC:
|
||||
|
@ -1429,6 +1420,23 @@ static int local_init(FsContext *ctx, Error **errp)
|
|||
break;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int local_init(FsContext *ctx, Error **errp)
|
||||
{
|
||||
LocalData *data = g_malloc(sizeof(*data));
|
||||
|
||||
data->mountfd = open(ctx->fs_root, O_DIRECTORY | O_RDONLY);
|
||||
if (data->mountfd == -1) {
|
||||
error_setg_errno(errp, errno, "failed to open '%s'", ctx->fs_root);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (local_ioc_getversion_init(ctx, data, errp) < 0) {
|
||||
close(data->mountfd);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (ctx->export_flags & V9FS_SM_PASSTHROUGH) {
|
||||
ctx->xops = passthrough_xattr_ops;
|
||||
|
|
|
@ -1088,7 +1088,7 @@ static int proxy_ioc_getversion(FsContext *fs_ctx, V9fsPath *path,
|
|||
|
||||
static int connect_namedsocket(const char *path, Error **errp)
|
||||
{
|
||||
int sockfd, size;
|
||||
int sockfd;
|
||||
struct sockaddr_un helper;
|
||||
|
||||
if (strlen(path) >= sizeof(helper.sun_path)) {
|
||||
|
@ -1102,8 +1102,7 @@ static int connect_namedsocket(const char *path, Error **errp)
|
|||
}
|
||||
strcpy(helper.sun_path, path);
|
||||
helper.sun_family = AF_UNIX;
|
||||
size = strlen(helper.sun_path) + sizeof(helper.sun_family);
|
||||
if (connect(sockfd, (struct sockaddr *)&helper, size) < 0) {
|
||||
if (connect(sockfd, (struct sockaddr *)&helper, sizeof(helper)) < 0) {
|
||||
error_setg_errno(errp, errno, "failed to connect to '%s'", path);
|
||||
close(sockfd);
|
||||
return -1;
|
||||
|
|
|
@ -24,3 +24,36 @@ ssize_t fgetxattrat_nofollow(int dirfd, const char *filename, const char *name,
|
|||
g_free(proc_path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t flistxattrat_nofollow(int dirfd, const char *filename,
|
||||
char *list, size_t size)
|
||||
{
|
||||
char *proc_path = g_strdup_printf("/proc/self/fd/%d/%s", dirfd, filename);
|
||||
int ret;
|
||||
|
||||
ret = llistxattr(proc_path, list, size);
|
||||
g_free(proc_path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t fremovexattrat_nofollow(int dirfd, const char *filename,
|
||||
const char *name)
|
||||
{
|
||||
char *proc_path = g_strdup_printf("/proc/self/fd/%d/%s", dirfd, filename);
|
||||
int ret;
|
||||
|
||||
ret = lremovexattr(proc_path, name);
|
||||
g_free(proc_path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int fsetxattrat_nofollow(int dirfd, const char *filename, const char *name,
|
||||
void *value, size_t size, int flags)
|
||||
{
|
||||
char *proc_path = g_strdup_printf("/proc/self/fd/%d/%s", dirfd, filename);
|
||||
int ret;
|
||||
|
||||
ret = lsetxattr(proc_path, name, value, size, flags);
|
||||
g_free(proc_path);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -60,5 +60,9 @@ ssize_t fgetxattrat_nofollow(int dirfd, const char *path, const char *name,
|
|||
void *value, size_t size);
|
||||
int fsetxattrat_nofollow(int dirfd, const char *path, const char *name,
|
||||
void *value, size_t size, int flags);
|
||||
ssize_t flistxattrat_nofollow(int dirfd, const char *filename,
|
||||
char *list, size_t size);
|
||||
ssize_t fremovexattrat_nofollow(int dirfd, const char *filename,
|
||||
const char *name);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -60,17 +60,6 @@ ssize_t pt_listxattr(FsContext *ctx, const char *path,
|
|||
return name_size;
|
||||
}
|
||||
|
||||
static ssize_t flistxattrat_nofollow(int dirfd, const char *filename,
|
||||
char *list, size_t size)
|
||||
{
|
||||
char *proc_path = g_strdup_printf("/proc/self/fd/%d/%s", dirfd, filename);
|
||||
int ret;
|
||||
|
||||
ret = llistxattr(proc_path, list, size);
|
||||
g_free(proc_path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the list and pass to each layer to find out whether
|
||||
* to send the data or not
|
||||
|
@ -196,17 +185,6 @@ ssize_t pt_getxattr(FsContext *ctx, const char *path, const char *name,
|
|||
return local_getxattr_nofollow(ctx, path, name, value, size);
|
||||
}
|
||||
|
||||
int fsetxattrat_nofollow(int dirfd, const char *filename, const char *name,
|
||||
void *value, size_t size, int flags)
|
||||
{
|
||||
char *proc_path = g_strdup_printf("/proc/self/fd/%d/%s", dirfd, filename);
|
||||
int ret;
|
||||
|
||||
ret = lsetxattr(proc_path, name, value, size, flags);
|
||||
g_free(proc_path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t local_setxattr_nofollow(FsContext *ctx, const char *path,
|
||||
const char *name, void *value, size_t size,
|
||||
int flags)
|
||||
|
@ -235,17 +213,6 @@ int pt_setxattr(FsContext *ctx, const char *path, const char *name, void *value,
|
|||
return local_setxattr_nofollow(ctx, path, name, value, size, flags);
|
||||
}
|
||||
|
||||
static ssize_t fremovexattrat_nofollow(int dirfd, const char *filename,
|
||||
const char *name)
|
||||
{
|
||||
char *proc_path = g_strdup_printf("/proc/self/fd/%d/%s", dirfd, filename);
|
||||
int ret;
|
||||
|
||||
ret = lremovexattr(proc_path, name);
|
||||
g_free(proc_path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t local_removexattr_nofollow(FsContext *ctx, const char *path,
|
||||
const char *name)
|
||||
{
|
||||
|
|
34
hw/9pfs/9p.c
34
hw/9pfs/9p.c
|
@ -2522,7 +2522,7 @@ static void coroutine_fn v9fs_unlinkat(void *opaque)
|
|||
{
|
||||
int err = 0;
|
||||
V9fsString name;
|
||||
int32_t dfid, flags;
|
||||
int32_t dfid, flags, rflags = 0;
|
||||
size_t offset = 7;
|
||||
V9fsPath path;
|
||||
V9fsFidState *dfidp;
|
||||
|
@ -2549,6 +2549,15 @@ static void coroutine_fn v9fs_unlinkat(void *opaque)
|
|||
goto out_nofid;
|
||||
}
|
||||
|
||||
if (flags & ~P9_DOTL_AT_REMOVEDIR) {
|
||||
err = -EINVAL;
|
||||
goto out_nofid;
|
||||
}
|
||||
|
||||
if (flags & P9_DOTL_AT_REMOVEDIR) {
|
||||
rflags |= AT_REMOVEDIR;
|
||||
}
|
||||
|
||||
dfidp = get_fid(pdu, dfid);
|
||||
if (dfidp == NULL) {
|
||||
err = -EINVAL;
|
||||
|
@ -2567,7 +2576,7 @@ static void coroutine_fn v9fs_unlinkat(void *opaque)
|
|||
if (err < 0) {
|
||||
goto out_err;
|
||||
}
|
||||
err = v9fs_co_unlinkat(pdu, &dfidp->path, &name, flags);
|
||||
err = v9fs_co_unlinkat(pdu, &dfidp->path, &name, rflags);
|
||||
if (!err) {
|
||||
err = offset;
|
||||
}
|
||||
|
@ -3256,8 +3265,8 @@ static void coroutine_fn v9fs_xattrwalk(void *opaque)
|
|||
xattr_fidp->fs.xattr.len = size;
|
||||
xattr_fidp->fid_type = P9_FID_XATTR;
|
||||
xattr_fidp->fs.xattr.xattrwalk_fid = true;
|
||||
xattr_fidp->fs.xattr.value = g_malloc0(size);
|
||||
if (size) {
|
||||
xattr_fidp->fs.xattr.value = g_malloc0(size);
|
||||
err = v9fs_co_llistxattr(pdu, &xattr_fidp->path,
|
||||
xattr_fidp->fs.xattr.value,
|
||||
xattr_fidp->fs.xattr.len);
|
||||
|
@ -3289,8 +3298,8 @@ static void coroutine_fn v9fs_xattrwalk(void *opaque)
|
|||
xattr_fidp->fs.xattr.len = size;
|
||||
xattr_fidp->fid_type = P9_FID_XATTR;
|
||||
xattr_fidp->fs.xattr.xattrwalk_fid = true;
|
||||
xattr_fidp->fs.xattr.value = g_malloc0(size);
|
||||
if (size) {
|
||||
xattr_fidp->fs.xattr.value = g_malloc0(size);
|
||||
err = v9fs_co_lgetxattr(pdu, &xattr_fidp->path,
|
||||
&name, xattr_fidp->fs.xattr.value,
|
||||
xattr_fidp->fs.xattr.len);
|
||||
|
@ -3318,7 +3327,7 @@ out_nofid:
|
|||
|
||||
static void coroutine_fn v9fs_xattrcreate(void *opaque)
|
||||
{
|
||||
int flags;
|
||||
int flags, rflags = 0;
|
||||
int32_t fid;
|
||||
uint64_t size;
|
||||
ssize_t err = 0;
|
||||
|
@ -3335,6 +3344,19 @@ static void coroutine_fn v9fs_xattrcreate(void *opaque)
|
|||
}
|
||||
trace_v9fs_xattrcreate(pdu->tag, pdu->id, fid, name.data, size, flags);
|
||||
|
||||
if (flags & ~(P9_XATTR_CREATE | P9_XATTR_REPLACE)) {
|
||||
err = -EINVAL;
|
||||
goto out_nofid;
|
||||
}
|
||||
|
||||
if (flags & P9_XATTR_CREATE) {
|
||||
rflags |= XATTR_CREATE;
|
||||
}
|
||||
|
||||
if (flags & P9_XATTR_REPLACE) {
|
||||
rflags |= XATTR_REPLACE;
|
||||
}
|
||||
|
||||
if (size > XATTR_SIZE_MAX) {
|
||||
err = -E2BIG;
|
||||
goto out_nofid;
|
||||
|
@ -3356,7 +3378,7 @@ static void coroutine_fn v9fs_xattrcreate(void *opaque)
|
|||
xattr_fidp->fs.xattr.copied_len = 0;
|
||||
xattr_fidp->fs.xattr.xattrwalk_fid = false;
|
||||
xattr_fidp->fs.xattr.len = size;
|
||||
xattr_fidp->fs.xattr.flags = flags;
|
||||
xattr_fidp->fs.xattr.flags = rflags;
|
||||
v9fs_string_init(&xattr_fidp->fs.xattr.name);
|
||||
v9fs_string_copy(&xattr_fidp->fs.xattr.name, &name);
|
||||
xattr_fidp->fs.xattr.value = g_malloc0(size);
|
||||
|
|
|
@ -169,6 +169,10 @@ typedef struct V9fsConf
|
|||
char *fsdev_id;
|
||||
} V9fsConf;
|
||||
|
||||
/* 9p2000.L xattr flags (matches Linux values) */
|
||||
#define P9_XATTR_CREATE 1
|
||||
#define P9_XATTR_REPLACE 2
|
||||
|
||||
typedef struct V9fsXattr
|
||||
{
|
||||
uint64_t copied_len;
|
||||
|
|
Loading…
Reference in New Issue