cp: odd behaviour; does not preserve symlink

Denys Vlasenko vda.linux at googlemail.com
Tue Jun 9 18:34:33 UTC 2009


On Tue, Jun 9, 2009 at 11:12 AM, Cristian
Ionescu-Idbohrn<cristian.ionescu-idbohrn at axis.com> wrote:
> this is what the gnu-tools do:
>
>        $ mkdir abc
>        $ cd abc
>
> create a dangling symlink:
>
>        $ ln -sf /tmp/foo
>        $ ls -l
>        lrwxrwxrwx 1 me users 8 Jun  9 10:35 foo -> /tmp/foo
>        $ ls -l /tmp/foo
>        ls: cannot access /tmp/foo: No such file or directory
>
>        $ cp /etc/resolv.conf foo
>        cp: not writing through dangling symlink `foo'
>        $ touch foo
>        $ ls -l /tmp/foo
>        -rw-r--r-- 1 me users 0 Jun  9 10:44 /tmp/foo
>
> /etc/resolv.conf is written through the symlink:
>
>        $ cp /etc/resolv.conf foo
>        $ ls -l /tmp/foo
>        -rw-r--r-- 1 me users 125 Jun  9 10:46 /tmp/foo
>        $ ls -l
>        lrwxrwxrwx 1 me users 8 Jun  9 10:35 foo -> /tmp/foo
>
> --- busybox ----------------------------------------
>
> BusyBox v1.14.1 (2009-06-08 17:34:46 CEST) multi-call binary
>
>        $ mkdir abc
>        $ cd abc
>        # ln -sf /tmp/foo
>        # ls -l
>        lrwxrwxrwx    1 root     root            8 Jun  9 08:50 foo -> /tmp/foo
>        # ls -l /tmp/foo
>        ls: /tmp/foo: No such file or directory
>
> 'cp' does not refuse to write through dangling symlink; overwrites the
> symlink with a file:
>
>        # cp /etc/resolv.conf foo
>        # echo $?
>        0
>        # ls -l
>        -rw-r--r--    1 root     root           71 Jun  9 08:54 foo
>
>
> 'cp' does not preserve the symlink eve if it's _not_ a dangling
> symlink:
>
>        # rm foo
>        # touch /tmp/foo
>        # ls -l /tmp/foo
>        -rw-r--r--    1 root     root            0 Jun  9 08:58 /tmp/foo
>        # ln -s /tmp/foo
>        # ls -l
>        lrwxrwxrwx    1 root     root            8 Jun  9 08:58 foo -> /tmp/foo
>        # cp /etc/resolv.conf foo
>        # echo $?
>        0
>        # ls -l
>        -rw-r--r--    1 root     root           71 Jun  9 08:58 foo
>
> Anyone else seeing this?

Yes. It's logical. cp *copies files*. IOW: it *creates a copy
of an existing file*. Copy of a file should be a file.

In this light,

cp file symlink - should not write into linked file
cp file device  - should not send file's bytes into the device

but both should either refuse to copy or delete 2nd param,
and create *an ordinary file*.

Apart from that, "cp file symlink" is a security risk.
Think about this:

cp /backup/home/joe/dissertation.htm /home/joe

What if malicious Joe created /home/joe/dissertation.htm symlink
pointing to /etc/shadow? Or to /dev/sda1?

I know that POSIX and friends do not do that. I do not know
why they chose to do stupid things and have security risks
instead of prescribing that cp is a copy operation.

If you want to dump bytes into an arbitrary entry in a directory,
the natural way is "cat >dest".
--
vda


More information about the busybox mailing list