mirror of
https://github.com/torvalds/linux.git
synced 2025-11-30 23:16:01 +07:00
Merge tag 'pull-f_path' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull file->f_path constification from Al Viro:
"Only one thing was modifying ->f_path of an opened file - acct(2).
Massaging that away and constifying a bunch of struct path * arguments
in functions that might be given &file->f_path ends up with the
situation where we can turn ->f_path into an anon union of const
struct path f_path and struct path __f_path, the latter modified only
in a few places in fs/{file_table,open,namei}.c, all for struct file
instances that are yet to be opened"
* tag 'pull-f_path' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (23 commits)
Have cc(1) catch attempts to modify ->f_path
kernel/acct.c: saner struct file treatment
configfs:get_target() - release path as soon as we grab configfs_item reference
apparmor/af_unix: constify struct path * arguments
ovl_is_real_file: constify realpath argument
ovl_sync_file(): constify path argument
ovl_lower_dir(): constify path argument
ovl_get_verity_digest(): constify path argument
ovl_validate_verity(): constify {meta,data}path arguments
ovl_ensure_verity_loaded(): constify datapath argument
ksmbd_vfs_set_init_posix_acl(): constify path argument
ksmbd_vfs_inherit_posix_acl(): constify path argument
ksmbd_vfs_kern_path_unlock(): constify path argument
ksmbd_vfs_path_lookup_locked(): root_share_path can be const struct path *
check_export(): constify path argument
export_operations->open(): constify path argument
rqst_exp_get_by_name(): constify path argument
nfs: constify path argument of __vfs_getattr()
bpf...d_path(): constify path argument
done_path_create(): constify path argument
...
This commit is contained in:
@@ -79,7 +79,7 @@ __bpf_kfunc void bpf_put_file(struct file *file)
|
||||
* pathname in *buf*, including the NUL termination character. On error, a
|
||||
* negative integer is returned.
|
||||
*/
|
||||
__bpf_kfunc int bpf_path_d_path(struct path *path, char *buf, size_t buf__sz)
|
||||
__bpf_kfunc int bpf_path_d_path(const struct path *path, char *buf, size_t buf__sz)
|
||||
{
|
||||
int len;
|
||||
char *ret;
|
||||
|
||||
@@ -114,26 +114,21 @@ static int create_link(struct config_item *parent_item,
|
||||
}
|
||||
|
||||
|
||||
static int get_target(const char *symname, struct path *path,
|
||||
struct config_item **target, struct super_block *sb)
|
||||
static int get_target(const char *symname, struct config_item **target,
|
||||
struct super_block *sb)
|
||||
{
|
||||
struct path path __free(path_put) = {};
|
||||
int ret;
|
||||
|
||||
ret = kern_path(symname, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, path);
|
||||
if (!ret) {
|
||||
if (path->dentry->d_sb == sb) {
|
||||
*target = configfs_get_config_item(path->dentry);
|
||||
if (!*target) {
|
||||
ret = -ENOENT;
|
||||
path_put(path);
|
||||
}
|
||||
} else {
|
||||
ret = -EPERM;
|
||||
path_put(path);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
ret = kern_path(symname, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &path);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (path.dentry->d_sb != sb)
|
||||
return -EPERM;
|
||||
*target = configfs_get_config_item(path.dentry);
|
||||
if (!*target)
|
||||
return -ENOENT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -141,7 +136,6 @@ int configfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, const char *symname)
|
||||
{
|
||||
int ret;
|
||||
struct path path;
|
||||
struct configfs_dirent *sd;
|
||||
struct config_item *parent_item;
|
||||
struct config_item *target_item = NULL;
|
||||
@@ -188,7 +182,7 @@ int configfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
|
||||
* AV, a thoroughly annoyed bastard.
|
||||
*/
|
||||
inode_unlock(dir);
|
||||
ret = get_target(symname, &path, &target_item, dentry->d_sb);
|
||||
ret = get_target(symname, &target_item, dentry->d_sb);
|
||||
inode_lock(dir);
|
||||
if (ret)
|
||||
goto out_put;
|
||||
@@ -210,7 +204,6 @@ int configfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
|
||||
}
|
||||
|
||||
config_item_put(target_item);
|
||||
path_put(&path);
|
||||
|
||||
out_put:
|
||||
config_item_put(parent_item);
|
||||
|
||||
@@ -54,7 +54,7 @@ struct backing_file {
|
||||
|
||||
#define backing_file(f) container_of(f, struct backing_file, file)
|
||||
|
||||
struct path *backing_file_user_path(const struct file *f)
|
||||
const struct path *backing_file_user_path(const struct file *f)
|
||||
{
|
||||
return &backing_file(f)->user_path;
|
||||
}
|
||||
@@ -171,7 +171,7 @@ static int init_file(struct file *f, int flags, const struct cred *cred)
|
||||
* the respective member when opening the file.
|
||||
*/
|
||||
mutex_init(&f->f_pos_lock);
|
||||
memset(&f->f_path, 0, sizeof(f->f_path));
|
||||
memset(&f->__f_path, 0, sizeof(f->f_path));
|
||||
memset(&f->f_ra, 0, sizeof(f->f_ra));
|
||||
|
||||
f->f_flags = flags;
|
||||
@@ -319,7 +319,7 @@ struct file *alloc_empty_backing_file(int flags, const struct cred *cred)
|
||||
static void file_init_path(struct file *file, const struct path *path,
|
||||
const struct file_operations *fop)
|
||||
{
|
||||
file->f_path = *path;
|
||||
file->__f_path = *path;
|
||||
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);
|
||||
|
||||
@@ -53,7 +53,7 @@ extern int finish_clean_context(struct fs_context *fc);
|
||||
* namei.c
|
||||
*/
|
||||
extern int filename_lookup(int dfd, struct filename *name, unsigned flags,
|
||||
struct path *path, struct path *root);
|
||||
struct path *path, const struct path *root);
|
||||
int do_rmdir(int dfd, struct filename *name);
|
||||
int do_unlinkat(int dfd, struct filename *name);
|
||||
int may_linkat(struct mnt_idmap *idmap, const struct path *link);
|
||||
|
||||
12
fs/namei.c
12
fs/namei.c
@@ -2695,7 +2695,7 @@ static int path_lookupat(struct nameidata *nd, unsigned flags, struct path *path
|
||||
}
|
||||
|
||||
int filename_lookup(int dfd, struct filename *name, unsigned flags,
|
||||
struct path *path, struct path *root)
|
||||
struct path *path, const struct path *root)
|
||||
{
|
||||
int retval;
|
||||
struct nameidata nd;
|
||||
@@ -3651,8 +3651,8 @@ static struct dentry *atomic_open(struct nameidata *nd, struct dentry *dentry,
|
||||
if (nd->flags & LOOKUP_DIRECTORY)
|
||||
open_flag |= O_DIRECTORY;
|
||||
|
||||
file->f_path.dentry = DENTRY_NOT_SET;
|
||||
file->f_path.mnt = nd->path.mnt;
|
||||
file->__f_path.dentry = DENTRY_NOT_SET;
|
||||
file->__f_path.mnt = nd->path.mnt;
|
||||
error = dir->i_op->atomic_open(dir, dentry, file,
|
||||
open_to_namei_flags(open_flag), mode);
|
||||
d_lookup_done(dentry);
|
||||
@@ -4020,8 +4020,8 @@ int vfs_tmpfile(struct mnt_idmap *idmap,
|
||||
child = d_alloc(parentpath->dentry, &slash_name);
|
||||
if (unlikely(!child))
|
||||
return -ENOMEM;
|
||||
file->f_path.mnt = parentpath->mnt;
|
||||
file->f_path.dentry = child;
|
||||
file->__f_path.mnt = parentpath->mnt;
|
||||
file->__f_path.dentry = child;
|
||||
mode = vfs_prepare_mode(idmap, dir, mode, mode, mode);
|
||||
error = dir->i_op->tmpfile(idmap, dir, file, mode);
|
||||
dput(child);
|
||||
@@ -4256,7 +4256,7 @@ struct dentry *start_creating_path(int dfd, const char *pathname,
|
||||
}
|
||||
EXPORT_SYMBOL(start_creating_path);
|
||||
|
||||
void end_creating_path(struct path *path, struct dentry *dentry)
|
||||
void end_creating_path(const struct path *path, struct dentry *dentry)
|
||||
{
|
||||
if (!IS_ERR(dentry))
|
||||
dput(dentry);
|
||||
|
||||
@@ -676,7 +676,7 @@ nfs_set_local_verifier(struct inode *inode,
|
||||
}
|
||||
|
||||
/* Factored out from fs/nfsd/vfs.h:fh_getattr() */
|
||||
static int __vfs_getattr(struct path *p, struct kstat *stat, int version)
|
||||
static int __vfs_getattr(const struct path *p, struct kstat *stat, int version)
|
||||
{
|
||||
u32 request_mask = STATX_BASIC_STATS;
|
||||
|
||||
|
||||
@@ -402,7 +402,7 @@ static struct svc_export *svc_export_update(struct svc_export *new,
|
||||
struct svc_export *old);
|
||||
static struct svc_export *svc_export_lookup(struct svc_export *);
|
||||
|
||||
static int check_export(struct path *path, int *flags, unsigned char *uuid)
|
||||
static int check_export(const struct path *path, int *flags, unsigned char *uuid)
|
||||
{
|
||||
struct inode *inode = d_inode(path->dentry);
|
||||
|
||||
@@ -1181,7 +1181,7 @@ denied:
|
||||
* use exp_get_by_name() or exp_find().
|
||||
*/
|
||||
struct svc_export *
|
||||
rqst_exp_get_by_name(struct svc_rqst *rqstp, struct path *path)
|
||||
rqst_exp_get_by_name(struct svc_rqst *rqstp, const struct path *path)
|
||||
{
|
||||
struct svc_export *gssexp, *exp = ERR_PTR(-ENOENT);
|
||||
struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
|
||||
|
||||
@@ -111,7 +111,7 @@ int nfsd_export_init(struct net *);
|
||||
void nfsd_export_shutdown(struct net *);
|
||||
void nfsd_export_flush(struct net *);
|
||||
struct svc_export * rqst_exp_get_by_name(struct svc_rqst *,
|
||||
struct path *);
|
||||
const struct path *);
|
||||
struct svc_export * rqst_exp_parent(struct svc_rqst *,
|
||||
struct path *);
|
||||
struct svc_export * rqst_find_fsidzero_export(struct svc_rqst *);
|
||||
|
||||
@@ -571,7 +571,7 @@ static int nsfs_export_permission(struct handle_to_path_ctx *ctx,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct file *nsfs_export_open(struct path *path, unsigned int oflags)
|
||||
static struct file *nsfs_export_open(const struct path *path, unsigned int oflags)
|
||||
{
|
||||
return file_open_root(path, "", oflags, 0);
|
||||
}
|
||||
|
||||
10
fs/open.c
10
fs/open.c
@@ -1022,8 +1022,8 @@ cleanup_all:
|
||||
put_file_access(f);
|
||||
cleanup_file:
|
||||
path_put(&f->f_path);
|
||||
f->f_path.mnt = NULL;
|
||||
f->f_path.dentry = NULL;
|
||||
f->__f_path.mnt = NULL;
|
||||
f->__f_path.dentry = NULL;
|
||||
f->f_inode = NULL;
|
||||
return error;
|
||||
}
|
||||
@@ -1050,7 +1050,7 @@ int finish_open(struct file *file, struct dentry *dentry,
|
||||
{
|
||||
BUG_ON(file->f_mode & FMODE_OPENED); /* once it's opened, it's opened */
|
||||
|
||||
file->f_path.dentry = dentry;
|
||||
file->__f_path.dentry = dentry;
|
||||
return do_dentry_open(file, open);
|
||||
}
|
||||
EXPORT_SYMBOL(finish_open);
|
||||
@@ -1073,7 +1073,7 @@ int finish_no_open(struct file *file, struct dentry *dentry)
|
||||
{
|
||||
if (IS_ERR(dentry))
|
||||
return PTR_ERR(dentry);
|
||||
file->f_path.dentry = dentry;
|
||||
file->__f_path.dentry = dentry;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(finish_no_open);
|
||||
@@ -1093,7 +1093,7 @@ int vfs_open(const struct path *path, struct file *file)
|
||||
{
|
||||
int ret;
|
||||
|
||||
file->f_path = *path;
|
||||
file->__f_path = *path;
|
||||
ret = do_dentry_open(file, NULL);
|
||||
if (!ret) {
|
||||
/*
|
||||
|
||||
@@ -242,7 +242,7 @@ static int ovl_verify_area(loff_t pos, loff_t pos2, loff_t len, loff_t totlen)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ovl_sync_file(struct path *path)
|
||||
static int ovl_sync_file(const struct path *path)
|
||||
{
|
||||
struct file *new_file;
|
||||
int err;
|
||||
|
||||
@@ -120,7 +120,7 @@ static bool ovl_is_real_file(const struct file *realfile,
|
||||
}
|
||||
|
||||
static struct file *ovl_real_file_path(const struct file *file,
|
||||
struct path *realpath)
|
||||
const struct path *realpath)
|
||||
{
|
||||
struct ovl_file *of = file->private_data;
|
||||
struct file *realfile = of->realfile;
|
||||
|
||||
@@ -562,11 +562,11 @@ int ovl_set_metacopy_xattr(struct ovl_fs *ofs, struct dentry *d,
|
||||
struct ovl_metacopy *metacopy);
|
||||
bool ovl_is_metacopy_dentry(struct dentry *dentry);
|
||||
char *ovl_get_redirect_xattr(struct ovl_fs *ofs, const struct path *path, int padding);
|
||||
int ovl_ensure_verity_loaded(struct path *path);
|
||||
int ovl_ensure_verity_loaded(const struct path *path);
|
||||
int ovl_validate_verity(struct ovl_fs *ofs,
|
||||
struct path *metapath,
|
||||
struct path *datapath);
|
||||
int ovl_get_verity_digest(struct ovl_fs *ofs, struct path *src,
|
||||
const struct path *metapath,
|
||||
const struct path *datapath);
|
||||
int ovl_get_verity_digest(struct ovl_fs *ofs, const struct path *src,
|
||||
struct ovl_metacopy *metacopy);
|
||||
int ovl_sync_status(struct ovl_fs *ofs);
|
||||
|
||||
|
||||
@@ -404,7 +404,7 @@ static int ovl_check_namelen(const struct path *path, struct ovl_fs *ofs,
|
||||
return err;
|
||||
}
|
||||
|
||||
static int ovl_lower_dir(const char *name, struct path *path,
|
||||
static int ovl_lower_dir(const char *name, const struct path *path,
|
||||
struct ovl_fs *ofs, int *stack_depth)
|
||||
{
|
||||
int fh_type;
|
||||
|
||||
@@ -1381,7 +1381,7 @@ err_free:
|
||||
}
|
||||
|
||||
/* Call with mounter creds as it may open the file */
|
||||
int ovl_ensure_verity_loaded(struct path *datapath)
|
||||
int ovl_ensure_verity_loaded(const struct path *datapath)
|
||||
{
|
||||
struct inode *inode = d_inode(datapath->dentry);
|
||||
struct file *filp;
|
||||
@@ -1401,8 +1401,8 @@ int ovl_ensure_verity_loaded(struct path *datapath)
|
||||
}
|
||||
|
||||
int ovl_validate_verity(struct ovl_fs *ofs,
|
||||
struct path *metapath,
|
||||
struct path *datapath)
|
||||
const struct path *metapath,
|
||||
const struct path *datapath)
|
||||
{
|
||||
struct ovl_metacopy metacopy_data;
|
||||
u8 actual_digest[FS_VERITY_MAX_DIGEST_SIZE];
|
||||
@@ -1455,7 +1455,7 @@ int ovl_validate_verity(struct ovl_fs *ofs,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ovl_get_verity_digest(struct ovl_fs *ofs, struct path *src,
|
||||
int ovl_get_verity_digest(struct ovl_fs *ofs, const struct path *src,
|
||||
struct ovl_metacopy *metacopy)
|
||||
{
|
||||
int err, digest_size;
|
||||
|
||||
@@ -850,7 +850,7 @@ static int pidfs_export_permission(struct handle_to_path_ctx *ctx,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct file *pidfs_export_open(struct path *path, unsigned int oflags)
|
||||
static struct file *pidfs_export_open(const struct path *path, unsigned int oflags)
|
||||
{
|
||||
/*
|
||||
* Clear O_LARGEFILE as open_by_handle_at() forces it and raise
|
||||
|
||||
@@ -73,7 +73,7 @@ static int ksmbd_vfs_path_lookup(struct ksmbd_share_config *share_conf,
|
||||
{
|
||||
struct qstr last;
|
||||
struct filename *filename __free(putname) = NULL;
|
||||
struct path *root_share_path = &share_conf->vfs_path;
|
||||
const struct path *root_share_path = &share_conf->vfs_path;
|
||||
int err, type;
|
||||
struct dentry *d;
|
||||
|
||||
@@ -1306,7 +1306,7 @@ int ksmbd_vfs_kern_path_locked(struct ksmbd_work *work, char *filepath,
|
||||
caseless, true);
|
||||
}
|
||||
|
||||
void ksmbd_vfs_kern_path_unlock(struct path *path)
|
||||
void ksmbd_vfs_kern_path_unlock(const struct path *path)
|
||||
{
|
||||
/* While lock is still held, ->d_parent is safe */
|
||||
inode_unlock(d_inode(path->dentry->d_parent));
|
||||
@@ -1867,7 +1867,7 @@ void ksmbd_vfs_posix_lock_unblock(struct file_lock *flock)
|
||||
}
|
||||
|
||||
int ksmbd_vfs_set_init_posix_acl(struct mnt_idmap *idmap,
|
||||
struct path *path)
|
||||
const struct path *path)
|
||||
{
|
||||
struct posix_acl_state acl_state;
|
||||
struct posix_acl *acls;
|
||||
@@ -1920,7 +1920,7 @@ int ksmbd_vfs_set_init_posix_acl(struct mnt_idmap *idmap,
|
||||
}
|
||||
|
||||
int ksmbd_vfs_inherit_posix_acl(struct mnt_idmap *idmap,
|
||||
struct path *path, struct inode *parent_inode)
|
||||
const struct path *path, struct inode *parent_inode)
|
||||
{
|
||||
struct posix_acl *acls;
|
||||
struct posix_acl_entry *pace;
|
||||
|
||||
@@ -123,7 +123,7 @@ int ksmbd_vfs_kern_path(struct ksmbd_work *work, char *name,
|
||||
int ksmbd_vfs_kern_path_locked(struct ksmbd_work *work, char *name,
|
||||
unsigned int flags,
|
||||
struct path *path, bool caseless);
|
||||
void ksmbd_vfs_kern_path_unlock(struct path *path);
|
||||
void ksmbd_vfs_kern_path_unlock(const struct path *path);
|
||||
struct dentry *ksmbd_vfs_kern_path_create(struct ksmbd_work *work,
|
||||
const char *name,
|
||||
unsigned int flags,
|
||||
@@ -164,8 +164,8 @@ int ksmbd_vfs_get_dos_attrib_xattr(struct mnt_idmap *idmap,
|
||||
struct dentry *dentry,
|
||||
struct xattr_dos_attrib *da);
|
||||
int ksmbd_vfs_set_init_posix_acl(struct mnt_idmap *idmap,
|
||||
struct path *path);
|
||||
const struct path *path);
|
||||
int ksmbd_vfs_inherit_posix_acl(struct mnt_idmap *idmap,
|
||||
struct path *path,
|
||||
const struct path *path,
|
||||
struct inode *parent_inode);
|
||||
#endif /* __KSMBD_VFS_H__ */
|
||||
|
||||
@@ -293,7 +293,7 @@ static int statx_lookup_flags(int flags)
|
||||
return lookup_flags;
|
||||
}
|
||||
|
||||
static int vfs_statx_path(struct path *path, int flags, struct kstat *stat,
|
||||
static int vfs_statx_path(const struct path *path, int flags, struct kstat *stat,
|
||||
u32 request_mask)
|
||||
{
|
||||
int error = vfs_getattr(path, stat, request_mask, flags);
|
||||
|
||||
@@ -276,7 +276,7 @@ struct export_operations {
|
||||
int (*commit_blocks)(struct inode *inode, struct iomap *iomaps,
|
||||
int nr_iomaps, struct iattr *iattr);
|
||||
int (*permission)(struct handle_to_path_ctx *ctx, unsigned int oflags);
|
||||
struct file * (*open)(struct path *path, unsigned int oflags);
|
||||
struct file * (*open)(const struct path *path, unsigned int oflags);
|
||||
#define EXPORT_OP_NOWCC (0x1) /* don't collect v3 wcc data */
|
||||
#define EXPORT_OP_NOSUBTREECHK (0x2) /* no subtree checking */
|
||||
#define EXPORT_OP_CLOSE_BEFORE_UNLINK (0x4) /* close files before unlink */
|
||||
|
||||
@@ -1192,6 +1192,8 @@ static inline int ra_has_index(struct file_ra_state *ra, pgoff_t index)
|
||||
* @f_cred: stashed credentials of creator/opener
|
||||
* @f_owner: file owner
|
||||
* @f_path: path of the file
|
||||
* @__f_path: writable alias for @f_path; *ONLY* for core VFS and only before
|
||||
* the file gets open
|
||||
* @f_pos_lock: lock protecting file position
|
||||
* @f_pipe: specific to pipes
|
||||
* @f_pos: file position
|
||||
@@ -1217,7 +1219,10 @@ struct file {
|
||||
const struct cred *f_cred;
|
||||
struct fown_struct *f_owner;
|
||||
/* --- cacheline 1 boundary (64 bytes) --- */
|
||||
struct path f_path;
|
||||
union {
|
||||
const struct path f_path;
|
||||
struct path __f_path;
|
||||
};
|
||||
union {
|
||||
/* regular files (with FMODE_ATOMIC_POS) and directories */
|
||||
struct mutex f_pos_lock;
|
||||
@@ -2877,7 +2882,7 @@ struct file *dentry_open_nonotify(const struct path *path, int flags,
|
||||
const struct cred *cred);
|
||||
struct file *dentry_create(const struct path *path, int flags, umode_t mode,
|
||||
const struct cred *cred);
|
||||
struct path *backing_file_user_path(const struct file *f);
|
||||
const struct path *backing_file_user_path(const struct file *f);
|
||||
|
||||
/*
|
||||
* When mmapping a file on a stackable filesystem (e.g., overlayfs), the file
|
||||
|
||||
@@ -61,10 +61,10 @@ struct dentry *kern_path_parent(const char *name, struct path *parent);
|
||||
|
||||
extern struct dentry *start_creating_path(int, const char *, struct path *, unsigned int);
|
||||
extern struct dentry *start_creating_user_path(int, const char __user *, struct path *, unsigned int);
|
||||
extern void end_creating_path(struct path *, struct dentry *);
|
||||
extern void end_creating_path(const struct path *, struct dentry *);
|
||||
extern struct dentry *start_removing_path(const char *, struct path *);
|
||||
extern struct dentry *start_removing_user_path_at(int , const char __user *, struct path *);
|
||||
static inline void end_removing_path(struct path *path , struct dentry *dentry)
|
||||
static inline void end_removing_path(const struct path *path , struct dentry *dentry)
|
||||
{
|
||||
end_creating_path(path, dentry);
|
||||
}
|
||||
|
||||
114
kernel/acct.c
114
kernel/acct.c
@@ -44,19 +44,14 @@
|
||||
* a struct file opened for write. Fixed. 2/6/2000, AV.
|
||||
*/
|
||||
|
||||
#include <linux/mm.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/acct.h>
|
||||
#include <linux/capability.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/security.h>
|
||||
#include <linux/vfs.h>
|
||||
#include <linux/statfs.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/times.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/mount.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/namei.h>
|
||||
#include <linux/sched/cputime.h>
|
||||
|
||||
#include <asm/div64.h>
|
||||
@@ -217,84 +212,70 @@ static void close_work(struct work_struct *work)
|
||||
complete(&acct->done);
|
||||
}
|
||||
|
||||
static int acct_on(struct filename *pathname)
|
||||
DEFINE_FREE(fput_sync, struct file *, if (!IS_ERR_OR_NULL(_T)) __fput_sync(_T))
|
||||
static int acct_on(const char __user *name)
|
||||
{
|
||||
struct file *file;
|
||||
struct vfsmount *mnt, *internal;
|
||||
/* Difference from BSD - they don't do O_APPEND */
|
||||
const int open_flags = O_WRONLY|O_APPEND|O_LARGEFILE;
|
||||
struct pid_namespace *ns = task_active_pid_ns(current);
|
||||
struct filename *pathname __free(putname) = getname(name);
|
||||
struct file *original_file __free(fput) = NULL; // in that order
|
||||
struct path internal __free(path_put) = {}; // in that order
|
||||
struct file *file __free(fput_sync) = NULL; // in that order
|
||||
struct bsd_acct_struct *acct;
|
||||
struct vfsmount *mnt;
|
||||
struct fs_pin *old;
|
||||
int err;
|
||||
|
||||
if (IS_ERR(pathname))
|
||||
return PTR_ERR(pathname);
|
||||
original_file = file_open_name(pathname, open_flags, 0);
|
||||
if (IS_ERR(original_file))
|
||||
return PTR_ERR(original_file);
|
||||
|
||||
mnt = mnt_clone_internal(&original_file->f_path);
|
||||
if (IS_ERR(mnt))
|
||||
return PTR_ERR(mnt);
|
||||
|
||||
internal.mnt = mnt;
|
||||
internal.dentry = dget(mnt->mnt_root);
|
||||
|
||||
file = dentry_open(&internal, open_flags, current_cred());
|
||||
if (IS_ERR(file))
|
||||
return PTR_ERR(file);
|
||||
|
||||
if (!S_ISREG(file_inode(file)->i_mode))
|
||||
return -EACCES;
|
||||
|
||||
/* Exclude kernel kernel internal filesystems. */
|
||||
if (file_inode(file)->i_sb->s_flags & (SB_NOUSER | SB_KERNMOUNT))
|
||||
return -EINVAL;
|
||||
|
||||
/* Exclude procfs and sysfs. */
|
||||
if (file_inode(file)->i_sb->s_iflags & SB_I_USERNS_VISIBLE)
|
||||
return -EINVAL;
|
||||
|
||||
if (!(file->f_mode & FMODE_CAN_WRITE))
|
||||
return -EIO;
|
||||
|
||||
acct = kzalloc(sizeof(struct bsd_acct_struct), GFP_KERNEL);
|
||||
if (!acct)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Difference from BSD - they don't do O_APPEND */
|
||||
file = file_open_name(pathname, O_WRONLY|O_APPEND|O_LARGEFILE, 0);
|
||||
if (IS_ERR(file)) {
|
||||
kfree(acct);
|
||||
return PTR_ERR(file);
|
||||
}
|
||||
|
||||
if (!S_ISREG(file_inode(file)->i_mode)) {
|
||||
kfree(acct);
|
||||
filp_close(file, NULL);
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
/* Exclude kernel kernel internal filesystems. */
|
||||
if (file_inode(file)->i_sb->s_flags & (SB_NOUSER | SB_KERNMOUNT)) {
|
||||
kfree(acct);
|
||||
filp_close(file, NULL);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Exclude procfs and sysfs. */
|
||||
if (file_inode(file)->i_sb->s_iflags & SB_I_USERNS_VISIBLE) {
|
||||
kfree(acct);
|
||||
filp_close(file, NULL);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!(file->f_mode & FMODE_CAN_WRITE)) {
|
||||
kfree(acct);
|
||||
filp_close(file, NULL);
|
||||
return -EIO;
|
||||
}
|
||||
internal = mnt_clone_internal(&file->f_path);
|
||||
if (IS_ERR(internal)) {
|
||||
kfree(acct);
|
||||
filp_close(file, NULL);
|
||||
return PTR_ERR(internal);
|
||||
}
|
||||
err = mnt_get_write_access(internal);
|
||||
if (err) {
|
||||
mntput(internal);
|
||||
kfree(acct);
|
||||
filp_close(file, NULL);
|
||||
return err;
|
||||
}
|
||||
mnt = file->f_path.mnt;
|
||||
file->f_path.mnt = internal;
|
||||
|
||||
atomic_long_set(&acct->count, 1);
|
||||
init_fs_pin(&acct->pin, acct_pin_kill);
|
||||
acct->file = file;
|
||||
acct->file = no_free_ptr(file);
|
||||
acct->needcheck = jiffies;
|
||||
acct->ns = ns;
|
||||
mutex_init(&acct->lock);
|
||||
INIT_WORK(&acct->work, close_work);
|
||||
init_completion(&acct->done);
|
||||
mutex_lock_nested(&acct->lock, 1); /* nobody has seen it yet */
|
||||
pin_insert(&acct->pin, mnt);
|
||||
pin_insert(&acct->pin, original_file->f_path.mnt);
|
||||
|
||||
rcu_read_lock();
|
||||
old = xchg(&ns->bacct, &acct->pin);
|
||||
mutex_unlock(&acct->lock);
|
||||
pin_kill(old);
|
||||
mnt_put_write_access(mnt);
|
||||
mntput(mnt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -319,14 +300,9 @@ SYSCALL_DEFINE1(acct, const char __user *, name)
|
||||
return -EPERM;
|
||||
|
||||
if (name) {
|
||||
struct filename *tmp = getname(name);
|
||||
|
||||
if (IS_ERR(tmp))
|
||||
return PTR_ERR(tmp);
|
||||
mutex_lock(&acct_on_mutex);
|
||||
error = acct_on(tmp);
|
||||
error = acct_on(name);
|
||||
mutex_unlock(&acct_on_mutex);
|
||||
putname(tmp);
|
||||
} else {
|
||||
rcu_read_lock();
|
||||
pin_kill(task_active_pid_ns(current)->bacct);
|
||||
|
||||
@@ -899,7 +899,7 @@ const struct bpf_func_proto bpf_send_signal_thread_proto = {
|
||||
.arg1_type = ARG_ANYTHING,
|
||||
};
|
||||
|
||||
BPF_CALL_3(bpf_d_path, struct path *, path, char *, buf, u32, sz)
|
||||
BPF_CALL_3(bpf_d_path, const struct path *, path, char *, buf, u32, sz)
|
||||
{
|
||||
struct path copy;
|
||||
long len;
|
||||
|
||||
@@ -31,7 +31,7 @@ static inline struct sock *aa_unix_sk(struct unix_sock *u)
|
||||
}
|
||||
|
||||
static int unix_fs_perm(const char *op, u32 mask, const struct cred *subj_cred,
|
||||
struct aa_label *label, struct path *path)
|
||||
struct aa_label *label, const struct path *path)
|
||||
{
|
||||
AA_BUG(!label);
|
||||
AA_BUG(!path);
|
||||
@@ -224,7 +224,7 @@ static int profile_create_perm(struct aa_profile *profile, int family,
|
||||
|
||||
static int profile_sk_perm(struct aa_profile *profile,
|
||||
struct apparmor_audit_data *ad,
|
||||
u32 request, struct sock *sk, struct path *path)
|
||||
u32 request, struct sock *sk, const struct path *path)
|
||||
{
|
||||
struct aa_ruleset *rules = profile->label.rules[0];
|
||||
struct aa_perms *p = NULL;
|
||||
@@ -386,9 +386,9 @@ static int profile_opt_perm(struct aa_profile *profile, u32 request,
|
||||
|
||||
/* null peer_label is allowed, in which case the peer_sk label is used */
|
||||
static int profile_peer_perm(struct aa_profile *profile, u32 request,
|
||||
struct sock *sk, struct path *path,
|
||||
struct sock *sk, const struct path *path,
|
||||
struct sockaddr_un *peer_addr,
|
||||
int peer_addrlen, struct path *peer_path,
|
||||
int peer_addrlen, const struct path *peer_path,
|
||||
struct aa_label *peer_label,
|
||||
struct apparmor_audit_data *ad)
|
||||
{
|
||||
@@ -445,7 +445,7 @@ int aa_unix_create_perm(struct aa_label *label, int family, int type,
|
||||
static int aa_unix_label_sk_perm(const struct cred *subj_cred,
|
||||
struct aa_label *label,
|
||||
const char *op, u32 request, struct sock *sk,
|
||||
struct path *path)
|
||||
const struct path *path)
|
||||
{
|
||||
if (!unconfined(label)) {
|
||||
struct aa_profile *profile;
|
||||
@@ -599,9 +599,9 @@ int aa_unix_opt_perm(const char *op, u32 request, struct socket *sock,
|
||||
|
||||
static int unix_peer_perm(const struct cred *subj_cred,
|
||||
struct aa_label *label, const char *op, u32 request,
|
||||
struct sock *sk, struct path *path,
|
||||
struct sock *sk, const struct path *path,
|
||||
struct sockaddr_un *peer_addr, int peer_addrlen,
|
||||
struct path *peer_path, struct aa_label *peer_label)
|
||||
const struct path *peer_path, struct aa_label *peer_label)
|
||||
{
|
||||
struct aa_profile *profile;
|
||||
DEFINE_AUDIT_SK(ad, op, subj_cred, sk);
|
||||
|
||||
@@ -219,7 +219,7 @@ extern void bpf_put_file(struct file *file) __ksym;
|
||||
* including the NULL termination character, stored in the supplied
|
||||
* buffer. On error, a negative integer is returned.
|
||||
*/
|
||||
extern int bpf_path_d_path(struct path *path, char *buf, size_t buf__sz) __ksym;
|
||||
extern int bpf_path_d_path(const struct path *path, char *buf, size_t buf__sz) __ksym;
|
||||
|
||||
/* This macro must be used to mark the exception callback corresponding to the
|
||||
* main program. For example:
|
||||
|
||||
Reference in New Issue
Block a user