Added permission checks for chmod, link, rename and chown
Those clearly need to ask for permissions.
This commit is contained in:
		@@ -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,
 | 
				
			||||||
@@ -676,7 +770,7 @@ static const struct fuse_operations xmp_oper = {
 | 
				
			|||||||
    .chown = xmp_chown,
 | 
					    .chown = xmp_chown,
 | 
				
			||||||
    .truncate = xmp_truncate,
 | 
					    .truncate = xmp_truncate,
 | 
				
			||||||
#ifdef HAVE_UTIMENSAT
 | 
					#ifdef HAVE_UTIMENSAT
 | 
				
			||||||
// .utimens = xmp_utimens,
 | 
					//  .utimens = xmp_utimens,
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
    .create = xmp_create,
 | 
					    .create = xmp_create,
 | 
				
			||||||
    .open = xmp_open,
 | 
					    .open = xmp_open,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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`. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user