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:
Peter Maydell 2018-06-07 16:22:57 +01:00
commit a674da0ab7
8 changed files with 97 additions and 66 deletions

View File

@ -559,19 +559,13 @@ static int handle_unlinkat(FsContext *ctx, V9fsPath *dir,
{ {
int dirfd, ret; int dirfd, ret;
HandleData *data = (HandleData *) ctx->private; HandleData *data = (HandleData *) ctx->private;
int rflags;
dirfd = open_by_handle(data->mountfd, dir->data, O_PATH); dirfd = open_by_handle(data->mountfd, dir->data, O_PATH);
if (dirfd < 0) { if (dirfd < 0) {
return dirfd; return dirfd;
} }
rflags = 0; ret = unlinkat(dirfd, name, flags);
if (flags & P9_DOTL_AT_REMOVEDIR) {
rflags |= AT_REMOVEDIR;
}
ret = unlinkat(dirfd, name, rflags);
close(dirfd); close(dirfd);
return ret; return ret;

View File

@ -1373,10 +1373,10 @@ static int local_unlinkat(FsContext *ctx, V9fsPath *dir,
return ret; return ret;
} }
#ifdef FS_IOC_GETVERSION
static int local_ioc_getversion(FsContext *ctx, V9fsPath *path, static int local_ioc_getversion(FsContext *ctx, V9fsPath *path,
mode_t st_mode, uint64_t *st_gen) mode_t st_mode, uint64_t *st_gen)
{ {
#ifdef FS_IOC_GETVERSION
int err; int err;
V9fsFidOpenState fid_open; 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); err = ioctl(fid_open.fd, FS_IOC_GETVERSION, st_gen);
local_close(ctx, &fid_open); local_close(ctx, &fid_open);
return err; 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 #ifdef FS_IOC_GETVERSION
struct statfs stbuf;
/* /*
* use ioc_getversion only if the ioctl is definied * use ioc_getversion only if the ioctl is definied
*/ */
if (fstatfs(data->mountfd, &stbuf) < 0) { if (fstatfs(data->mountfd, &stbuf) < 0) {
close_preserve_errno(data->mountfd); error_setg_errno(errp, errno,
goto err; "failed to stat file system at '%s'", ctx->fs_root);
return -1;
} }
switch (stbuf.f_type) { switch (stbuf.f_type) {
case EXT2_SUPER_MAGIC: case EXT2_SUPER_MAGIC:
@ -1429,6 +1420,23 @@ static int local_init(FsContext *ctx, Error **errp)
break; break;
} }
#endif #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) { if (ctx->export_flags & V9FS_SM_PASSTHROUGH) {
ctx->xops = passthrough_xattr_ops; ctx->xops = passthrough_xattr_ops;

View File

@ -1088,7 +1088,7 @@ static int proxy_ioc_getversion(FsContext *fs_ctx, V9fsPath *path,
static int connect_namedsocket(const char *path, Error **errp) static int connect_namedsocket(const char *path, Error **errp)
{ {
int sockfd, size; int sockfd;
struct sockaddr_un helper; struct sockaddr_un helper;
if (strlen(path) >= sizeof(helper.sun_path)) { 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); strcpy(helper.sun_path, path);
helper.sun_family = AF_UNIX; helper.sun_family = AF_UNIX;
size = strlen(helper.sun_path) + sizeof(helper.sun_family); if (connect(sockfd, (struct sockaddr *)&helper, sizeof(helper)) < 0) {
if (connect(sockfd, (struct sockaddr *)&helper, size) < 0) {
error_setg_errno(errp, errno, "failed to connect to '%s'", path); error_setg_errno(errp, errno, "failed to connect to '%s'", path);
close(sockfd); close(sockfd);
return -1; return -1;

View File

@ -24,3 +24,36 @@ ssize_t fgetxattrat_nofollow(int dirfd, const char *filename, const char *name,
g_free(proc_path); g_free(proc_path);
return ret; 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;
}

View File

@ -60,5 +60,9 @@ ssize_t fgetxattrat_nofollow(int dirfd, const char *path, const char *name,
void *value, size_t size); void *value, size_t size);
int fsetxattrat_nofollow(int dirfd, const char *path, const char *name, int fsetxattrat_nofollow(int dirfd, const char *path, const char *name,
void *value, size_t size, int flags); 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 #endif

View File

@ -60,17 +60,6 @@ ssize_t pt_listxattr(FsContext *ctx, const char *path,
return name_size; 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 * Get the list and pass to each layer to find out whether
* to send the data or not * 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); 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, ssize_t local_setxattr_nofollow(FsContext *ctx, const char *path,
const char *name, void *value, size_t size, const char *name, void *value, size_t size,
int flags) 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); 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, ssize_t local_removexattr_nofollow(FsContext *ctx, const char *path,
const char *name) const char *name)
{ {

View File

@ -2522,7 +2522,7 @@ static void coroutine_fn v9fs_unlinkat(void *opaque)
{ {
int err = 0; int err = 0;
V9fsString name; V9fsString name;
int32_t dfid, flags; int32_t dfid, flags, rflags = 0;
size_t offset = 7; size_t offset = 7;
V9fsPath path; V9fsPath path;
V9fsFidState *dfidp; V9fsFidState *dfidp;
@ -2549,6 +2549,15 @@ static void coroutine_fn v9fs_unlinkat(void *opaque)
goto out_nofid; 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); dfidp = get_fid(pdu, dfid);
if (dfidp == NULL) { if (dfidp == NULL) {
err = -EINVAL; err = -EINVAL;
@ -2567,7 +2576,7 @@ static void coroutine_fn v9fs_unlinkat(void *opaque)
if (err < 0) { if (err < 0) {
goto out_err; goto out_err;
} }
err = v9fs_co_unlinkat(pdu, &dfidp->path, &name, flags); err = v9fs_co_unlinkat(pdu, &dfidp->path, &name, rflags);
if (!err) { if (!err) {
err = offset; err = offset;
} }
@ -3256,8 +3265,8 @@ static void coroutine_fn v9fs_xattrwalk(void *opaque)
xattr_fidp->fs.xattr.len = size; xattr_fidp->fs.xattr.len = size;
xattr_fidp->fid_type = P9_FID_XATTR; xattr_fidp->fid_type = P9_FID_XATTR;
xattr_fidp->fs.xattr.xattrwalk_fid = true; xattr_fidp->fs.xattr.xattrwalk_fid = true;
xattr_fidp->fs.xattr.value = g_malloc0(size);
if (size) { if (size) {
xattr_fidp->fs.xattr.value = g_malloc0(size);
err = v9fs_co_llistxattr(pdu, &xattr_fidp->path, err = v9fs_co_llistxattr(pdu, &xattr_fidp->path,
xattr_fidp->fs.xattr.value, xattr_fidp->fs.xattr.value,
xattr_fidp->fs.xattr.len); 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->fs.xattr.len = size;
xattr_fidp->fid_type = P9_FID_XATTR; xattr_fidp->fid_type = P9_FID_XATTR;
xattr_fidp->fs.xattr.xattrwalk_fid = true; xattr_fidp->fs.xattr.xattrwalk_fid = true;
xattr_fidp->fs.xattr.value = g_malloc0(size);
if (size) { if (size) {
xattr_fidp->fs.xattr.value = g_malloc0(size);
err = v9fs_co_lgetxattr(pdu, &xattr_fidp->path, err = v9fs_co_lgetxattr(pdu, &xattr_fidp->path,
&name, xattr_fidp->fs.xattr.value, &name, xattr_fidp->fs.xattr.value,
xattr_fidp->fs.xattr.len); xattr_fidp->fs.xattr.len);
@ -3318,7 +3327,7 @@ out_nofid:
static void coroutine_fn v9fs_xattrcreate(void *opaque) static void coroutine_fn v9fs_xattrcreate(void *opaque)
{ {
int flags; int flags, rflags = 0;
int32_t fid; int32_t fid;
uint64_t size; uint64_t size;
ssize_t err = 0; 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); 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) { if (size > XATTR_SIZE_MAX) {
err = -E2BIG; err = -E2BIG;
goto out_nofid; 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.copied_len = 0;
xattr_fidp->fs.xattr.xattrwalk_fid = false; xattr_fidp->fs.xattr.xattrwalk_fid = false;
xattr_fidp->fs.xattr.len = size; 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_init(&xattr_fidp->fs.xattr.name);
v9fs_string_copy(&xattr_fidp->fs.xattr.name, &name); v9fs_string_copy(&xattr_fidp->fs.xattr.name, &name);
xattr_fidp->fs.xattr.value = g_malloc0(size); xattr_fidp->fs.xattr.value = g_malloc0(size);

View File

@ -169,6 +169,10 @@ typedef struct V9fsConf
char *fsdev_id; char *fsdev_id;
} V9fsConf; } V9fsConf;
/* 9p2000.L xattr flags (matches Linux values) */
#define P9_XATTR_CREATE 1
#define P9_XATTR_REPLACE 2
typedef struct V9fsXattr typedef struct V9fsXattr
{ {
uint64_t copied_len; uint64_t copied_len;