nofork_noexec.txt 4.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. NOEXEC and NOFORK applets.
  2. Unix shells traditionally execute some commands internally in the attempt
  3. to dramatically speed up execution. It will be slow as hell if for every
  4. "echo blah" shell will fork and exec /bin/echo. To this end, shells
  5. have to _reimplement_ these commands internally.
  6. Busybox is unique in this regard because it already is a collection
  7. of reimplemented Unix commands, and we can do the same trick
  8. for speeding up busybox shells, and more. NOEXEC and NOFORK applets
  9. are exactly those applets which are eligible for these tricks.
  10. Applet will be subject to NOFORK/NOEXEC tricks if it is marked as such
  11. in applets.h. FEATURE_PREFER_APPLETS is a config option which
  12. globally enables usage of NOFORK/NOEXEC tricks.
  13. If it is enabled, FEATURE_SH_STANDALONE can be enabled too,
  14. and then shells will use NOFORK/NOEXEC tricks for ordinary commands.
  15. NB: shell builtins use these tricks regardless of FEATURE_SH_STANDALONE
  16. or FEATURE_PREFER_APPLETS.
  17. In C, if you want to call a program and wait for it, use
  18. spawn_and_wait(argv), BB_EXECVP(prog,argv) or BB_EXECLP(prog,argv0,...).
  19. They check whether program name is an applet name and optionally
  20. do NOFORK/NOEXEC thing depending on configuration.
  21. NOEXEC
  22. NOEXEC applet should work correctly if another applet forks and then
  23. executes exit(<applet>_main(argc,argv)) in the child. The rules
  24. roughly are:
  25. * do not expect shared global variables/buffers to be in their
  26. "initialized" state. Examples: xfunc_error_retval can be != 1,
  27. bb_common_bufsiz1 can be scribbled over, ...
  28. * do not expect that stdio wasn't used before. Calling set[v]buf()
  29. can be disastrous.
  30. * ...
  31. NOEXEC applets save only one half of fork+exec overhead.
  32. NOEXEC trick is disabled for NOMMU build.
  33. NOFORK
  34. NOFORK applet should work correctly if another applet simply runs
  35. <applet>_main(argc,argv) and then continues with its business.
  36. xargs, find, shells do it (grep for "spawn_and_wait" and
  37. "run_nofork_applet" to find more users).
  38. This poses much more serious limitations on what applet can do:
  39. * all NOEXEC limitations apply.
  40. * do not ever exit() or exec().
  41. - xfuncs are okay. They are using special trick to return
  42. to the caller applet instead of dying when they detect "x" condition.
  43. - you may "exit" to caller applet by calling xfunc_die(). Return value
  44. is taken from xfunc_error_retval.
  45. - fflush_stdout_and_exit(n) is ok to use.
  46. * do not use shared global data, or save/restore shared global data
  47. (e.g. bb_common_bufsiz1) prior to returning.
  48. - getopt32() is ok to use. You do not need to save/restore option_mask32,
  49. it is already done by core code.
  50. * if you allocate memory, you can use xmalloc() only on the very first
  51. allocation. All other allocations should use malloc[_or_warn]().
  52. After first allocation, you cannot use any xfuncs.
  53. Otherwise, failing xfunc will return to caller applet
  54. without freeing malloced data!
  55. * All allocated data, opened files, signal handlers, termios settings,
  56. O_NONBLOCK flags etc should be freed/closed/restored prior to return.
  57. * ...
  58. NOFORK applets give the most of speed advantage, but are trickiest
  59. to implement. In order to minimize amount of bugs and maintenance,
  60. prime candidates for NOFORK-ification are those applets which
  61. are small and easy to audit, and those which are more likely to be
  62. frequently executed from shell/find/xargs, particularly in shell
  63. script loops. Applets which mess with signal handlers, termios etc
  64. are probably not worth the effort.
  65. Any NOFORK applet is also a NOEXEC applet.
  66. Relevant CONFIG options
  67. FEATURE_PREFER_APPLETS
  68. BB_EXECVP(cmd, argv) will try to exec /proc/self/exe
  69. if command's name matches some applet name
  70. applet tables will contain NOFORK/NOEXEC bits
  71. spawn_and_wait(argv) will do NOFORK/NOEXEC tricks
  72. FEATURE_SH_STANDALONE (needs FEATURE_PREFER_APPLETS=y)
  73. shells will try to exec /proc/self/exe if command's name matches
  74. some applet name
  75. shells will do NOEXEC trick on NOEXEC applets
  76. FEATURE_SH_NOFORK (needs FEATURE_PREFER_APPLETS=y)
  77. shells will do NOFORK trick on NOFORK applets