aboutsummaryrefslogtreecommitdiff
path: root/networking/ftpd.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2009-03-18 14:12:22 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2009-03-18 14:12:22 +0000
commit5b492ee87614632e7bf5cd68fe0ce87dad30002a (patch)
tree747b5212fc9428139b29b5fb273772eebf6025da /networking/ftpd.c
parent1432cb4bd9daf304111dd19e0011f8756c32e327 (diff)
downloadbusybox-w32-5b492ee87614632e7bf5cd68fe0ce87dad30002a.tar.gz
busybox-w32-5b492ee87614632e7bf5cd68fe0ce87dad30002a.tar.bz2
busybox-w32-5b492ee87614632e7bf5cd68fe0ce87dad30002a.zip
ftpd: do not use nasty tricks for re-execing if we are on MMU machine.
On NOMMU, code is alomost the same, on MMU: function old new delta handle_dir_common 223 390 +167 ftpd_main 2306 2231 -75 popen_ls 203 - -203 ------------------------------------------------------------------------------ (add/remove: 0/1 grow/shrink: 1/1 up/down: 167/-278) Total: -111 bytes
Diffstat (limited to 'networking/ftpd.c')
-rw-r--r--networking/ftpd.c79
1 files changed, 57 insertions, 22 deletions
diff --git a/networking/ftpd.c b/networking/ftpd.c
index b295ddf4f..0a4b185a1 100644
--- a/networking/ftpd.c
+++ b/networking/ftpd.c
@@ -87,7 +87,9 @@ enum {
87 87
88struct globals { 88struct globals {
89 int pasv_listen_fd; 89 int pasv_listen_fd;
90 int proc_self_fd; 90#if !BB_MMU
91 int root_fd;
92#endif
91 int local_file_fd; 93 int local_file_fd;
92 unsigned end_time; 94 unsigned end_time;
93 unsigned timeout; 95 unsigned timeout;
@@ -615,7 +617,13 @@ static int
615popen_ls(const char *opt) 617popen_ls(const char *opt)
616{ 618{
617 char *cwd; 619 char *cwd;
618 const char *argv[5] = { "ftpd", opt, NULL, G.ftp_arg, NULL }; 620 const char *argv[] = {
621 "ftpd",
622 opt,
623 BB_MMU ? "--" : NULL,
624 G.ftp_arg,
625 NULL
626 };
619 struct fd_pair outfd; 627 struct fd_pair outfd;
620 pid_t pid; 628 pid_t pid;
621 629
@@ -623,25 +631,40 @@ popen_ls(const char *opt)
623 xpiped_pair(outfd); 631 xpiped_pair(outfd);
624 632
625 /*fflush(NULL); - so far we dont use stdio on output */ 633 /*fflush(NULL); - so far we dont use stdio on output */
626 pid = vfork(); 634 pid = BB_MMU ? fork() : vfork();
627 switch (pid) { 635 if (pid < 0)
628 case -1: /* failure */ 636 bb_perror_msg_and_die(BB_MMU ? "fork" : "vfork");
629 bb_perror_msg_and_die("vfork"); 637
630 case 0: /* child */ 638 if (pid == 0) {
631 /* NB: close _first_, then move fds! */ 639 /* child */
640#if !BB_MMU
641 if (fchdir(G.root_fd) != 0)
642 _exit(127);
643 close(G.root_fd);
644#endif
645 /* NB: close _first_, then move fd! */
632 close(outfd.rd); 646 close(outfd.rd);
633 xmove_fd(outfd.wr, STDOUT_FILENO); 647 xmove_fd(outfd.wr, STDOUT_FILENO);
648 /* Opening /dev/null in chroot is hard.
649 * Just making sure STDIN_FILENO is opened
650 * to something harmless. Paranoia,
651 * ls won't read it anyway */
634 close(STDIN_FILENO); 652 close(STDIN_FILENO);
635 /* xopen("/dev/null", O_RDONLY); - chroot may lack it! */ 653 dup(STDOUT_FILENO); /* copy will become STDIN_FILENO */
636 if (fchdir(G.proc_self_fd) == 0) { 654#if !BB_MMU
637 close(G.proc_self_fd); 655 /* ftpd ls helper chdirs to argv[2],
638 argv[2] = cwd; 656 * preventing peer from seeing real root we are in now
639 /* ftpd ls helper chdirs to argv[2], 657 */
640 * preventing peer from seeing /proc/self 658 argv[2] = cwd;
641 */ 659 /* + 1: we must use relative path here if in chroot.
642 execv("exe", (char**) argv); 660 * For example, execv("/proc/self/exe") will fail, since
643 } 661 * it looks for "/proc/self/exe" _relative to chroot!_ */
662 execv(CONFIG_BUSYBOX_EXEC_PATH + 1, (char**) argv);
644 _exit(127); 663 _exit(127);
664#else
665 memset(&G, 0, sizeof(G));
666 exit(ls_main(ARRAY_SIZE(argv) - 1, (char**) argv));
667#endif
645 } 668 }
646 669
647 /* parent */ 670 /* parent */
@@ -1006,15 +1029,21 @@ enum {
1006 const_TYPE = mk_const4('T', 'Y', 'P', 'E'), 1029 const_TYPE = mk_const4('T', 'Y', 'P', 'E'),
1007 const_USER = mk_const4('U', 'S', 'E', 'R'), 1030 const_USER = mk_const4('U', 'S', 'E', 'R'),
1008 1031
1032#if !BB_MMU
1009 OPT_l = (1 << 0), 1033 OPT_l = (1 << 0),
1010 OPT_1 = (1 << 1), 1034 OPT_1 = (1 << 1),
1011 OPT_v = (1 << 2), 1035#endif
1012 OPT_S = (1 << 3), 1036 OPT_v = (1 << ((!BB_MMU) * 2 + 0)),
1013 OPT_w = (1 << 4), 1037 OPT_S = (1 << ((!BB_MMU) * 2 + 1)),
1038 OPT_w = (1 << ((!BB_MMU) * 2 + 2)) * ENABLE_FEATURE_FTP_WRITE,
1014}; 1039};
1015 1040
1016int ftpd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 1041int ftpd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
1042#if !BB_MMU
1017int ftpd_main(int argc, char **argv) 1043int ftpd_main(int argc, char **argv)
1044#else
1045int ftpd_main(int argc UNUSED_PARAM, char **argv)
1046#endif
1018{ 1047{
1019 unsigned abs_timeout; 1048 unsigned abs_timeout;
1020 smallint opts; 1049 smallint opts;
@@ -1024,16 +1053,20 @@ int ftpd_main(int argc, char **argv)
1024 abs_timeout = 1 * 60 * 60; 1053 abs_timeout = 1 * 60 * 60;
1025 G.timeout = 2 * 60; 1054 G.timeout = 2 * 60;
1026 opt_complementary = "t+:T+:vv"; 1055 opt_complementary = "t+:T+:vv";
1056#if BB_MMU
1057 opts = getopt32(argv, "vS" USE_FEATURE_FTP_WRITE("w") "t:T:", &G.timeout, &abs_timeout, &G.verbose);
1058#else
1027 opts = getopt32(argv, "l1vS" USE_FEATURE_FTP_WRITE("w") "t:T:", &G.timeout, &abs_timeout, &G.verbose); 1059 opts = getopt32(argv, "l1vS" USE_FEATURE_FTP_WRITE("w") "t:T:", &G.timeout, &abs_timeout, &G.verbose);
1028 if (opts & (OPT_l|OPT_1)) { 1060 if (opts & (OPT_l|OPT_1)) {
1029 /* Our secret backdoor to ls */ 1061 /* Our secret backdoor to ls */
1030 memset(&G, 0, sizeof(G));
1031/* TODO: pass -n too? */ 1062/* TODO: pass -n too? */
1032/* --group-directories-first would be nice, but ls don't do that yet */ 1063/* --group-directories-first would be nice, but ls don't do that yet */
1033 xchdir(argv[2]); 1064 xchdir(argv[2]);
1034 argv[2] = (char*)"--"; 1065 argv[2] = (char*)"--";
1066 memset(&G, 0, sizeof(G));
1035 return ls_main(argc, argv); 1067 return ls_main(argc, argv);
1036 } 1068 }
1069#endif
1037 if (abs_timeout | G.timeout) { 1070 if (abs_timeout | G.timeout) {
1038 if (abs_timeout == 0) 1071 if (abs_timeout == 0)
1039 abs_timeout = INT_MAX; 1072 abs_timeout = INT_MAX;
@@ -1065,7 +1098,9 @@ int ftpd_main(int argc, char **argv)
1065 if (logmode) 1098 if (logmode)
1066 applet_name = xasprintf("%s[%u]", applet_name, (int)getpid()); 1099 applet_name = xasprintf("%s[%u]", applet_name, (int)getpid());
1067 1100
1068 G.proc_self_fd = xopen("/proc/self", O_RDONLY | O_DIRECTORY); 1101#if !BB_MMU
1102 G.root_fd = xopen("/", O_RDONLY | O_DIRECTORY);
1103#endif
1069 1104
1070 if (argv[optind]) { 1105 if (argv[optind]) {
1071 xchdir(argv[optind]); 1106 xchdir(argv[optind]);