svn commit: trunk/busybox/libbb

vda at busybox.net vda at busybox.net
Tue Sep 11 10:39:14 UTC 2007


Author: vda
Date: 2007-09-11 03:39:13 -0700 (Tue, 11 Sep 2007)
New Revision: 19815

Log:
cp: make "cp file /dev/node" special case; explained in comments

function                                             old     new   delta
copy_file                                           1487    1538     +51
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 51/0)               Total: 51 bytes
   text    data     bss     dec     hex filename
 772502    1051   10724  784277   bf795 busybox_old
 772554    1051   10724  784329   bf7c9 busybox_unstripped



Modified:
   trunk/busybox/libbb/copy_file.c


Changeset:
Modified: trunk/busybox/libbb/copy_file.c
===================================================================
--- trunk/busybox/libbb/copy_file.c	2007-09-10 17:17:01 UTC (rev 19814)
+++ trunk/busybox/libbb/copy_file.c	2007-09-11 10:39:13 UTC (rev 19815)
@@ -19,6 +19,9 @@
 // (or fail, if it points to dir/nonexistent location/etc).
 // This is strange, but POSIX-correct.
 // coreutils cp has --remove-destination to override this...
+//
+// NB: we have special code which still allows for "cp file /dev/node"
+// to work POSIX-ly (the only realistic case where it makes sense)
 
 #define DO_POSIX_CP 0  /* 1 - POSIX behavior, 0 - safe behavior */
 
@@ -243,13 +246,18 @@
 		if (src_fd < 0)
 			return -1;
 
-#if DO_POSIX_CP  /* POSIX way (a security problem versus symlink attacks!): */
-		dst_fd = open(dest, (flags & FILEUTILS_INTERACTIVE)
-				? O_WRONLY|O_CREAT|O_EXCL
-				: O_WRONLY|O_CREAT|O_TRUNC, source_stat.st_mode);
-#else  /* safe way: */
-		dst_fd = open(dest, O_WRONLY|O_CREAT|O_EXCL, source_stat.st_mode);
-#endif
+		/* POSIX way is a security problem versus symlink attacks,
+		 * we do it only for dest's which are device nodes,
+		 * and only for non-recursive, non-interactive cp. NB: it is still racy
+		 * for "cp file /home/bad_user/device_node" case
+		 * (user can rm device_node and create link to /etc/passwd) */
+		if (DO_POSIX_CP
+		 || (dest_exists && !(flags & (FILEUTILS_RECUR|FILEUTILS_INTERACTIVE))
+		     && (S_ISBLK(dest_stat.st_mode) || S_ISCHR(dest_stat.st_mode)))
+		) {
+			dst_fd = open(dest, O_WRONLY|O_CREAT|O_TRUNC, source_stat.st_mode);
+		} else  /* safe way: */
+			dst_fd = open(dest, O_WRONLY|O_CREAT|O_EXCL, source_stat.st_mode);
 		if (dst_fd == -1) {
 			ovr = ask_and_unlink(dest, flags);
 			if (ovr <= 0) {




More information about the busybox-cvs mailing list