On Mon, 27 Jan 2025, Nadav Tasher wrote:
This patch makes BB_EXECVP the gateway to the exec syscall
family.
When called, it first looks for a matching applet, and
executes it directly of indirectly by re-executing the
binary. This new behaviour is configurable by the new
FEATURE_FORCE_NOEXEC option.
I'm pretty sure that applets not marked NOEXEC won't work well
unless you use an exec syscall, so this FORCE_NOEXEC seems pretty
dubious. Can you separate this feature from this series?
When FEATURE_FORCE_APPLETS is enabled, BB_EXECVP will
fail when trying to execute things that are not busybox
applets. This allows more control over the executed
processes.
This is more of a restriction, than a force. Good names are hard,
but something like FEATURE_EXEC_ONLY_APPLETS would be clearer?
BB_EXECVPE is introduced to support passing seperate
environment to a BB_EXECVP call, and uses the new
copy_terminated_string_array function to backup the
current environ. This mimics the behaviour of execvpe.
[...]
+char** copy_terminated_string_array(char **array) {
Ah, I was thinking that you could avoid any string copying of environ[] by
committing to use the envp argument only when you know the applet is known
and is NOEXEC. The relevant equivalence I think is:
BB_EXECVP(p,a) === BB_EXECVPE(p,a,environ)
Because the only error you expect from BB_EXECVPE on an applet is ENOENT,
then you can try find_applet_by_name() early, and return -1 without ever
touching environ. Also, since you expect the BB_EXEC* not to return on
success, there's no need to save the environ.
The sketch looks like this:
extern char **environ;
BB_EXECVP(file, argv)
{
/* passing environ indicates we're not changing it */
return BB_EXECVPE(file, argv, environ);
}
BB_EXECVPE(file, argv, envp)
{
applet = -1;
if (ENABLE_FEATURE_PREFER_APPLETS &&
(applet = find_applet_by_name(file)) > 0 &&
!APPLET_IS_NOEXEC(applet))
{
if (env != environ) {
clearenv();
for (e in envp) putenv(e);
}
exec_applet(...); /* noreturn */
} else {
if (ENABLE_FEATURE_FORCE_APPLETS) {
errno = applet < 0 ? ENOENT : ENOEXEC;
return -1;
}
if (envp == environ)
return execv(file, argv);
else
return execve(file, argv, envp);
}
}
_______________________________________________
busybox mailing list
[email protected]
https://lists.busybox.net/mailman/listinfo/busybox