Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
- fs/file.c | 28 +++++++--------
- include/linux/bitmap.h | 12 +++++++
- .../testing/selftests/core/close_range_test.c | 35 +++++++++++++++++++
- 3 files changed, 59 insertions(+), 16 deletions(-)
+ fs/file.c | 28 ++++++++++++----------------
+ include/linux/bitmap.h | 12 ++++++++++++
+ 2 files changed, 24 insertions(+), 16 deletions(-)
-diff --git a/fs/file.c b/fs/file.c
-index a11e59b5d602..655338effe9c 100644
--- a/fs/file.c
+++ b/fs/file.c
-@@ -46,27 +46,23 @@ static void free_fdtable_rcu(struct rcu_head *rcu)
+@@ -41,27 +41,23 @@ static void free_fdtable_rcu(struct rcu_
#define BITBIT_NR(nr) BITS_TO_LONGS(BITS_TO_LONGS(nr))
#define BITBIT_SIZE(nr) (BITBIT_NR(nr) * sizeof(long))
}
/*
-@@ -84,7 +80,7 @@ static void copy_fdtable(struct fdtable *nfdt, struct fdtable *ofdt)
+@@ -79,7 +75,7 @@ static void copy_fdtable(struct fdtable
memcpy(nfdt->fd, ofdt->fd, cpy);
memset((char *)nfdt->fd + cpy, 0, set);
+ copy_fd_bitmaps(nfdt, ofdt, fdt_words(ofdt));
}
- /*
-@@ -379,7 +375,7 @@ struct files_struct *dup_fd(struct files_struct *oldf, unsigned int max_fds, int
- open_files = sane_fdtable_size(old_fdt, max_fds);
+ static struct fdtable * alloc_fdtable(unsigned int nr)
+@@ -330,7 +326,7 @@ struct files_struct *dup_fd(struct files
+ open_files = count_open_files(old_fdt);
}
- copy_fd_bitmaps(new_fdt, old_fdt, open_files);
old_fds = old_fdt->fd;
new_fds = new_fdt->fd;
-diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h
-index 8c4768c44a01..d3b66d77df7a 100644
--- a/include/linux/bitmap.h
+++ b/include/linux/bitmap.h
-@@ -270,6 +270,18 @@ static inline void bitmap_copy_clear_tail(unsigned long *dst,
+@@ -254,6 +254,18 @@ static inline void bitmap_copy_clear_tai
dst[nbits / BITS_PER_LONG] &= BITMAP_LAST_WORD_MASK(nbits);
}
+}
+
/*
- * On 32-bit systems bitmaps are represented as u32 arrays internally. On LE64
- * machines the order of hi and lo parts of numbers match the bitmap structure.
-diff --git a/tools/testing/selftests/core/close_range_test.c b/tools/testing/selftests/core/close_range_test.c
-index 991c473e3859..12b4eb9d0434 100644
---- a/tools/testing/selftests/core/close_range_test.c
-+++ b/tools/testing/selftests/core/close_range_test.c
-@@ -589,4 +589,39 @@ TEST(close_range_cloexec_unshare_syzbot)
- EXPECT_EQ(close(fd3), 0);
- }
-
-+TEST(close_range_bitmap_corruption)
-+{
-+ pid_t pid;
-+ int status;
-+ struct __clone_args args = {
-+ .flags = CLONE_FILES,
-+ .exit_signal = SIGCHLD,
-+ };
-+
-+ /* get the first 128 descriptors open */
-+ for (int i = 2; i < 128; i++)
-+ EXPECT_GE(dup2(0, i), 0);
-+
-+ /* get descriptor table shared */
-+ pid = sys_clone3(&args, sizeof(args));
-+ ASSERT_GE(pid, 0);
-+
-+ if (pid == 0) {
-+ /* unshare and truncate descriptor table down to 64 */
-+ if (sys_close_range(64, ~0U, CLOSE_RANGE_UNSHARE))
-+ exit(EXIT_FAILURE);
-+
-+ ASSERT_EQ(fcntl(64, F_GETFD), -1);
-+ /* ... and verify that the range 64..127 is not
-+ stuck "fully used" according to secondary bitmap */
-+ EXPECT_EQ(dup(0), 64)
-+ exit(EXIT_FAILURE);
-+ exit(EXIT_SUCCESS);
-+ }
-+
-+ EXPECT_EQ(waitpid(pid, &status, 0), pid);
-+ EXPECT_EQ(true, WIFEXITED(status));
-+ EXPECT_EQ(0, WEXITSTATUS(status));
-+}
-+
- TEST_HARNESS_MAIN
---
-2.46.0
-
+ * On 32-bit systems bitmaps are represented as u32 arrays internally, and
+ * therefore conversion is not needed when copying data from/to arrays of u32.