diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2009-07-05 12:49:29 +0200 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2009-07-05 12:49:29 +0200 |
| commit | 2d7b5bfa9bd0b8096bf1ec5069fb6638d538a028 (patch) | |
| tree | 5d44e107ed6ad34e804fa14d4febf08540650f66 /libbb | |
| parent | 09e63bb81f12707d31c8c4570931af0196b53a46 (diff) | |
| download | busybox-w32-2d7b5bfa9bd0b8096bf1ec5069fb6638d538a028.tar.gz busybox-w32-2d7b5bfa9bd0b8096bf1ec5069fb6638d538a028.tar.bz2 busybox-w32-2d7b5bfa9bd0b8096bf1ec5069fb6638d538a028.zip | |
cp: by popular demand, make it POSIX compliant (but less safe)
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'libbb')
| -rw-r--r-- | libbb/Config.in | 10 | ||||
| -rw-r--r-- | libbb/copy_file.c | 18 |
2 files changed, 19 insertions, 9 deletions
diff --git a/libbb/Config.in b/libbb/Config.in index a572775c9..9b616d1af 100644 --- a/libbb/Config.in +++ b/libbb/Config.in | |||
| @@ -114,6 +114,16 @@ config FEATURE_EDITING_ASK_TERMINAL | |||
| 114 | correctly, or want to save on code size (about 300 bytes), | 114 | correctly, or want to save on code size (about 300 bytes), |
| 115 | then do not turn this option on. | 115 | then do not turn this option on. |
| 116 | 116 | ||
| 117 | config FEATURE_NON_POSIX_CP | ||
| 118 | bool "Non-POSIX, but safer, copying to special nodes" | ||
| 119 | default y | ||
| 120 | help | ||
| 121 | With this option, "cp file symlink" will delete symlink | ||
| 122 | and create a regular file. This does not conform to POSIX, | ||
| 123 | but prevents a symlink attack. | ||
| 124 | Similarly, "cp file device" will not send file's data | ||
| 125 | to the device. | ||
| 126 | |||
| 117 | config FEATURE_VERBOSE_CP_MESSAGE | 127 | config FEATURE_VERBOSE_CP_MESSAGE |
| 118 | bool "Give more precise messages when copy fails (cp, mv etc)" | 128 | bool "Give more precise messages when copy fails (cp, mv etc)" |
| 119 | default n | 129 | default n |
diff --git a/libbb/copy_file.c b/libbb/copy_file.c index d804eccfa..4d2f17aa5 100644 --- a/libbb/copy_file.c +++ b/libbb/copy_file.c | |||
| @@ -8,9 +8,10 @@ | |||
| 8 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. | 8 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
| 9 | * | 9 | * |
| 10 | */ | 10 | */ |
| 11 | |||
| 12 | #include "libbb.h" | 11 | #include "libbb.h" |
| 13 | 12 | ||
| 13 | // FEATURE_NON_POSIX_CP: | ||
| 14 | // | ||
| 14 | // POSIX: if exists and -i, ask (w/o -i assume yes). | 15 | // POSIX: if exists and -i, ask (w/o -i assume yes). |
| 15 | // Then open w/o EXCL (yes, not unlink!). | 16 | // Then open w/o EXCL (yes, not unlink!). |
| 16 | // If open still fails and -f, try unlink, then try open again. | 17 | // If open still fails and -f, try unlink, then try open again. |
| @@ -23,22 +24,21 @@ | |||
| 23 | // NB: we have special code which still allows for "cp file /dev/node" | 24 | // NB: we have special code which still allows for "cp file /dev/node" |
| 24 | // to work POSIX-ly (the only realistic case where it makes sense) | 25 | // to work POSIX-ly (the only realistic case where it makes sense) |
| 25 | 26 | ||
| 26 | #define DO_POSIX_CP 0 /* 1 - POSIX behavior, 0 - safe behavior */ | ||
| 27 | |||
| 28 | // errno must be set to relevant value ("why we cannot create dest?") | 27 | // errno must be set to relevant value ("why we cannot create dest?") |
| 29 | // for POSIX mode to give reasonable error message | 28 | // for POSIX mode to give reasonable error message |
| 30 | static int ask_and_unlink(const char *dest, int flags) | 29 | static int ask_and_unlink(const char *dest, int flags) |
| 31 | { | 30 | { |
| 32 | int e = errno; | 31 | int e = errno; |
| 33 | #if DO_POSIX_CP | 32 | #if !ENABLE_FEATURE_NON_POSIX_CP |
| 34 | if (!(flags & (FILEUTILS_FORCE|FILEUTILS_INTERACTIVE))) { | 33 | if (!(flags & (FILEUTILS_FORCE|FILEUTILS_INTERACTIVE))) { |
| 35 | // Either it exists, or the *path* doesnt exist | 34 | // Either it exists, or the *path* doesnt exist |
| 36 | bb_perror_msg("cannot create '%s'", dest); | 35 | bb_perror_msg("cannot create '%s'", dest); |
| 37 | return -1; | 36 | return -1; |
| 38 | } | 37 | } |
| 39 | #endif | 38 | #endif |
| 40 | // If !DO_POSIX_CP, act as if -f is always in effect - we don't want | 39 | // If ENABLE_FEATURE_NON_POSIX_CP, act as if -f is always in effect |
| 41 | // "cannot create" msg, we want unlink to be done (silently unless -i). | 40 | // - we don't want "cannot create" msg, we want unlink to be done |
| 41 | // (silently unless -i). | ||
| 42 | 42 | ||
| 43 | // TODO: maybe we should do it only if ctty is present? | 43 | // TODO: maybe we should do it only if ctty is present? |
| 44 | if (flags & FILEUTILS_INTERACTIVE) { | 44 | if (flags & FILEUTILS_INTERACTIVE) { |
| @@ -279,10 +279,10 @@ int FAST_FUNC copy_file(const char *source, const char *dest, int flags) | |||
| 279 | * non-interactive cp. NB: it is still racy | 279 | * non-interactive cp. NB: it is still racy |
| 280 | * for "cp file /home/bad_user/file" case | 280 | * for "cp file /home/bad_user/file" case |
| 281 | * (user can rm file and create a link to /etc/passwd) */ | 281 | * (user can rm file and create a link to /etc/passwd) */ |
| 282 | if (DO_POSIX_CP | 282 | if (!ENABLE_FEATURE_NON_POSIX_CP |
| 283 | || (dest_exists | 283 | || (dest_exists |
| 284 | && !(flags & (FILEUTILS_RECUR|FILEUTILS_INTERACTIVE)) | 284 | && !(flags & (FILEUTILS_RECUR|FILEUTILS_INTERACTIVE)) |
| 285 | && !S_ISLNK(dest_stat.st_mode)) | 285 | && !S_ISLNK(dest_stat.st_mode)) |
| 286 | ) { | 286 | ) { |
| 287 | dst_fd = open(dest, O_WRONLY|O_CREAT|O_TRUNC, new_mode); | 287 | dst_fd = open(dest, O_WRONLY|O_CREAT|O_TRUNC, new_mode); |
| 288 | } else /* safe way: */ | 288 | } else /* safe way: */ |
