Allow CLOSE_RANGE actions to pass newfd == -1 to mean the largest
possible fd. This gives userspace a compact way to request the common
close_range(first, ~0U, flags) pattern even though the UAPI action uses
signed fd fields so OPEN actions can still carry AT_FDCWD.
Signed-off-by: Li Chen <redacted>
---
Documentation/userspace-api/spawn_template.rst | 3 ++-
fs/spawn_template.c | 10 +++++++---
2 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/Documentation/userspace-api/spawn_template.rst b/Documentation/userspace-api/spawn_template.rst
index afe215e51db6f..be66be20d4fde 100644
--- a/Documentation/userspace-api/spawn_template.rst
+++ b/Documentation/userspace-api/spawn_template.rst
@@ -86,7 +86,8 @@ kind of setup that ``posix_spawn_file_actions_t`` commonly performs:
Open a path using ``struct open_how`` and install it at ``newfd``.
``SPAWN_TEMPLATE_ACTION_CLOSE_RANGE``
- Apply ``close_range()`` to a child fd range.
+ Apply ``close_range()`` to a child fd range. Passing ``newfd == -1`` means
+ the range extends to the largest possible fd.
``SPAWN_TEMPLATE_ACTION_SIGMASK``
Set the child signal mask.
diff --git a/fs/spawn_template.c b/fs/spawn_template.c
index 6430a6645fb57..82b833bc9865a 100644
--- a/fs/spawn_template.c
+++ b/fs/spawn_template.c
@@ -220,6 +220,8 @@ static int spawn_template_apply_sigdefault(const struct spawn_template_action *a
static int spawn_template_apply_action(const struct spawn_template_action *action)
{
+ unsigned int max_fd;
+
switch (action->type) {
case SPAWN_TEMPLATE_ACTION_CLOSE:
return close_fd(action->fd);@@ -251,7 +253,8 @@ static int spawn_template_apply_action(const struct spawn_template_action *actio
case SPAWN_TEMPLATE_ACTION_OPEN:
return spawn_template_apply_open(action);
case SPAWN_TEMPLATE_ACTION_CLOSE_RANGE:
- return do_close_range(action->fd, action->newfd, action->flags);
+ max_fd = action->newfd == -1 ? ~0U : action->newfd;
+ return do_close_range(action->fd, max_fd, action->flags);
case SPAWN_TEMPLATE_ACTION_SIGMASK:
return spawn_template_apply_sigmask(action);
case SPAWN_TEMPLATE_ACTION_SIGDEFAULT:
@@ -306,8 +309,9 @@ static int spawn_template_copy_actions(struct spawn_template_action **out_action
return -EINVAL;
break;
case SPAWN_TEMPLATE_ACTION_CLOSE_RANGE:
- if (actions[i].fd < 0 || actions[i].newfd < 0 ||
- actions[i].fd > actions[i].newfd ||
+ if (actions[i].fd < 0 || actions[i].newfd < -1 ||
+ (actions[i].newfd >= 0 &&
+ actions[i].fd > actions[i].newfd) ||
(actions[i].flags &
~(CLOSE_RANGE_UNSHARE | CLOSE_RANGE_CLOEXEC)) ||
actions[i].arg)
--
2.52.0