static void restore_context(const struct prev_root *prev_root, const struct cred *old_cred) { chroot_to_prev_root(prev_root); revert_creds(old_cred); }
static int unpack_root_pwd(struct rpc_desc *desc, struct prev_root *prev_root) { struct path root, pwd, tmp_root, tmp_pwd; int err; chroot_to_physical_root(prev_root); err = unpack_path(desc, &root); if (err) goto out_err; err = unpack_path(desc, &pwd); if (err) goto out_err_pwd; write_lock(¤t->fs->lock); tmp_root = current->fs->root; current->fs->root = root; tmp_pwd = current->fs->pwd; current->fs->pwd = pwd; write_unlock(¤t->fs->lock); path_put(&tmp_root); path_put(&tmp_pwd); return err; out_err_pwd: path_put(&root); out_err: chroot_to_prev_root(prev_root); return err; }
struct file *open_physical_file (char *filename, int flags, int mode, uid_t fsuid, gid_t fsgid) { const struct cred *old_cred; struct cred *override_cred; struct prev_root prev_root; struct file *file; override_cred = prepare_creds(); if (!override_cred) return ERR_PTR(-ENOMEM); override_cred->fsuid = fsuid; override_cred->fsgid = fsgid; old_cred = override_creds(override_cred); chroot_to_physical_root(&prev_root); file = filp_open (filename, flags, mode); chroot_to_prev_root(&prev_root); revert_creds(old_cred); put_cred(override_cred); return file; }
int handle_faf_getpeername (struct rpc_desc* desc, void *msgIn, size_t size) { struct faf_bind_msg *msg = msgIn; struct prev_root prev_root; int r; unpack_root(desc, &prev_root); r = sys_getpeername(msg->server_fd, (struct sockaddr *)&msg->sa, &msg->addrlen); rpc_pack_type(desc, msg->addrlen); rpc_pack(desc, 0, &msg->sa, msg->addrlen); chroot_to_prev_root(&prev_root); return r; }
static int unpack_root(struct rpc_desc *desc, struct prev_root *prev_root) { struct path root, tmp_root; int err; chroot_to_physical_root(prev_root); err = unpack_path(desc, &root); if (err) { chroot_to_prev_root(prev_root); return err; } write_lock(¤t->fs->lock); tmp_root = current->fs->root; current->fs->root = root; write_unlock(¤t->fs->lock); path_put(&tmp_root); return err; }
/** Handler for d_path in a FAF open file. * @author Renaud Lottiaux * * @param from Node sending the request * @param msgIn Request message */ void handle_faf_d_path (struct rpc_desc* desc, void *msgIn, size_t size) { struct faf_d_path_msg *msg = msgIn; char *buff, *file_name = NULL; struct file *file; struct prev_root prev_root; const struct cred *old_cred; bool deleted = false; int len; int err; old_cred = unpack_override_creds(desc); if (IS_ERR(old_cred)) { rpc_cancel(desc); return; } err = unpack_root(desc, &prev_root); if (err) { revert_creds(old_cred); rpc_cancel(desc); return; } buff = kmalloc (msg->count, GFP_KERNEL); file = fcheck_files (current->files, msg->server_fd); /* Remote caller holds a reference so it can't disappear. */ BUG_ON(!file); if (msg->deleted) file_name = d_path_check(&file->f_path, buff, msg->count, &deleted); else file_name = d_path(&file->f_path, buff, msg->count); if (IS_ERR(file_name)) len = PTR_ERR(file_name); else len = strlen(file_name) + 1; err = rpc_pack_type(desc, len); if (err) goto err_cancel; if (len >= 0) { err = rpc_pack(desc, 0, file_name, len); if (err) goto err_cancel; if (msg->deleted) { err = rpc_pack_type(desc, deleted); if (err) goto err_cancel; } } out: kfree (buff); chroot_to_prev_root(&prev_root); revert_creds(old_cred); return; err_cancel: rpc_cancel(desc); goto out; }
/** Create a new file ghost. * @author Renaud Lottiaux, Matthieu Fertré * * @param access Ghost access (READ/WRITE) * @param file File to read/write data to/from. * * @return ghost_t if everything ok * ERR_PTR otherwise. */ ghost_t *create_file_ghost(int access, long app_id, unsigned int chkpt_sn, const char *format, ...) { struct file *file; va_list args; char *filename; struct prev_root prev_root; ghost_t *ghost; int r; chroot_to_physical_root(&prev_root); /* Create directory if not exist */ if (access & GHOST_WRITE) { r = mkdir_chkpt_path(app_id, chkpt_sn); if (r) goto err; } /* Create a ghost to host the checkpoint */ va_start(args, format); filename = __get_chkpt_filebase(app_id, chkpt_sn, format, args); va_end(args); if (IS_ERR(filename)) { r = PTR_ERR(filename); goto err; } if (access & GHOST_WRITE)/* fail if already exists */ file = filp_open(filename, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR); else file = filp_open(filename, O_RDONLY, S_IRWXU); kfree(filename); if (IS_ERR(file)) { r = PTR_ERR(file); goto err; } /* Create a ghost to host the checkoint */ ghost = __create_file_ghost(access, file, 0); if (IS_ERR(ghost)) { r = PTR_ERR(ghost); goto err_file; } out: chroot_to_prev_root(&prev_root); return ghost; err_file: filp_close(file, current->files); err: ghost = ERR_PTR(r); goto out; }