Hi BusyBox maintainers,
I’m working on a performance optimization and would like to explore adding noexec support for sed and grep. The motivation is to reduce fork/exec overhead in constrained environments by executing sed/grep in-process when they are invoked via BusyBox applet dispatch (similar in spirit to existing noexec-related optimizations). I have an initial implementation attached below, where: • sed and grep are marked as noexec-capable applets • the change is intended purely as a performance optimization Before refining or splitting this further, I’d like to confirm whether this direction is acceptable, and whether there are known concerns in sed/grep internals that would make noexec unsuitable. Thanks for your time and feedback. Signed-off-by: Ren Chunhui <[email protected]<mailto:[email protected]>> editors/sed.c | 2 +- findutils/grep.c | 2 +- include/libbb.h | 2 ++ libbb/appletlib.c | 29 +++++++++++++++++++++++++++++ shell/ash.c | 2 +- 5 files changed, 34 insertions(+), 3 deletions(-) diff --git a/editors/sed.c b/editors/sed.c index 6179c5e..10fb3d9 100644 --- a/editors/sed.c +++ b/editors/sed.c @@ -60,7 +60,7 @@ //config: sed is used to perform text transformations on a file //config: or input from a pipeline. -//applet:IF_SED(APPLET(sed, BB_DIR_BIN, BB_SUID_DROP)) +//applet:IF_SED(APPLET_NOEXEC(sed, sed, BB_DIR_BIN, BB_SUID_DROP, sed)) //kbuild:lib-$(CONFIG_SED) += sed.o diff --git a/findutils/grep.c b/findutils/grep.c index f6d0a73..7cb89da 100644 --- a/findutils/grep.c +++ b/findutils/grep.c @@ -44,7 +44,7 @@ //config: context surrounding our matching lines. //config: Print the specified number of context lines (-C). -//applet:IF_GREP(APPLET(grep, BB_DIR_BIN, BB_SUID_DROP)) +//applet:IF_GREP(APPLET_NOEXEC(grep, grep, BB_DIR_BIN, BB_SUID_DROP, grep)) // APPLET_ODDNAME:name main location suid_type help //applet:IF_EGREP(APPLET_ODDNAME(egrep, grep, BB_DIR_BIN, BB_SUID_DROP, egrep)) //applet:IF_FGREP(APPLET_ODDNAME(fgrep, grep, BB_DIR_BIN, BB_SUID_DROP, fgrep)) diff --git a/include/libbb.h b/include/libbb.h index 01cdb1b..6704213 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -2658,6 +2658,8 @@ void bbunit_settestfailed(void); } \ } while (0) +extern bool is_applet_forbidden_noexec(int applet_no); +extern bool is_applet_force_noexec(int applet_no); POP_SAVED_FUNCTION_VISIBILITY diff --git a/libbb/appletlib.c b/libbb/appletlib.c index d9cc484..915049d 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c @@ -1129,3 +1129,32 @@ int main(int argc UNUSED_PARAM, char **argv) #endif } + +static bool is_forbidden_noexec[NUM_APPLETS] = { + [66] = true, // APPLET_NO_gzip + [140] = true, // APPLET_NO_ps + [85] = true, // APPLET_NO_ip + [183] = true, // APPLET_NO_top + [106] = true, // APPLET_NO_lsattr + [177] = true, // APPLET_NO_taskset +}; + +bool is_applet_forbidden_noexec(int applet_no) +{ + if (applet_no < 0 || applet_no >= NUM_APPLETS) + return false; + return is_forbidden_noexec[applet_no]; +} + +static bool is_force_noexec[NUM_APPLETS] = { + [6] = true, // APPLET_NO_awk + //[63] = true, // APPLET_NO_grep + [157] = true, // APPLET_NO_sed +}; + +bool is_applet_force_noexec(int applet_no) +{ + if (applet_no < 0 || applet_no >= NUM_APPLETS) + return false; + return is_force_noexec[applet_no]; +} diff --git a/shell/ash.c b/shell/ash.c index bbd7307..8e83dab 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -8336,7 +8336,7 @@ static void shellexec(char *prog, char **argv, const char *path, int idx) envp = listvars(VEXPORT, VUNSET, /*strlist:*/ NULL, /*end:*/ NULL); if (strchr(prog, '/') != NULL #if ENABLE_FEATURE_SH_STANDALONE - || (applet_no = find_applet_by_name(prog)) >= 0 + || (((applet_no = find_applet_by_name(prog)) >= 0) + && !is_applet_forbidden_noexec(applet_no) + && is_applet_force_noexec(applet_no)) #endif ) { tryexec(IF_FEATURE_SH_STANDALONE(applet_no,) prog, argv, envp); -- 2.37.7
_______________________________________________ busybox mailing list [email protected] https://lists.busybox.net/mailman/listinfo/busybox
