On Tuesday 11 September 2007 00:19, Alexander Kriegisch wrote: > In SVN rev. #18119 [1] the default behaviour of 'cp' was changed by > Denis in order to improve security and also to save a few bytes. This > leads to problems in our application scenario here: We work on a > mipsel-based router platform equipped with a TFFS (tiny flash > filesystem) showing several "files" as character devices. Copying new > contents over existing files results in the character devices being > unlinked and regular files being created instead, which is a problem > because they are not saved back into the flash memory, thus the changes > are not persistent. We have to use 'cat' in order to fix this. > > Denis, would you please consider making the hard-coded value of > DO_POSIX_CP configurable? I could provide a patch, if needed, but it > should be pretty straightforward and will probably be cleaner if you do > it yourself. This way the default would still be the one you prefer and > our firmware mod using a newer BB version than the original one would > still work if we just changed this config option.
Try this, is it good enough? -- vda
diff -d -urpN busybox.8/libbb/copy_file.c busybox.9/libbb/copy_file.c --- busybox.8/libbb/copy_file.c 2007-09-06 20:05:34.000000000 +0100 +++ busybox.9/libbb/copy_file.c 2007-09-11 11:30:45.000000000 +0100 @@ -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 @@ int copy_file(const char *source, const 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) {
_______________________________________________ busybox mailing list busybox@busybox.net http://busybox.net/cgi-bin/mailman/listinfo/busybox