If the fdtable is unshared or the task exits we can't install reservations. The reserved fd isn't reserved anymore. execve() would leak the reservation into the child. Signed-off-by: Christian Brauner (Amutable) --- fs/exec.c | 3 +++ kernel/fork.c | 2 ++ 2 files changed, 5 insertions(+) diff --git a/fs/exec.c b/fs/exec.c index 745f6eb5279e..1aa0f7b99fc3 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1159,6 +1159,9 @@ int begin_new_exec(struct linux_binprm * bprm) */ io_uring_task_cancel(); + /* A prepared descriptor would be installed into the new program. */ + VFS_WARN_ON_ONCE(me->fd_slots.nr); + /* Ensure the files table is not shared. */ retval = unshare_files(); if (retval) diff --git a/kernel/fork.c b/kernel/fork.c index 59c5cfa3e482..bd0e1e85abb0 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -3217,6 +3217,8 @@ static int unshare_fd(unsigned long unshare_flags, struct files_struct **new_fdp if ((unshare_flags & CLONE_FILES) && (fd && atomic_read(&fd->count) > 1)) { + /* Prepared descriptors live in the table we are about to leave. */ + VFS_WARN_ON_ONCE(current->fd_slots.nr); fd = dup_fd(fd, NULL); if (IS_ERR(fd)) return PTR_ERR(fd); -- 2.53.0