]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
fs/file: fix the check in find_next_fd()
authorYuntao Wang <yuntao.wang@linux.dev>
Wed, 29 May 2024 16:06:56 +0000 (00:06 +0800)
committerChristian Brauner <brauner@kernel.org>
Thu, 30 May 2024 07:11:47 +0000 (09:11 +0200)
The maximum possible return value of find_next_zero_bit(fdt->full_fds_bits,
maxbit, bitbit) is maxbit. This return value, multiplied by BITS_PER_LONG,
gives the value of bitbit, which can never be greater than maxfd, it can
only be equal to maxfd at most, so the following check 'if (bitbit > maxfd)'
will never be true.

Moreover, when bitbit equals maxfd, it indicates that there are no unused
fds, and the function can directly return.

Fix this check.

Signed-off-by: Yuntao Wang <yuntao.wang@linux.dev>
Link: https://lore.kernel.org/r/20240529160656.209352-1-yuntao.wang@linux.dev
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Christian Brauner <brauner@kernel.org>
fs/file.c

index 8076aef9c21011f6d52ff2366354d921c47cb2fc..a3b72aa64f1164380fdaa6524081a4ac956831da 100644 (file)
--- a/fs/file.c
+++ b/fs/file.c
@@ -486,12 +486,12 @@ struct files_struct init_files = {
 
 static unsigned int find_next_fd(struct fdtable *fdt, unsigned int start)
 {
-       unsigned int maxfd = fdt->max_fds;
+       unsigned int maxfd = fdt->max_fds; /* always multiple of BITS_PER_LONG */
        unsigned int maxbit = maxfd / BITS_PER_LONG;
        unsigned int bitbit = start / BITS_PER_LONG;
 
        bitbit = find_next_zero_bit(fdt->full_fds_bits, maxbit, bitbit) * BITS_PER_LONG;
-       if (bitbit > maxfd)
+       if (bitbit >= maxfd)
                return maxfd;
        if (bitbit > start)
                start = bitbit;