hw/9pfs: Use O_NOFOLLOW when opening files on server

9p server should never follow a symlink. So use O_NOFOLLOW with all open
syscall

Tested-by: "M. Mohan Kumar" <mohan@in.ibm.com>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
This commit is contained in:
Aneesh Kumar K.V 2013-05-20 19:43:15 +05:30
parent aed858ce10
commit 0ceb092e35
1 changed files with 41 additions and 7 deletions

View File

@ -59,6 +59,33 @@ static const char *local_mapped_attr_path(FsContext *ctx,
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
static void local_mapped_file_attr(FsContext *ctx, const char *path,
struct stat *stbuf)
@ -68,7 +95,7 @@ static void local_mapped_file_attr(FsContext *ctx, const char *path,
char attr_path[PATH_MAX];
local_mapped_attr_path(ctx, path, attr_path);
fp = fopen(attr_path, "r");
fp = local_fopen(attr_path, "r");
if (!fp) {
return;
}
@ -152,7 +179,7 @@ static int local_set_mapped_file_attr(FsContext *ctx,
char attr_path[PATH_MAX];
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) {
goto create_map_file;
}
@ -179,7 +206,7 @@ create_map_file:
}
update_map_file:
fp = fopen(attr_path, "w");
fp = local_fopen(attr_path, "w");
if (!fp) {
ret = -1;
goto err_out;
@ -316,7 +343,7 @@ static int local_open(FsContext *ctx, V9fsPath *fs_path,
char buffer[PATH_MAX];
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;
}
@ -601,6 +628,11 @@ static int local_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name,
V9fsString fullname;
char buffer[PATH_MAX];
/*
* Mark all the open to not follow symlinks
*/
flags |= O_NOFOLLOW;
v9fs_string_init(&fullname);
v9fs_string_sprintf(&fullname, "%s/%s", dir_path->data, name);
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) {
int fd;
ssize_t oldpath_size, write_size;
fd = open(rpath(fs_ctx, newpath, buffer), O_CREAT|O_EXCL|O_RDWR,
SM_LOCAL_MODE_BITS);
fd = open(rpath(fs_ctx, newpath, buffer),
O_CREAT|O_EXCL|O_RDWR|O_NOFOLLOW,
SM_LOCAL_MODE_BITS);
if (fd == -1) {
err = fd;
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) {
int fd;
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);
if (fd == -1) {
err = fd;