mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:41:42 +00:00
sanitize struct filename and lookup flags handling in statx
and friends Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> -----BEGIN PGP SIGNATURE----- iHUEABYIAB0WIQQqUNBr3gm4hGXdBJlZ7Krx/gZQ6wUCZzdpZQAKCRBZ7Krx/gZQ 6whMAQDhlGFV+nGRetwe4t60mVRpxIoc71GLC7b6V8FmyfTI5AEAkAigkJ8KCZDP mfGsN/3PtzoxnIkIqdk7Y7q4/fowyAw= =4DWZ -----END PGP SIGNATURE----- Merge tag 'pull-statx' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs Pull statx updates from Al Viro: "Sanitize struct filename and lookup flags handling in statx and friends" * tag 'pull-statx' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: libfs: kill empty_dir_getattr() fs: Simplify getattr interface function checking AT_GETATTR_NOSEC flag fs/stat.c: switch to CLASS(fd_raw) kill getname_statx_lookup_flags() io_statx_prep(): use getname_uflags()
This commit is contained in:
commit
c6d64479d6
@ -1008,14 +1008,6 @@ static int ecryptfs_getattr_link(struct mnt_idmap *idmap,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int ecryptfs_do_getattr(const struct path *path, struct kstat *stat,
|
||||
u32 request_mask, unsigned int flags)
|
||||
{
|
||||
if (flags & AT_GETATTR_NOSEC)
|
||||
return vfs_getattr_nosec(path, stat, request_mask, flags);
|
||||
return vfs_getattr(path, stat, request_mask, flags);
|
||||
}
|
||||
|
||||
static int ecryptfs_getattr(struct mnt_idmap *idmap,
|
||||
const struct path *path, struct kstat *stat,
|
||||
u32 request_mask, unsigned int flags)
|
||||
@ -1024,7 +1016,7 @@ static int ecryptfs_getattr(struct mnt_idmap *idmap,
|
||||
struct kstat lower_stat;
|
||||
int rc;
|
||||
|
||||
rc = ecryptfs_do_getattr(ecryptfs_dentry_to_lower_path(dentry),
|
||||
rc = vfs_getattr_nosec(ecryptfs_dentry_to_lower_path(dentry),
|
||||
&lower_stat, request_mask, flags);
|
||||
if (!rc) {
|
||||
fsstack_copy_attr_all(d_inode(dentry),
|
||||
|
@ -246,7 +246,6 @@ int open_namespace(struct ns_common *ns);
|
||||
* fs/stat.c:
|
||||
*/
|
||||
|
||||
int getname_statx_lookup_flags(int flags);
|
||||
int do_statx(int dfd, struct filename *filename, unsigned int flags,
|
||||
unsigned int mask, struct statx __user *buffer);
|
||||
int do_statx_fd(int fd, unsigned int flags, unsigned int mask,
|
||||
|
11
fs/libfs.c
11
fs/libfs.c
@ -1715,15 +1715,6 @@ static struct dentry *empty_dir_lookup(struct inode *dir, struct dentry *dentry,
|
||||
return ERR_PTR(-ENOENT);
|
||||
}
|
||||
|
||||
static int empty_dir_getattr(struct mnt_idmap *idmap,
|
||||
const struct path *path, struct kstat *stat,
|
||||
u32 request_mask, unsigned int query_flags)
|
||||
{
|
||||
struct inode *inode = d_inode(path->dentry);
|
||||
generic_fillattr(&nop_mnt_idmap, request_mask, inode, stat);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int empty_dir_setattr(struct mnt_idmap *idmap,
|
||||
struct dentry *dentry, struct iattr *attr)
|
||||
{
|
||||
@ -1737,9 +1728,7 @@ static ssize_t empty_dir_listxattr(struct dentry *dentry, char *list, size_t siz
|
||||
|
||||
static const struct inode_operations empty_dir_inode_operations = {
|
||||
.lookup = empty_dir_lookup,
|
||||
.permission = generic_permission,
|
||||
.setattr = empty_dir_setattr,
|
||||
.getattr = empty_dir_getattr,
|
||||
.listxattr = empty_dir_listxattr,
|
||||
};
|
||||
|
||||
|
@ -170,7 +170,7 @@ int ovl_getattr(struct mnt_idmap *idmap, const struct path *path,
|
||||
|
||||
type = ovl_path_real(dentry, &realpath);
|
||||
old_cred = ovl_override_creds(dentry->d_sb);
|
||||
err = ovl_do_getattr(&realpath, stat, request_mask, flags);
|
||||
err = vfs_getattr_nosec(&realpath, stat, request_mask, flags);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
@ -195,7 +195,7 @@ int ovl_getattr(struct mnt_idmap *idmap, const struct path *path,
|
||||
(!is_dir ? STATX_NLINK : 0);
|
||||
|
||||
ovl_path_lower(dentry, &realpath);
|
||||
err = ovl_do_getattr(&realpath, &lowerstat, lowermask,
|
||||
err = vfs_getattr_nosec(&realpath, &lowerstat, lowermask,
|
||||
flags);
|
||||
if (err)
|
||||
goto out;
|
||||
@ -248,7 +248,7 @@ int ovl_getattr(struct mnt_idmap *idmap, const struct path *path,
|
||||
|
||||
ovl_path_lowerdata(dentry, &realpath);
|
||||
if (realpath.dentry) {
|
||||
err = ovl_do_getattr(&realpath, &lowerdatastat,
|
||||
err = vfs_getattr_nosec(&realpath, &lowerdatastat,
|
||||
lowermask, flags);
|
||||
if (err)
|
||||
goto out;
|
||||
|
@ -412,14 +412,6 @@ static inline bool ovl_open_flags_need_copy_up(int flags)
|
||||
return ((OPEN_FMODE(flags) & FMODE_WRITE) || (flags & O_TRUNC));
|
||||
}
|
||||
|
||||
static inline int ovl_do_getattr(const struct path *path, struct kstat *stat,
|
||||
u32 request_mask, unsigned int flags)
|
||||
{
|
||||
if (flags & AT_GETATTR_NOSEC)
|
||||
return vfs_getattr_nosec(path, stat, request_mask, flags);
|
||||
return vfs_getattr(path, stat, request_mask, flags);
|
||||
}
|
||||
|
||||
/* util.c */
|
||||
int ovl_get_write_access(struct dentry *dentry);
|
||||
void ovl_put_write_access(struct dentry *dentry);
|
||||
|
24
fs/stat.c
24
fs/stat.c
@ -207,7 +207,7 @@ int vfs_getattr_nosec(const struct path *path, struct kstat *stat,
|
||||
if (inode->i_op->getattr)
|
||||
return inode->i_op->getattr(idmap, path, stat,
|
||||
request_mask,
|
||||
query_flags | AT_GETATTR_NOSEC);
|
||||
query_flags);
|
||||
|
||||
generic_fillattr(idmap, request_mask, inode, stat);
|
||||
return 0;
|
||||
@ -240,9 +240,6 @@ int vfs_getattr(const struct path *path, struct kstat *stat,
|
||||
{
|
||||
int retval;
|
||||
|
||||
if (WARN_ON_ONCE(query_flags & AT_GETATTR_NOSEC))
|
||||
return -EPERM;
|
||||
|
||||
retval = security_inode_getattr(path);
|
||||
if (retval)
|
||||
return retval;
|
||||
@ -262,18 +259,13 @@ EXPORT_SYMBOL(vfs_getattr);
|
||||
*/
|
||||
int vfs_fstat(int fd, struct kstat *stat)
|
||||
{
|
||||
struct fd f;
|
||||
int error;
|
||||
|
||||
f = fdget_raw(fd);
|
||||
if (!fd_file(f))
|
||||
CLASS(fd_raw, f)(fd);
|
||||
if (fd_empty(f))
|
||||
return -EBADF;
|
||||
error = vfs_getattr(&fd_file(f)->f_path, stat, STATX_BASIC_STATS, 0);
|
||||
fdput(f);
|
||||
return error;
|
||||
return vfs_getattr(&fd_file(f)->f_path, stat, STATX_BASIC_STATS, 0);
|
||||
}
|
||||
|
||||
int getname_statx_lookup_flags(int flags)
|
||||
static int statx_lookup_flags(int flags)
|
||||
{
|
||||
int lookup_flags = 0;
|
||||
|
||||
@ -281,8 +273,6 @@ int getname_statx_lookup_flags(int flags)
|
||||
lookup_flags |= LOOKUP_FOLLOW;
|
||||
if (!(flags & AT_NO_AUTOMOUNT))
|
||||
lookup_flags |= LOOKUP_AUTOMOUNT;
|
||||
if (flags & AT_EMPTY_PATH)
|
||||
lookup_flags |= LOOKUP_EMPTY;
|
||||
|
||||
return lookup_flags;
|
||||
}
|
||||
@ -319,7 +309,7 @@ static int vfs_statx_fd(int fd, int flags, struct kstat *stat,
|
||||
u32 request_mask)
|
||||
{
|
||||
CLASS(fd_raw, f)(fd);
|
||||
if (!fd_file(f))
|
||||
if (fd_empty(f))
|
||||
return -EBADF;
|
||||
return vfs_statx_path(&fd_file(f)->f_path, flags, stat, request_mask);
|
||||
}
|
||||
@ -343,7 +333,7 @@ static int vfs_statx(int dfd, struct filename *filename, int flags,
|
||||
struct kstat *stat, u32 request_mask)
|
||||
{
|
||||
struct path path;
|
||||
unsigned int lookup_flags = getname_statx_lookup_flags(flags);
|
||||
unsigned int lookup_flags = statx_lookup_flags(flags);
|
||||
int error;
|
||||
|
||||
if (flags & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT | AT_EMPTY_PATH |
|
||||
|
@ -154,8 +154,4 @@
|
||||
usable with open_by_handle_at(2). */
|
||||
#define AT_HANDLE_MNT_ID_UNIQUE 0x001 /* Return the u64 unique mount ID. */
|
||||
|
||||
#if defined(__KERNEL__)
|
||||
#define AT_GETATTR_NOSEC 0x80000000
|
||||
#endif
|
||||
|
||||
#endif /* _UAPI_LINUX_FCNTL_H */
|
||||
|
@ -36,8 +36,7 @@ int io_statx_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
|
||||
sx->buffer = u64_to_user_ptr(READ_ONCE(sqe->addr2));
|
||||
sx->flags = READ_ONCE(sqe->statx_flags);
|
||||
|
||||
sx->filename = getname_flags(path,
|
||||
getname_statx_lookup_flags(sx->flags));
|
||||
sx->filename = getname_uflags(path, sx->flags);
|
||||
|
||||
if (IS_ERR(sx->filename)) {
|
||||
int ret = PTR_ERR(sx->filename);
|
||||
|
Loading…
Reference in New Issue
Block a user