Merge branch 'for-ovl' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs into overlayfs-next

This gives us the open_with_fake_path() helper that is needed for stacked
open files in overlay and mmap in particular.
This commit is contained in:
Miklos Szeredi 2018-07-18 10:46:05 +02:00
commit 9951934d76
26 changed files with 137 additions and 183 deletions

View file

@ -553,24 +553,13 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev,
/* Clone the lessor file to create a new file for us */
DRM_DEBUG_LEASE("Allocating lease file\n");
path_get(&lessor_file->f_path);
lessee_file = alloc_file(&lessor_file->f_path,
lessor_file->f_mode,
fops_get(lessor_file->f_inode->i_fop));
lessee_file = file_clone_open(lessor_file);
if (IS_ERR(lessee_file)) {
ret = PTR_ERR(lessee_file);
goto out_lessee;
}
/* Initialize the new file for DRM */
DRM_DEBUG_LEASE("Initializing the file with %p\n", lessee_file->f_op->open);
ret = lessee_file->f_op->open(lessee_file->f_inode, lessee_file);
if (ret)
goto out_lessee_file;
lessee_priv = lessee_file->private_data;
/* Change the file to a master one */
drm_master_put(&lessee_priv->master);
lessee_priv->master = lessee;
@ -588,9 +577,6 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev,
DRM_DEBUG_LEASE("drm_mode_create_lease_ioctl succeeded\n");
return 0;
out_lessee_file:
fput(lessee_file);
out_lessee:
drm_master_put(&lessee);

View file

@ -102,16 +102,15 @@ static struct file *cxl_getfile(const char *name,
path.mnt = mntget(cxl_vfs_mount);
d_instantiate(path.dentry, inode);
file = alloc_file(&path, OPEN_FMODE(flags), fops);
if (IS_ERR(file))
goto err_dput;
file->f_flags = flags & (O_ACCMODE | O_NONBLOCK);
file = alloc_file(&path, flags & (O_ACCMODE | O_NONBLOCK), fops);
if (IS_ERR(file)) {
path_put(&path);
goto err_fs;
}
file->private_data = priv;
return file;
err_dput:
path_put(&path);
err_inode:
iput(inode);
err_fs:

View file

@ -129,20 +129,18 @@ static struct file *ocxlflash_getfile(struct device *dev, const char *name,
path.mnt = mntget(ocxlflash_vfs_mount);
d_instantiate(path.dentry, inode);
file = alloc_file(&path, OPEN_FMODE(flags), fops);
file = alloc_file(&path, flags & (O_ACCMODE | O_NONBLOCK), fops);
if (IS_ERR(file)) {
rc = PTR_ERR(file);
dev_err(dev, "%s: alloc_file failed rc=%d\n",
__func__, rc);
goto err5;
path_put(&path);
goto err3;
}
file->f_flags = flags & (O_ACCMODE | O_NONBLOCK);
file->private_data = priv;
out:
return file;
err5:
path_put(&path);
err4:
iput(inode);
err3:

View file

@ -234,13 +234,9 @@ static struct file *aio_private_file(struct kioctx *ctx, loff_t nr_pages)
path.mnt = mntget(aio_mnt);
d_instantiate(path.dentry, inode);
file = alloc_file(&path, FMODE_READ | FMODE_WRITE, &aio_ring_fops);
if (IS_ERR(file)) {
file = alloc_file(&path, O_RDWR, &aio_ring_fops);
if (IS_ERR(file))
path_put(&path);
return file;
}
file->f_flags = O_RDWR;
return file;
}

View file

@ -102,12 +102,11 @@ struct file *anon_inode_getfile(const char *name,
d_instantiate(path.dentry, anon_inode_inode);
file = alloc_file(&path, OPEN_FMODE(flags), fops);
file = alloc_file(&path, flags & (O_ACCMODE | O_NONBLOCK), fops);
if (IS_ERR(file))
goto err_dput;
file->f_mapping = anon_inode_inode->i_mapping;
file->f_flags = flags & (O_ACCMODE | O_NONBLOCK);
file->private_data = priv;
return file;

View file

@ -205,7 +205,7 @@ static int load_misc_binary(struct linux_binprm *bprm)
goto error;
if (fmt->flags & MISC_FMT_OPEN_FILE) {
interp_file = filp_clone_open(fmt->interp_file);
interp_file = file_clone_open(fmt->interp_file);
if (!IS_ERR(interp_file))
deny_write_access(interp_file);
} else {

View file

@ -51,6 +51,7 @@ static void file_free_rcu(struct rcu_head *head)
static inline void file_free(struct file *f)
{
security_file_free(f);
percpu_counter_dec(&nr_files);
call_rcu(&f->f_u.fu_rcuhead, file_free_rcu);
}
@ -100,9 +101,8 @@ int proc_nr_files(struct ctl_table *table, int write,
* done, you will imbalance int the mount's writer count
* and a warning at __fput() time.
*/
struct file *get_empty_filp(void)
struct file *alloc_empty_file(int flags, const struct cred *cred)
{
const struct cred *cred = current_cred();
static long old_max;
struct file *f;
int error;
@ -123,11 +123,10 @@ struct file *get_empty_filp(void)
if (unlikely(!f))
return ERR_PTR(-ENOMEM);
percpu_counter_inc(&nr_files);
f->f_cred = get_cred(cred);
error = security_file_alloc(f);
if (unlikely(error)) {
file_free(f);
file_free_rcu(&f->f_u.fu_rcuhead);
return ERR_PTR(error);
}
@ -136,7 +135,10 @@ struct file *get_empty_filp(void)
spin_lock_init(&f->f_lock);
mutex_init(&f->f_pos_lock);
eventpoll_init_file(f);
f->f_flags = flags;
f->f_mode = OPEN_FMODE(flags);
/* f->f_version: 0 */
percpu_counter_inc(&nr_files);
return f;
over:
@ -152,15 +154,15 @@ struct file *get_empty_filp(void)
* alloc_file - allocate and initialize a 'struct file'
*
* @path: the (dentry, vfsmount) pair for the new file
* @mode: the mode with which the new file will be opened
* @flags: O_... flags with which the new file will be opened
* @fop: the 'struct file_operations' for the new file
*/
struct file *alloc_file(const struct path *path, fmode_t mode,
struct file *alloc_file(const struct path *path, int flags,
const struct file_operations *fop)
{
struct file *file;
file = get_empty_filp();
file = alloc_empty_file(flags, current_cred());
if (IS_ERR(file))
return file;
@ -168,15 +170,15 @@ struct file *alloc_file(const struct path *path, fmode_t mode,
file->f_inode = path->dentry->d_inode;
file->f_mapping = path->dentry->d_inode->i_mapping;
file->f_wb_err = filemap_sample_wb_err(file->f_mapping);
if ((mode & FMODE_READ) &&
if ((file->f_mode & FMODE_READ) &&
likely(fop->read || fop->read_iter))
mode |= FMODE_CAN_READ;
if ((mode & FMODE_WRITE) &&
file->f_mode |= FMODE_CAN_READ;
if ((file->f_mode & FMODE_WRITE) &&
likely(fop->write || fop->write_iter))
mode |= FMODE_CAN_WRITE;
file->f_mode = mode;
file->f_mode |= FMODE_CAN_WRITE;
file->f_mode |= FMODE_OPENED;
file->f_op = fop;
if ((mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
if ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
i_readcount_inc(path->dentry->d_inode);
return file;
}
@ -190,6 +192,9 @@ static void __fput(struct file *file)
struct vfsmount *mnt = file->f_path.mnt;
struct inode *inode = file->f_inode;
if (unlikely(!(file->f_mode & FMODE_OPENED)))
goto out;
might_sleep();
fsnotify_close(file);
@ -207,7 +212,6 @@ static void __fput(struct file *file)
}
if (file->f_op->release)
file->f_op->release(inode, file);
security_file_free(file);
if (unlikely(S_ISCHR(inode->i_mode) && inode->i_cdev != NULL &&
!(file->f_mode & FMODE_PATH))) {
cdev_put(inode->i_cdev);
@ -220,12 +224,10 @@ static void __fput(struct file *file)
put_write_access(inode);
__mnt_drop_write(mnt);
}
file->f_path.dentry = NULL;
file->f_path.mnt = NULL;
file->f_inode = NULL;
file_free(file);
dput(dentry);
mntput(mnt);
out:
file_free(file);
}
static LLIST_HEAD(delayed_fput_list);
@ -300,14 +302,6 @@ void __fput_sync(struct file *file)
EXPORT_SYMBOL(fput);
void put_filp(struct file *file)
{
if (atomic_long_dec_and_test(&file->f_count)) {
security_file_free(file);
file_free(file);
}
}
void __init files_init(void)
{
filp_cachep = kmem_cache_create("filp", sizeof(struct file), 0,

View file

@ -1375,8 +1375,7 @@ struct file *hugetlb_file_setup(const char *name, size_t size,
inode->i_size = size;
clear_nlink(inode);
file = alloc_file(&path, FMODE_WRITE | FMODE_READ,
&hugetlbfs_file_operations);
file = alloc_file(&path, O_RDWR, &hugetlbfs_file_operations);
if (IS_ERR(file))
goto out_dentry; /* inode is already attached */

View file

@ -93,7 +93,7 @@ extern void chroot_fs_refs(const struct path *, const struct path *);
/*
* file_table.c
*/
extern struct file *get_empty_filp(void);
extern struct file *alloc_empty_file(int, const struct cred *);
/*
* super.c
@ -125,9 +125,7 @@ int do_fchmodat(int dfd, const char __user *filename, umode_t mode);
int do_fchownat(int dfd, const char __user *filename, uid_t user, gid_t group,
int flag);
extern int open_check_o_direct(struct file *f);
extern int vfs_open(const struct path *, struct file *, const struct cred *);
extern struct file *filp_clone_open(struct file *);
extern int vfs_open(const struct path *, struct file *);
/*
* inode.c

View file

@ -3396,19 +3396,15 @@ static int do_last(struct nameidata *nd,
if (error)
goto out;
BUG_ON(*opened & FILE_OPENED); /* once it's opened, it's opened */
error = vfs_open(&nd->path, file, current_cred());
error = vfs_open(&nd->path, file);
if (error)
goto out;
*opened |= FILE_OPENED;
opened:
error = open_check_o_direct(file);
if (!error)
error = ima_file_check(file, op->acc_mode, *opened);
error = ima_file_check(file, op->acc_mode, *opened);
if (!error && will_truncate)
error = handle_truncate(file);
out:
if (unlikely(error) && (*opened & FILE_OPENED))
fput(file);
if (unlikely(error > 0)) {
WARN_ON(1);
error = -EINVAL;
@ -3481,11 +3477,6 @@ static int do_tmpfile(struct nameidata *nd, unsigned flags,
goto out2;
file->f_path.mnt = path.mnt;
error = finish_open(file, child, NULL, opened);
if (error)
goto out2;
error = open_check_o_direct(file);
if (error)
fput(file);
out2:
mnt_drop_write(path.mnt);
out:
@ -3499,7 +3490,7 @@ static int do_o_path(struct nameidata *nd, unsigned flags, struct file *file)
int error = path_lookupat(nd, flags, &path);
if (!error) {
audit_inode(nd->name, path.dentry, 0);
error = vfs_open(&path, file, current_cred());
error = vfs_open(&path, file);
path_put(&path);
}
return error;
@ -3513,12 +3504,10 @@ static struct file *path_openat(struct nameidata *nd,
int opened = 0;
int error;
file = get_empty_filp();
file = alloc_empty_file(op->open_flag, current_cred());
if (IS_ERR(file))
return file;
file->f_flags = op->open_flag;
if (unlikely(file->f_flags & __O_TMPFILE)) {
error = do_tmpfile(nd, flags, op, file, &opened);
goto out2;
@ -3533,7 +3522,7 @@ static struct file *path_openat(struct nameidata *nd,
s = path_init(nd, flags);
if (IS_ERR(s)) {
put_filp(file);
fput(file);
return ERR_CAST(s);
}
while (!(error = link_path_walk(s, nd)) &&
@ -3547,20 +3536,20 @@ static struct file *path_openat(struct nameidata *nd,
}
terminate_walk(nd);
out2:
if (!(opened & FILE_OPENED)) {
BUG_ON(!error);
put_filp(file);
if (likely(!error)) {
if (likely(opened & FILE_OPENED))
return file;
WARN_ON(1);
error = -EINVAL;
}
if (unlikely(error)) {
if (error == -EOPENSTALE) {
if (flags & LOOKUP_RCU)
error = -ECHILD;
else
error = -ESTALE;
}
file = ERR_PTR(error);
fput(file);
if (error == -EOPENSTALE) {
if (flags & LOOKUP_RCU)
error = -ECHILD;
else
error = -ESTALE;
}
return file;
return ERR_PTR(error);
}
struct file *do_filp_open(int dfd, struct filename *pathname,

View file

@ -724,27 +724,13 @@ SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group)
return ksys_fchown(fd, user, group);
}
int open_check_o_direct(struct file *f)
{
/* NB: we're sure to have correct a_ops only after f_op->open */
if (f->f_flags & O_DIRECT) {
if (!f->f_mapping->a_ops || !f->f_mapping->a_ops->direct_IO)
return -EINVAL;
}
return 0;
}
static int do_dentry_open(struct file *f,
struct inode *inode,
int (*open)(struct inode *, struct file *),
const struct cred *cred)
int (*open)(struct inode *, struct file *))
{
static const struct file_operations empty_fops = {};
int error;
f->f_mode = OPEN_FMODE(f->f_flags) | FMODE_LSEEK |
FMODE_PREAD | FMODE_PWRITE;
path_get(&f->f_path);
f->f_inode = inode;
f->f_mapping = inode->i_mapping;
@ -753,7 +739,7 @@ static int do_dentry_open(struct file *f,
f->f_wb_err = filemap_sample_wb_err(f->f_mapping);
if (unlikely(f->f_flags & O_PATH)) {
f->f_mode = FMODE_PATH;
f->f_mode = FMODE_PATH | FMODE_OPENED;
f->f_op = &empty_fops;
return 0;
}
@ -780,7 +766,7 @@ static int do_dentry_open(struct file *f,
goto cleanup_all;
}
error = security_file_open(f, cred);
error = security_file_open(f);
if (error)
goto cleanup_all;
@ -788,6 +774,8 @@ static int do_dentry_open(struct file *f,
if (error)
goto cleanup_all;
/* normally all 3 are set; ->open() can clear them if needed */
f->f_mode |= FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE;
if (!open)
open = f->f_op->open;
if (open) {
@ -795,6 +783,7 @@ static int do_dentry_open(struct file *f,
if (error)
goto cleanup_all;
}
f->f_mode |= FMODE_OPENED;
if ((f->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
i_readcount_inc(inode);
if ((f->f_mode & FMODE_READ) &&
@ -809,9 +798,16 @@ static int do_dentry_open(struct file *f,
file_ra_state_init(&f->f_ra, f->f_mapping->host->i_mapping);
/* NB: we're sure to have correct a_ops only after f_op->open */
if (f->f_flags & O_DIRECT) {
if (!f->f_mapping->a_ops || !f->f_mapping->a_ops->direct_IO)
return -EINVAL;
}
return 0;
cleanup_all:
if (WARN_ON_ONCE(error > 0))
error = -EINVAL;
fops_put(f->f_op);
if (f->f_mode & FMODE_WRITER) {
put_write_access(inode);
@ -854,8 +850,7 @@ int finish_open(struct file *file, struct dentry *dentry,
BUG_ON(*opened & FILE_OPENED); /* once it's opened, it's opened */
file->f_path.dentry = dentry;
error = do_dentry_open(file, d_backing_inode(dentry), open,
current_cred());
error = do_dentry_open(file, d_backing_inode(dentry), open);
if (!error)
*opened |= FILE_OPENED;
@ -896,8 +891,7 @@ EXPORT_SYMBOL(file_path);
* @file: newly allocated file with f_flag initialized
* @cred: credentials to use
*/
int vfs_open(const struct path *path, struct file *file,
const struct cred *cred)
int vfs_open(const struct path *path, struct file *file)
{
struct dentry *dentry = d_real(path->dentry, NULL, file->f_flags, 0);
@ -905,7 +899,7 @@ int vfs_open(const struct path *path, struct file *file,
return PTR_ERR(dentry);
file->f_path = *path;
return do_dentry_open(file, d_backing_inode(dentry), NULL, cred);
return do_dentry_open(file, d_backing_inode(dentry), NULL);
}
struct file *dentry_open(const struct path *path, int flags,
@ -919,19 +913,11 @@ struct file *dentry_open(const struct path *path, int flags,
/* We must always pass in a valid mount pointer. */
BUG_ON(!path->mnt);
f = get_empty_filp();
f = alloc_empty_file(flags, cred);
if (!IS_ERR(f)) {
f->f_flags = flags;
error = vfs_open(path, f, cred);
if (!error) {
/* from now on we need fput() to dispose of f */
error = open_check_o_direct(f);
if (error) {
fput(f);
f = ERR_PTR(error);
}
} else {
put_filp(f);
error = vfs_open(path, f);
if (error) {
fput(f);
f = ERR_PTR(error);
}
}
@ -939,6 +925,24 @@ struct file *dentry_open(const struct path *path, int flags,
}
EXPORT_SYMBOL(dentry_open);
struct file *open_with_fake_path(const struct path *path, int flags,
struct inode *inode, const struct cred *cred)
{
struct file *f = alloc_empty_file(flags, cred);
if (!IS_ERR(f)) {
int error;
f->f_path = *path;
error = do_dentry_open(f, inode, NULL);
if (error) {
fput(f);
f = ERR_PTR(error);
}
}
return f;
}
EXPORT_SYMBOL(open_with_fake_path);
static inline int build_open_flags(int flags, umode_t mode, struct open_flags *op)
{
int lookup_flags = 0;
@ -1063,26 +1067,6 @@ struct file *file_open_root(struct dentry *dentry, struct vfsmount *mnt,
}
EXPORT_SYMBOL(file_open_root);
struct file *filp_clone_open(struct file *oldfile)
{
struct file *file;
int retval;
file = get_empty_filp();
if (IS_ERR(file))
return file;
file->f_flags = oldfile->f_flags;
retval = vfs_open(&oldfile->f_path, file, oldfile->f_cred);
if (retval) {
put_filp(file);
return ERR_PTR(retval);
}
return file;
}
EXPORT_SYMBOL(filp_clone_open);
long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode)
{
struct open_flags op;

View file

@ -760,29 +760,28 @@ int create_pipe_files(struct file **res, int flags)
d_instantiate(path.dentry, inode);
f = alloc_file(&path, FMODE_WRITE, &pipefifo_fops);
f = alloc_file(&path, O_WRONLY | (flags & (O_NONBLOCK | O_DIRECT)),
&pipefifo_fops);
if (IS_ERR(f)) {
err = PTR_ERR(f);
goto err_dentry;
}
f->f_flags = O_WRONLY | (flags & (O_NONBLOCK | O_DIRECT));
f->private_data = inode->i_pipe;
res[0] = alloc_file(&path, FMODE_READ, &pipefifo_fops);
res[0] = alloc_file(&path, O_RDONLY | (flags & O_NONBLOCK),
&pipefifo_fops);
if (IS_ERR(res[0])) {
err = PTR_ERR(res[0]);
goto err_file;
put_pipe_info(inode, inode->i_pipe);
fput(f);
return PTR_ERR(res[0]);
}
path_get(&path);
res[0]->private_data = inode->i_pipe;
res[0]->f_flags = O_RDONLY | (flags & O_NONBLOCK);
res[1] = f;
return 0;
err_file:
put_filp(f);
err_dentry:
free_pipe_info(inode->i_pipe);
path_put(&path);

View file

@ -564,11 +564,20 @@ static int proc_seq_open(struct inode *inode, struct file *file)
return seq_open(file, de->seq_ops);
}
static int proc_seq_release(struct inode *inode, struct file *file)
{
struct proc_dir_entry *de = PDE(inode);
if (de->state_size)
return seq_release_private(inode, file);
return seq_release(inode, file);
}
static const struct file_operations proc_seq_fops = {
.open = proc_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
.release = proc_seq_release,
};
struct proc_dir_entry *proc_create_seq_private(const char *name, umode_t mode,

View file

@ -18,7 +18,7 @@ struct file_operations;
struct vfsmount;
struct dentry;
struct path;
extern struct file *alloc_file(const struct path *, fmode_t mode,
extern struct file *alloc_file(const struct path *, int flags,
const struct file_operations *fop);
static inline void fput_light(struct file *file, int fput_needed)
@ -78,7 +78,6 @@ extern int f_dupfd(unsigned int from, struct file *file, unsigned flags);
extern int replace_fd(unsigned fd, struct file *file, unsigned flags);
extern void set_close_on_exec(unsigned int fd, int flag);
extern bool get_close_on_exec(unsigned int fd);
extern void put_filp(struct file *);
extern int get_unused_fd_flags(unsigned flags);
extern void put_unused_fd(unsigned int fd);

View file

@ -148,6 +148,8 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
/* Has write method(s) */
#define FMODE_CAN_WRITE ((__force fmode_t)0x40000)
#define FMODE_OPENED ((__force fmode_t)0x80000)
/* File was opened by fanotify and shouldn't generate fanotify events */
#define FMODE_NONOTIFY ((__force fmode_t)0x4000000)
@ -2422,6 +2424,12 @@ extern struct file *filp_open(const char *, int, umode_t);
extern struct file *file_open_root(struct dentry *, struct vfsmount *,
const char *, int, umode_t);
extern struct file * dentry_open(const struct path *, int, const struct cred *);
extern struct file * open_with_fake_path(const struct path *, int,
struct inode*, const struct cred *);
static inline struct file *file_clone_open(struct file *file)
{
return dentry_open(&file->f_path, file->f_flags, file->f_cred);
}
extern int filp_close(struct file *, fl_owner_t id);
extern struct filename *getname_flags(const char __user *, int, int *);

View file

@ -1569,7 +1569,7 @@ union security_list_options {
int (*file_send_sigiotask)(struct task_struct *tsk,
struct fown_struct *fown, int sig);
int (*file_receive)(struct file *file);
int (*file_open)(struct file *file, const struct cred *cred);
int (*file_open)(struct file *file);
int (*task_alloc)(struct task_struct *task, unsigned long clone_flags);
void (*task_free)(struct task_struct *task);

View file

@ -309,7 +309,7 @@ void security_file_set_fowner(struct file *file);
int security_file_send_sigiotask(struct task_struct *tsk,
struct fown_struct *fown, int sig);
int security_file_receive(struct file *file);
int security_file_open(struct file *file, const struct cred *cred);
int security_file_open(struct file *file);
int security_task_alloc(struct task_struct *task, unsigned long clone_flags);
void security_task_free(struct task_struct *task);
int security_cred_alloc_blank(struct cred *cred, gfp_t gfp);
@ -858,8 +858,7 @@ static inline int security_file_receive(struct file *file)
return 0;
}
static inline int security_file_open(struct file *file,
const struct cred *cred)
static inline int security_file_open(struct file *file)
{
return 0;
}

View file

@ -1362,7 +1362,7 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg,
struct ipc_namespace *ns;
struct shm_file_data *sfd;
struct path path;
fmode_t f_mode;
int f_flags;
unsigned long populate = 0;
err = -EINVAL;
@ -1395,11 +1395,11 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg,
if (shmflg & SHM_RDONLY) {
prot = PROT_READ;
acc_mode = S_IRUGO;
f_mode = FMODE_READ;
f_flags = O_RDONLY;
} else {
prot = PROT_READ | PROT_WRITE;
acc_mode = S_IRUGO | S_IWUGO;
f_mode = FMODE_READ | FMODE_WRITE;
f_flags = O_RDWR;
}
if (shmflg & SHM_EXEC) {
prot |= PROT_EXEC;
@ -1449,7 +1449,7 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg,
goto out_nattch;
}
file = alloc_file(&path, f_mode,
file = alloc_file(&path, f_flags,
is_file_hugepages(shp->shm_file) ?
&shm_file_operations_huge :
&shm_file_operations);

View file

@ -326,7 +326,7 @@ SYSCALL_DEFINE2(memfd_create,
goto err_fd;
}
file->f_mode |= FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE;
file->f_flags |= O_RDWR | O_LARGEFILE;
file->f_flags |= O_LARGEFILE;
if (flags & MFD_ALLOW_SEALING) {
file_seals = memfd_file_seals_ptr(file);

View file

@ -3942,8 +3942,7 @@ static struct file *__shmem_file_setup(struct vfsmount *mnt, const char *name, l
if (IS_ERR(res))
goto put_path;
res = alloc_file(&path, FMODE_WRITE | FMODE_READ,
&shmem_file_operations);
res = alloc_file(&path, O_RDWR, &shmem_file_operations);
if (IS_ERR(res))
goto put_path;

View file

@ -411,7 +411,7 @@ struct file *sock_alloc_file(struct socket *sock, int flags, const char *dname)
d_instantiate(path.dentry, SOCK_INODE(sock));
file = alloc_file(&path, FMODE_READ | FMODE_WRITE,
file = alloc_file(&path, O_RDWR | (flags & O_NONBLOCK),
&socket_file_ops);
if (IS_ERR(file)) {
/* drop dentry, keep inode for a bit */
@ -423,7 +423,6 @@ struct file *sock_alloc_file(struct socket *sock, int flags, const char *dname)
}
sock->file = file;
file->f_flags = O_RDWR | (flags & O_NONBLOCK);
file->private_data = sock;
return file;
}

View file

@ -395,7 +395,7 @@ static int apparmor_inode_getattr(const struct path *path)
return common_perm_cond(OP_GETATTR, path, AA_MAY_GETATTR);
}
static int apparmor_file_open(struct file *file, const struct cred *cred)
static int apparmor_file_open(struct file *file)
{
struct aa_file_ctx *fctx = file_ctx(file);
struct aa_label *label;
@ -414,7 +414,7 @@ static int apparmor_file_open(struct file *file, const struct cred *cred)
return 0;
}
label = aa_get_newest_cred_label(cred);
label = aa_get_newest_cred_label(file->f_cred);
if (!unconfined(label)) {
struct inode *inode = file_inode(file);
struct path_cond cond = { inode->i_uid, inode->i_mode };

View file

@ -970,11 +970,11 @@ int security_file_receive(struct file *file)
return call_int_hook(file_receive, 0, file);
}
int security_file_open(struct file *file, const struct cred *cred)
int security_file_open(struct file *file)
{
int ret;
ret = call_int_hook(file_open, 0, file, cred);
ret = call_int_hook(file_open, 0, file);
if (ret)
return ret;

View file

@ -3862,7 +3862,7 @@ static int selinux_file_receive(struct file *file)
return file_has_perm(cred, file, file_to_av(file));
}
static int selinux_file_open(struct file *file, const struct cred *cred)
static int selinux_file_open(struct file *file)
{
struct file_security_struct *fsec;
struct inode_security_struct *isec;
@ -3886,7 +3886,7 @@ static int selinux_file_open(struct file *file, const struct cred *cred)
* new inode label or new policy.
* This check is not redundant - do not remove.
*/
return file_path_has_perm(cred, file, open_file_to_av(file));
return file_path_has_perm(file->f_cred, file, open_file_to_av(file));
}
/* task security operations */

View file

@ -1927,9 +1927,9 @@ static int smack_file_receive(struct file *file)
*
* Returns 0
*/
static int smack_file_open(struct file *file, const struct cred *cred)
static int smack_file_open(struct file *file)
{
struct task_smack *tsp = cred->security;
struct task_smack *tsp = file->f_cred->security;
struct inode *inode = file_inode(file);
struct smk_audit_info ad;
int rc;
@ -1937,7 +1937,7 @@ static int smack_file_open(struct file *file, const struct cred *cred)
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
smk_ad_setfield_u_fs_path(&ad, file->f_path);
rc = smk_tskacc(tsp, smk_of_inode(inode), MAY_READ, &ad);
rc = smk_bu_credfile(cred, file, MAY_READ, rc);
rc = smk_bu_credfile(file->f_cred, file, MAY_READ, rc);
return rc;
}

View file

@ -320,7 +320,7 @@ static int tomoyo_file_fcntl(struct file *file, unsigned int cmd,
*
* Returns 0 on success, negative value otherwise.
*/
static int tomoyo_file_open(struct file *f, const struct cred *cred)
static int tomoyo_file_open(struct file *f)
{
int flags = f->f_flags;
/* Don't check read permission here if called from do_execve(). */