Add the RHEL 211.17.1..211.18.1 backports (1162-1244) from centos-stream-10 and upstream, on top of 211.16.1. Includes the lpfc 14.4.0.x revert batch and the RHEL-only lpfc_nlp_get UAF guard. Bump to 211.18.1.
171 lines
5.7 KiB
Diff
171 lines
5.7 KiB
Diff
From 0e6f0c4069e34ae66ce960879b5a88ae0ce9aab8 Mon Sep 17 00:00:00 2001
|
|
From: Rafael Aquini <raquini@redhat.com>
|
|
Date: Mon, 11 May 2026 10:39:37 -0400
|
|
Subject: [PATCH] fs: add S_ANON_INODE
|
|
|
|
JIRA: https://issues.redhat.com/browse/RHEL-171616
|
|
Conflicts:
|
|
* mm/readahead.c: in order to reduce differences and make the porting cleaner
|
|
we are folding the hunk from 6348be02eead ("fdget(), trivial conversions")
|
|
|
|
commit 19bbfe7b5fcc04d8711e8e1352acc77c1a5c3955
|
|
Author: Christian Brauner <brauner@kernel.org>
|
|
Date: Mon Apr 21 10:27:40 2025 +0200
|
|
|
|
fs: add S_ANON_INODE
|
|
|
|
This makes it easy to detect proper anonymous inodes and to ensure that
|
|
we can detect them in codepaths such as readahead().
|
|
|
|
Readahead on anonymous inodes didn't work because they didn't have a
|
|
proper mode. Now that they have we need to retain EINVAL being returned
|
|
otherwise LTP will fail.
|
|
|
|
We also need to ensure that ioctls aren't simply fired like they are for
|
|
regular files so things like inotify inodes continue to correctly call
|
|
their own ioctl handlers as in [1].
|
|
|
|
Reported-by: Xilin Wu <sophon@radxa.com>
|
|
Link: https://lore.kernel.org/3A9139D5CD543962+89831381-31b9-4392-87ec-a84a5b3507d8@radxa.com [1]
|
|
Link: https://lore.kernel.org/7a1a7076-ff6b-4cb0-94e7-7218a0a44028@sirena.org.uk
|
|
Signed-off-by: Christian Brauner <brauner@kernel.org>
|
|
|
|
Signed-off-by: Rafael Aquini <raquini@redhat.com>
|
|
|
|
diff --git a/fs/ioctl.c b/fs/ioctl.c
|
|
index 6e0c954388d4..4dbd5627af8f 100644
|
|
--- a/fs/ioctl.c
|
|
+++ b/fs/ioctl.c
|
|
@@ -822,7 +822,8 @@ static int do_vfs_ioctl(struct file *filp, unsigned int fd,
|
|
return ioctl_fioasync(fd, filp, argp);
|
|
|
|
case FIOQSIZE:
|
|
- if (S_ISDIR(inode->i_mode) || S_ISREG(inode->i_mode) ||
|
|
+ if (S_ISDIR(inode->i_mode) ||
|
|
+ (S_ISREG(inode->i_mode) && !IS_ANON_FILE(inode)) ||
|
|
S_ISLNK(inode->i_mode)) {
|
|
loff_t res = inode_get_bytes(inode);
|
|
return copy_to_user(argp, &res, sizeof(res)) ?
|
|
@@ -857,7 +858,7 @@ static int do_vfs_ioctl(struct file *filp, unsigned int fd,
|
|
return ioctl_file_dedupe_range(filp, argp);
|
|
|
|
case FIONREAD:
|
|
- if (!S_ISREG(inode->i_mode))
|
|
+ if (!S_ISREG(inode->i_mode) || IS_ANON_FILE(inode))
|
|
return vfs_ioctl(filp, cmd, arg);
|
|
|
|
return put_user(i_size_read(inode) - filp->f_pos,
|
|
@@ -882,7 +883,7 @@ static int do_vfs_ioctl(struct file *filp, unsigned int fd,
|
|
return ioctl_get_fs_sysfs_path(filp, argp);
|
|
|
|
default:
|
|
- if (S_ISREG(inode->i_mode))
|
|
+ if (S_ISREG(inode->i_mode) && !IS_ANON_FILE(inode))
|
|
return file_ioctl(filp, cmd, argp);
|
|
break;
|
|
}
|
|
diff --git a/fs/libfs.c b/fs/libfs.c
|
|
index 4e9de5aa4d7f..c4a305967619 100644
|
|
--- a/fs/libfs.c
|
|
+++ b/fs/libfs.c
|
|
@@ -1660,7 +1660,7 @@ struct inode *alloc_anon_inode(struct super_block *s)
|
|
inode->i_mode = S_IFREG | S_IRUSR | S_IWUSR;
|
|
inode->i_uid = current_fsuid();
|
|
inode->i_gid = current_fsgid();
|
|
- inode->i_flags |= S_PRIVATE;
|
|
+ inode->i_flags |= S_PRIVATE | S_ANON_INODE;
|
|
simple_inode_init_ts(inode);
|
|
return inode;
|
|
}
|
|
diff --git a/fs/pidfs.c b/fs/pidfs.c
|
|
index d6c0ed79ea24..7e10fac8e623 100644
|
|
--- a/fs/pidfs.c
|
|
+++ b/fs/pidfs.c
|
|
@@ -804,7 +804,7 @@ static int pidfs_init_inode(struct inode *inode, void *data)
|
|
const struct pid *pid = data;
|
|
|
|
inode->i_private = data;
|
|
- inode->i_flags |= S_PRIVATE;
|
|
+ inode->i_flags |= S_PRIVATE | S_ANON_INODE;
|
|
inode->i_mode |= S_IRWXU;
|
|
inode->i_op = &pidfs_inode_operations;
|
|
inode->i_fop = &pidfs_file_operations;
|
|
diff --git a/include/linux/fs.h b/include/linux/fs.h
|
|
index 3e14c4eb64f4..fa47510429f0 100644
|
|
--- a/include/linux/fs.h
|
|
+++ b/include/linux/fs.h
|
|
@@ -2319,6 +2319,7 @@ struct super_operations {
|
|
#define S_CASEFOLD (1 << 15) /* Casefolded file */
|
|
#define S_VERITY (1 << 16) /* Verity file (using fs/verity/) */
|
|
#define S_KERNEL_FILE (1 << 17) /* File is in use by the kernel (eg. fs/cachefiles) */
|
|
+#define S_ANON_INODE (1 << 19) /* Inode is an anonymous inode */
|
|
|
|
/*
|
|
* Note that nosuid etc flags are inode-specific: setting some file-system
|
|
@@ -2375,6 +2376,7 @@ static inline bool sb_rdonly(const struct super_block *sb) { return sb->s_flags
|
|
|
|
#define IS_WHITEOUT(inode) (S_ISCHR(inode->i_mode) && \
|
|
(inode)->i_rdev == WHITEOUT_DEV)
|
|
+#define IS_ANON_FILE(inode) ((inode)->i_flags & S_ANON_INODE)
|
|
|
|
static inline bool HAS_UNMAPPED_ID(struct mnt_idmap *idmap,
|
|
struct inode *inode)
|
|
diff --git a/mm/readahead.c b/mm/readahead.c
|
|
index 2dbe5993b6aa..a3547f923249 100644
|
|
--- a/mm/readahead.c
|
|
+++ b/mm/readahead.c
|
|
@@ -678,29 +678,34 @@ EXPORT_SYMBOL_GPL(page_cache_async_ra);
|
|
|
|
ssize_t ksys_readahead(int fd, loff_t offset, size_t count)
|
|
{
|
|
- ssize_t ret;
|
|
- struct fd f;
|
|
+ struct file *file;
|
|
+ const struct inode *inode;
|
|
|
|
- ret = -EBADF;
|
|
- f = fdget(fd);
|
|
- if (!fd_file(f) || !(fd_file(f)->f_mode & FMODE_READ))
|
|
- goto out;
|
|
+ CLASS(fd, f)(fd);
|
|
+ if (fd_empty(f))
|
|
+ return -EBADF;
|
|
+
|
|
+ file = fd_file(f);
|
|
+ if (!(file->f_mode & FMODE_READ))
|
|
+ return -EBADF;
|
|
|
|
/*
|
|
* The readahead() syscall is intended to run only on files
|
|
* that can execute readahead. If readahead is not possible
|
|
* on this file, then we must return -EINVAL.
|
|
*/
|
|
- ret = -EINVAL;
|
|
- if (!fd_file(f)->f_mapping || !fd_file(f)->f_mapping->a_ops ||
|
|
- (!S_ISREG(file_inode(fd_file(f))->i_mode) &&
|
|
- !S_ISBLK(file_inode(fd_file(f))->i_mode)))
|
|
- goto out;
|
|
-
|
|
- ret = vfs_fadvise(fd_file(f), offset, count, POSIX_FADV_WILLNEED);
|
|
-out:
|
|
- fdput(f);
|
|
- return ret;
|
|
+ if (!file->f_mapping)
|
|
+ return -EINVAL;
|
|
+ if (!file->f_mapping->a_ops)
|
|
+ return -EINVAL;
|
|
+
|
|
+ inode = file_inode(file);
|
|
+ if (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode))
|
|
+ return -EINVAL;
|
|
+ if (IS_ANON_FILE(inode))
|
|
+ return -EINVAL;
|
|
+
|
|
+ return vfs_fadvise(fd_file(f), offset, count, POSIX_FADV_WILLNEED);
|
|
}
|
|
|
|
SYSCALL_DEFINE3(readahead, int, fd, loff_t, offset, size_t, count)
|
|
--
|
|
2.50.1 (Apple Git-155)
|
|
|