Commit 03ba0fe4 authored by Christian Brauner's avatar Christian Brauner

file: simplify logic in __close_range()

It never looked too pleasant and it doesn't really buy us anything
anymore now that CLOSE_RANGE_CLOEXEC exists and we need to retake the
current maximum under the lock for it anyway. This also makes the logic
easier to follow.

Cc: Christoph Hellwig <hch@lst.de>
Cc: Giuseppe Scrivano <gscrivan@redhat.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: linux-fsdevel@vger.kernel.org
Signed-off-by: default avatarChristian Brauner <christian.brauner@ubuntu.com>
parent f49fd6d3
...@@ -701,7 +701,6 @@ static inline void __range_close(struct files_struct *cur_fds, unsigned int fd, ...@@ -701,7 +701,6 @@ static inline void __range_close(struct files_struct *cur_fds, unsigned int fd,
*/ */
int __close_range(unsigned fd, unsigned max_fd, unsigned int flags) int __close_range(unsigned fd, unsigned max_fd, unsigned int flags)
{ {
unsigned int cur_max;
struct task_struct *me = current; struct task_struct *me = current;
struct files_struct *cur_fds = me->files, *fds = NULL; struct files_struct *cur_fds = me->files, *fds = NULL;
...@@ -711,26 +710,26 @@ int __close_range(unsigned fd, unsigned max_fd, unsigned int flags) ...@@ -711,26 +710,26 @@ int __close_range(unsigned fd, unsigned max_fd, unsigned int flags)
if (fd > max_fd) if (fd > max_fd)
return -EINVAL; return -EINVAL;
rcu_read_lock();
cur_max = files_fdtable(cur_fds)->max_fds;
rcu_read_unlock();
/* cap to last valid index into fdtable */
cur_max--;
if (flags & CLOSE_RANGE_UNSHARE) { if (flags & CLOSE_RANGE_UNSHARE) {
int ret; int ret;
unsigned int max_unshare_fds = NR_OPEN_MAX; unsigned int max_unshare_fds = NR_OPEN_MAX;
/* /*
* If the requested range is greater than the current maximum, * If the caller requested all fds to be made cloexec we always
* we're closing everything so only copy all file descriptors * copy all of the file descriptors since they still want to
* beneath the lowest file descriptor. * use them.
* If the caller requested all fds to be made cloexec copy all */
* of the file descriptors since they still want to use them. if (!(flags & CLOSE_RANGE_CLOEXEC)) {
/*
* If the requested range is greater than the current
* maximum, we're closing everything so only copy all
* file descriptors beneath the lowest file descriptor.
*/ */
if (!(flags & CLOSE_RANGE_CLOEXEC) && (max_fd >= cur_max)) rcu_read_lock();
if (max_fd >= last_fd(files_fdtable(cur_fds)))
max_unshare_fds = fd; max_unshare_fds = fd;
rcu_read_unlock();
}
ret = unshare_fd(CLONE_FILES, max_unshare_fds, &fds); ret = unshare_fd(CLONE_FILES, max_unshare_fds, &fds);
if (ret) if (ret)
...@@ -744,8 +743,6 @@ int __close_range(unsigned fd, unsigned max_fd, unsigned int flags) ...@@ -744,8 +743,6 @@ int __close_range(unsigned fd, unsigned max_fd, unsigned int flags)
swap(cur_fds, fds); swap(cur_fds, fds);
} }
max_fd = min(max_fd, cur_max);
if (flags & CLOSE_RANGE_CLOEXEC) if (flags & CLOSE_RANGE_CLOEXEC)
__range_cloexec(cur_fds, fd, max_fd); __range_cloexec(cur_fds, fd, max_fd);
else else
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment