Merge remote-tracking branch 'aneesh/for-upstream' into staging

# By Aneesh Kumar K.V (3) and Gabriel de Perthuis (1)
# Via Aneesh Kumar K.V
* aneesh/for-upstream:
  hw/9pfs: Be robust against paths without FS_IOC_GETVERSION
  hw/9pfs: Use O_NOFOLLOW when opening files on server
  hw/9pfs: use O_NOFOLLOW for mapped readlink operation
  hw/9pfs: Fix segfault with 9p2000.u

Message-id: 87zjvevx4s.fsf@linux.vnet.ibm.com
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
Anthony Liguori 2013-05-29 08:13:20 -05:00
commit 338ea905e9
3 changed files with 47 additions and 9 deletions

View File

@ -38,6 +38,10 @@ int v9fs_co_st_gen(V9fsPDU *pdu, V9fsPath *path, mode_t st_mode,
}); });
v9fs_path_unlock(s); v9fs_path_unlock(s);
} }
/* The ioctl may not be supported depending on the path */
if (err == -ENOTTY) {
err = 0;
}
return err; return err;
} }

View File

@ -59,6 +59,33 @@ static const char *local_mapped_attr_path(FsContext *ctx,
return buffer; return buffer;
} }
static FILE *local_fopen(const char *path, const char *mode)
{
int fd, o_mode = 0;
FILE *fp;
int flags = O_NOFOLLOW;
/*
* only supports two modes
*/
if (mode[0] == 'r') {
flags |= O_RDONLY;
} else if (mode[0] == 'w') {
flags |= O_WRONLY | O_TRUNC | O_CREAT;
o_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
} else {
return NULL;
}
fd = open(path, flags, o_mode);
if (fd == -1) {
return NULL;
}
fp = fdopen(fd, mode);
if (!fp) {
close(fd);
}
return fp;
}
#define ATTR_MAX 100 #define ATTR_MAX 100
static void local_mapped_file_attr(FsContext *ctx, const char *path, static void local_mapped_file_attr(FsContext *ctx, const char *path,
struct stat *stbuf) struct stat *stbuf)
@ -68,7 +95,7 @@ static void local_mapped_file_attr(FsContext *ctx, const char *path,
char attr_path[PATH_MAX]; char attr_path[PATH_MAX];
local_mapped_attr_path(ctx, path, attr_path); local_mapped_attr_path(ctx, path, attr_path);
fp = fopen(attr_path, "r"); fp = local_fopen(attr_path, "r");
if (!fp) { if (!fp) {
return; return;
} }
@ -152,7 +179,7 @@ static int local_set_mapped_file_attr(FsContext *ctx,
char attr_path[PATH_MAX]; char attr_path[PATH_MAX];
int uid = -1, gid = -1, mode = -1, rdev = -1; int uid = -1, gid = -1, mode = -1, rdev = -1;
fp = fopen(local_mapped_attr_path(ctx, path, attr_path), "r"); fp = local_fopen(local_mapped_attr_path(ctx, path, attr_path), "r");
if (!fp) { if (!fp) {
goto create_map_file; goto create_map_file;
} }
@ -179,7 +206,7 @@ create_map_file:
} }
update_map_file: update_map_file:
fp = fopen(attr_path, "w"); fp = local_fopen(attr_path, "w");
if (!fp) { if (!fp) {
ret = -1; ret = -1;
goto err_out; goto err_out;
@ -284,7 +311,7 @@ static ssize_t local_readlink(FsContext *fs_ctx, V9fsPath *fs_path,
if ((fs_ctx->export_flags & V9FS_SM_MAPPED) || if ((fs_ctx->export_flags & V9FS_SM_MAPPED) ||
(fs_ctx->export_flags & V9FS_SM_MAPPED_FILE)) { (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE)) {
int fd; int fd;
fd = open(rpath(fs_ctx, path, buffer), O_RDONLY); fd = open(rpath(fs_ctx, path, buffer), O_RDONLY | O_NOFOLLOW);
if (fd == -1) { if (fd == -1) {
return -1; return -1;
} }
@ -316,7 +343,7 @@ static int local_open(FsContext *ctx, V9fsPath *fs_path,
char buffer[PATH_MAX]; char buffer[PATH_MAX];
char *path = fs_path->data; char *path = fs_path->data;
fs->fd = open(rpath(ctx, path, buffer), flags); fs->fd = open(rpath(ctx, path, buffer), flags | O_NOFOLLOW);
return fs->fd; return fs->fd;
} }
@ -601,6 +628,11 @@ static int local_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name,
V9fsString fullname; V9fsString fullname;
char buffer[PATH_MAX]; char buffer[PATH_MAX];
/*
* Mark all the open to not follow symlinks
*/
flags |= O_NOFOLLOW;
v9fs_string_init(&fullname); v9fs_string_init(&fullname);
v9fs_string_sprintf(&fullname, "%s/%s", dir_path->data, name); v9fs_string_sprintf(&fullname, "%s/%s", dir_path->data, name);
path = fullname.data; path = fullname.data;
@ -676,8 +708,9 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath,
if (fs_ctx->export_flags & V9FS_SM_MAPPED) { if (fs_ctx->export_flags & V9FS_SM_MAPPED) {
int fd; int fd;
ssize_t oldpath_size, write_size; ssize_t oldpath_size, write_size;
fd = open(rpath(fs_ctx, newpath, buffer), O_CREAT|O_EXCL|O_RDWR, fd = open(rpath(fs_ctx, newpath, buffer),
SM_LOCAL_MODE_BITS); O_CREAT|O_EXCL|O_RDWR|O_NOFOLLOW,
SM_LOCAL_MODE_BITS);
if (fd == -1) { if (fd == -1) {
err = fd; err = fd;
goto out; goto out;
@ -705,7 +738,8 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath,
} else if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) { } else if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
int fd; int fd;
ssize_t oldpath_size, write_size; ssize_t oldpath_size, write_size;
fd = open(rpath(fs_ctx, newpath, buffer), O_CREAT|O_EXCL|O_RDWR, fd = open(rpath(fs_ctx, newpath, buffer),
O_CREAT|O_EXCL|O_RDWR|O_NOFOLLOW,
SM_LOCAL_MODE_BITS); SM_LOCAL_MODE_BITS);
if (fd == -1) { if (fd == -1) {
err = fd; err = fd;

View File

@ -658,7 +658,7 @@ static mode_t v9mode_to_mode(uint32_t mode, V9fsString *extension)
ret |= S_IFIFO; ret |= S_IFIFO;
} }
if (mode & P9_STAT_MODE_DEVICE) { if (mode & P9_STAT_MODE_DEVICE) {
if (extension && extension->data[0] == 'c') { if (extension->size && extension->data[0] == 'c') {
ret |= S_IFCHR; ret |= S_IFCHR;
} else { } else {
ret |= S_IFBLK; ret |= S_IFBLK;