svn commit: [25716] trunk/busybox/networking

vda at busybox.net vda at busybox.net
Wed Mar 18 14:12:24 UTC 2009


Author: vda
Date: 2009-03-18 14:12:22 +0000 (Wed, 18 Mar 2009)
New Revision: 25716

Log:
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



Modified:
   trunk/busybox/networking/ftpd.c


Changeset:
Modified: trunk/busybox/networking/ftpd.c
===================================================================
--- trunk/busybox/networking/ftpd.c	2009-03-18 11:27:49 UTC (rev 25715)
+++ trunk/busybox/networking/ftpd.c	2009-03-18 14:12:22 UTC (rev 25716)
@@ -87,7 +87,9 @@
 
 struct globals {
 	int pasv_listen_fd;
-	int proc_self_fd;
+#if !BB_MMU
+	int root_fd;
+#endif
 	int local_file_fd;
 	unsigned end_time;
 	unsigned timeout;
@@ -615,7 +617,13 @@
 popen_ls(const char *opt)
 {
 	char *cwd;
-	const char *argv[5] = { "ftpd", opt, NULL, G.ftp_arg, NULL };
+	const char *argv[] = {
+			"ftpd",
+			opt,
+			BB_MMU ? "--" : NULL,
+			G.ftp_arg,
+			NULL
+	};
 	struct fd_pair outfd;
 	pid_t pid;
 
@@ -623,25 +631,40 @@
 	xpiped_pair(outfd);
 
 	/*fflush(NULL); - so far we dont use stdio on output */
-	pid = vfork();
-	switch (pid) {
-	case -1:  /* failure */
-		bb_perror_msg_and_die("vfork");
-	case 0:  /* child */
-		/* NB: close _first_, then move fds! */
+	pid = BB_MMU ? fork() : vfork();
+	if (pid < 0)
+		bb_perror_msg_and_die(BB_MMU ? "fork" : "vfork");
+
+	if (pid == 0) {
+		/* child */
+#if !BB_MMU
+		if (fchdir(G.root_fd) != 0)
+			_exit(127);
+		close(G.root_fd);
+#endif
+		/* NB: close _first_, then move fd! */
 		close(outfd.rd);
 		xmove_fd(outfd.wr, STDOUT_FILENO);
+		/* Opening /dev/null in chroot is hard.
+		 * Just making sure STDIN_FILENO is opened
+		 * to something harmless. Paranoia,
+		 * ls won't read it anyway */
 		close(STDIN_FILENO);
-		/* xopen("/dev/null", O_RDONLY); - chroot may lack it! */
-		if (fchdir(G.proc_self_fd) == 0) {
-			close(G.proc_self_fd);
-			argv[2] = cwd;
-			/* ftpd ls helper chdirs to argv[2],
-			 * preventing peer from seeing /proc/self
-			 */
-			execv("exe", (char**) argv);
-		}
+		dup(STDOUT_FILENO); /* copy will become STDIN_FILENO */
+#if !BB_MMU
+		/* ftpd ls helper chdirs to argv[2],
+		 * preventing peer from seeing real root we are in now
+		 */
+		argv[2] = cwd;
+		/* + 1: we must use relative path here if in chroot.
+		 * For example, execv("/proc/self/exe") will fail, since
+		 * it looks for "/proc/self/exe" _relative to chroot!_ */
+		execv(CONFIG_BUSYBOX_EXEC_PATH + 1, (char**) argv);
 		_exit(127);
+#else
+		memset(&G, 0, sizeof(G));
+		exit(ls_main(ARRAY_SIZE(argv) - 1, (char**) argv));
+#endif
 	}
 
 	/* parent */
@@ -1006,15 +1029,21 @@
 	const_TYPE = mk_const4('T', 'Y', 'P', 'E'),
 	const_USER = mk_const4('U', 'S', 'E', 'R'),
 
+#if !BB_MMU
 	OPT_l = (1 << 0),
 	OPT_1 = (1 << 1),
-	OPT_v = (1 << 2),
-	OPT_S = (1 << 3),
-	OPT_w = (1 << 4),
+#endif
+	OPT_v = (1 << ((!BB_MMU) * 2 + 0)),
+	OPT_S = (1 << ((!BB_MMU) * 2 + 1)),
+	OPT_w = (1 << ((!BB_MMU) * 2 + 2)) * ENABLE_FEATURE_FTP_WRITE,
 };
 
 int ftpd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+#if !BB_MMU
 int ftpd_main(int argc, char **argv)
+#else
+int ftpd_main(int argc UNUSED_PARAM, char **argv)
+#endif
 {
 	unsigned abs_timeout;
 	smallint opts;
@@ -1024,16 +1053,20 @@
 	abs_timeout = 1 * 60 * 60;
 	G.timeout = 2 * 60;
 	opt_complementary = "t+:T+:vv";
+#if BB_MMU
+	opts = getopt32(argv,   "vS" USE_FEATURE_FTP_WRITE("w") "t:T:", &G.timeout, &abs_timeout, &G.verbose);
+#else
 	opts = getopt32(argv, "l1vS" USE_FEATURE_FTP_WRITE("w") "t:T:", &G.timeout, &abs_timeout, &G.verbose);
 	if (opts & (OPT_l|OPT_1)) {
 		/* Our secret backdoor to ls */
-		memset(&G, 0, sizeof(G));
 /* TODO: pass -n too? */
 /* --group-directories-first would be nice, but ls don't do that yet */
 		xchdir(argv[2]);
 		argv[2] = (char*)"--";
+		memset(&G, 0, sizeof(G));
 		return ls_main(argc, argv);
 	}
+#endif
 	if (abs_timeout | G.timeout) {
 		if (abs_timeout == 0)
 			abs_timeout = INT_MAX;
@@ -1065,7 +1098,9 @@
 	if (logmode)
 		applet_name = xasprintf("%s[%u]", applet_name, (int)getpid());
 
-	G.proc_self_fd = xopen("/proc/self", O_RDONLY | O_DIRECTORY);
+#if !BB_MMU
+	G.root_fd = xopen("/", O_RDONLY | O_DIRECTORY);
+#endif
 
 	if (argv[optind]) {
 		xchdir(argv[optind]);



More information about the busybox-cvs mailing list