Added permission checks for chmod, link, rename and chown
Those clearly need to ask for permissions.
This commit is contained in:
parent
6342de0dd3
commit
da37376fde
@ -108,7 +108,29 @@ static int xmp_getattr(const char *path, struct stat *stbuf,
|
|||||||
static int xmp_access(const char *path, int mask) {
|
static int xmp_access(const char *path, int mask) {
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
res = access(path, mask);
|
// if mask is F_OK, then we don't need to check the permissions
|
||||||
|
// (is that possible?)
|
||||||
|
|
||||||
|
if (mask != F_OK) {
|
||||||
|
struct process_info pi;
|
||||||
|
struct fuse_context *fc = fuse_get_context();
|
||||||
|
|
||||||
|
pi.PID = fc->pid;
|
||||||
|
pi.UID = fc->uid;
|
||||||
|
pi.name = get_process_name_by_pid(pi.PID);
|
||||||
|
|
||||||
|
// fprintf(stderr, "%s, %d\n", path, ask_access(path, pi));
|
||||||
|
|
||||||
|
if (!interactive_access(real_filename(path), pi)) {
|
||||||
|
free(pi.name);
|
||||||
|
return -EACCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(pi.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
res = source_access(path, mask);
|
||||||
|
|
||||||
if (res == -1)
|
if (res == -1)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
@ -304,6 +326,30 @@ static int xmp_rename(const char *from, const char *to, unsigned int flags) {
|
|||||||
if (flags)
|
if (flags)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
struct process_info pi;
|
||||||
|
struct fuse_context *fc = fuse_get_context();
|
||||||
|
|
||||||
|
pi.PID = fc->pid;
|
||||||
|
pi.UID = fc->uid;
|
||||||
|
pi.name = get_process_name_by_pid(pi.PID);
|
||||||
|
|
||||||
|
// fprintf(stderr, "%s, %d\n", path, ask_access(path, pi));
|
||||||
|
|
||||||
|
if (!interactive_access(real_filename(from), pi)) {
|
||||||
|
free(pi.name);
|
||||||
|
return -EACCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the "to" file may exist and the process needs to get persmission to modify
|
||||||
|
// it
|
||||||
|
if (source_access(to, F_OK) == 0 &&
|
||||||
|
!interactive_access(real_filename(to), pi)) {
|
||||||
|
free(pi.name);
|
||||||
|
return -EACCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(pi.name);
|
||||||
|
|
||||||
res = source_rename(from, to);
|
res = source_rename(from, to);
|
||||||
if (res == -1)
|
if (res == -1)
|
||||||
return -errno;
|
return -errno;
|
||||||
@ -313,6 +359,22 @@ static int xmp_rename(const char *from, const char *to, unsigned int flags) {
|
|||||||
|
|
||||||
static int xmp_link(const char *from, const char *to) {
|
static int xmp_link(const char *from, const char *to) {
|
||||||
int res;
|
int res;
|
||||||
|
struct process_info pi;
|
||||||
|
struct fuse_context *fc = fuse_get_context();
|
||||||
|
|
||||||
|
pi.PID = fc->pid;
|
||||||
|
pi.UID = fc->uid;
|
||||||
|
pi.name = get_process_name_by_pid(pi.PID);
|
||||||
|
|
||||||
|
// fprintf(stderr, "%s, %d\n", path, ask_access(path, pi));
|
||||||
|
if (!interactive_access(real_filename(from), pi)) {
|
||||||
|
free(pi.name);
|
||||||
|
return -EACCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
// no need to check the access to the "to" file, see link(2)
|
||||||
|
|
||||||
|
free(pi.name);
|
||||||
|
|
||||||
res = source_link(from, to);
|
res = source_link(from, to);
|
||||||
if (res == -1)
|
if (res == -1)
|
||||||
@ -323,6 +385,20 @@ static int xmp_link(const char *from, const char *to) {
|
|||||||
|
|
||||||
static int xmp_chmod(const char *path, mode_t mode, struct fuse_file_info *fi) {
|
static int xmp_chmod(const char *path, mode_t mode, struct fuse_file_info *fi) {
|
||||||
int res;
|
int res;
|
||||||
|
struct process_info pi;
|
||||||
|
struct fuse_context *fc = fuse_get_context();
|
||||||
|
|
||||||
|
pi.PID = fc->pid;
|
||||||
|
pi.UID = fc->uid;
|
||||||
|
pi.name = get_process_name_by_pid(pi.PID);
|
||||||
|
|
||||||
|
// fprintf(stderr, "%s, %d\n", path, ask_access(path, pi));
|
||||||
|
if (!interactive_access(real_filename(path), pi)) {
|
||||||
|
free(pi.name);
|
||||||
|
return -EACCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(pi.name);
|
||||||
|
|
||||||
if (fi)
|
if (fi)
|
||||||
res = fchmod(fi->fh, mode);
|
res = fchmod(fi->fh, mode);
|
||||||
@ -334,9 +410,27 @@ static int xmp_chmod(const char *path, mode_t mode, struct fuse_file_info *fi) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This filesystem is not designed for multiuser operation (e.g. with
|
||||||
|
* allow_other) so there is little point in having chown implemnted
|
||||||
|
*/
|
||||||
static int xmp_chown(const char *path, uid_t uid, gid_t gid,
|
static int xmp_chown(const char *path, uid_t uid, gid_t gid,
|
||||||
struct fuse_file_info *fi) {
|
struct fuse_file_info *fi) {
|
||||||
int res;
|
int res;
|
||||||
|
struct process_info pi;
|
||||||
|
struct fuse_context *fc = fuse_get_context();
|
||||||
|
|
||||||
|
pi.PID = fc->pid;
|
||||||
|
pi.UID = fc->uid;
|
||||||
|
pi.name = get_process_name_by_pid(pi.PID);
|
||||||
|
|
||||||
|
// fprintf(stderr, "%s, %d\n", path, ask_access(path, pi));
|
||||||
|
if (!interactive_access(real_filename(path), pi)) {
|
||||||
|
free(pi.name);
|
||||||
|
return -EACCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(pi.name);
|
||||||
|
|
||||||
if (fi)
|
if (fi)
|
||||||
res = fchown(fi->fh, uid, gid);
|
res = fchown(fi->fh, uid, gid);
|
||||||
@ -660,7 +754,7 @@ static off_t xmp_lseek(const char *path, off_t off, int whence,
|
|||||||
static const struct fuse_operations xmp_oper = {
|
static const struct fuse_operations xmp_oper = {
|
||||||
.init = xmp_init,
|
.init = xmp_init,
|
||||||
.getattr = xmp_getattr,
|
.getattr = xmp_getattr,
|
||||||
// .access = xmp_access,
|
.access = xmp_access,
|
||||||
.readlink = xmp_readlink,
|
.readlink = xmp_readlink,
|
||||||
.opendir = xmp_opendir,
|
.opendir = xmp_opendir,
|
||||||
.readdir = xmp_readdir,
|
.readdir = xmp_readdir,
|
||||||
|
@ -66,6 +66,11 @@ int source_symlink(const char *target, const char *linkpath) {
|
|||||||
return symlinkat(target, handle.root_fd, relative_linkpath);
|
return symlinkat(target, handle.root_fd, relative_linkpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int source_access(const char *filename, int mode) {
|
||||||
|
const char *relative_filename = source_filename_translate(filename);
|
||||||
|
return faccessat(handle.root_fd, relative_filename, mode, 0);
|
||||||
|
}
|
||||||
|
|
||||||
DIR *source_opendir(const char *filename) {
|
DIR *source_opendir(const char *filename) {
|
||||||
const char *relative_filename = source_filename_translate(filename);
|
const char *relative_filename = source_filename_translate(filename);
|
||||||
int fd = openat(handle.root_fd, relative_filename, 0);
|
int fd = openat(handle.root_fd, relative_filename, 0);
|
||||||
|
@ -47,6 +47,8 @@ int source_chown(const char *filename, uid_t owner, gid_t group);
|
|||||||
|
|
||||||
int source_truncate(const char *filename, off_t length);
|
int source_truncate(const char *filename, off_t length);
|
||||||
|
|
||||||
|
int source_access(const char *filename, int mode);
|
||||||
|
|
||||||
/* `open` and `create` are designed to correspond to fuse operations, not the
|
/* `open` and `create` are designed to correspond to fuse operations, not the
|
||||||
* libc's `open(2)`. Both of them actually call `openat`. */
|
* libc's `open(2)`. Both of them actually call `openat`. */
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user