public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Al Viro <viro@ZenIV.linux.org.uk>
To: Piotr Karbowski <piotr.karbowski@gmail.com>
Cc: linux-kernel@vger.kernel.org
Subject: Re: [BUG] rename() from outside of the target dir breaks /proc exe symlink.
Date: Sat, 27 Dec 2014 18:14:13 +0000	[thread overview]
Message-ID: <20141227181412.GG22149@ZenIV.linux.org.uk> (raw)
In-Reply-To: <549EEEEA.1050306@gmail.com>

On Sat, Dec 27, 2014 at 06:39:54PM +0100, Piotr Karbowski wrote:
> Hi,
> 
> There's something wrong about exe symlink that can be found insde
> /proc/<pid>/ directories. When the running binary is replaced with
> another, using rename() call, the symlink may point to wrong path.
> 
> As example let me use sshd. I have running sshd from /usr/sbin. If I
> replace /usr/sbin/sshd one could expect to see exe symlink pointing
> to '/usr/sbin/sshd (deleted)', it does work this way if the source
> of rename() was in the same directory or nested within, thus rename
> like:
> 
> rename("/usr/sbin/foo", "/usr/sbin/sshd")
> 
> and
> 
> rename("/usr/sbin/bar/sshd", "/usr/sbin/sshd")
> 
> ends with a proper '/usr/sbin/sshd (deleted)' symlink.
> 
> if however the source was outside of the target directory, the
> symlink will point to the source path of rename() calls with
> 'deleted' sufix.
> 
> Here's example:
> 
> sbin # for i in `pidof sshd`; do ls -l /proc/$i/exe; done
> lrwxrwxrwx 1 root root 0 Dec 27 18:09 /proc/29047/exe -> /usr/sbin/sshd
> 
> sbin # cp sshd /root/foo
> 
> sbin # strace -f perl -e 'rename("/root/foo", "/usr/sbin/sshd")'
> 2>&1 | grep sshd
> rename("/root/foo", "/usr/sbin/sshd")   = 0
> 
> sbin # for i in `pidof sshd`; do ls -l /proc/$i/exe; done
> lrwxrwxrwx 1 root root 0 Dec 27 18:09 /proc/29047/exe -> /root/sshd
> (deleted)
> 
> I am unable to find kernel version where it worked as one could
> presume thus I cannot offer to bisect commits to find the bad one.

That's because it never _had_ worked.  Note that opening the damn thing
will give the right file - it does not work by traversing the result of
readlink(2).  readlink(2) output on those is not promised to be useful
in all cases; often enough it is, but it won't work on cross-directory
renames, it can't be used to tell a filename that really ends with " (deleted)"
from a removed file, etc.  Moreover, it only very recently became usable for
victim names with the last component longer than 40 characters if you did an
overwriting rename.

What are you trying to use it for?

  reply	other threads:[~2014-12-27 18:14 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-12-27 17:39 [BUG] rename() from outside of the target dir breaks /proc exe symlink Piotr Karbowski
2014-12-27 18:14 ` Al Viro [this message]
2014-12-30 22:40   ` Piotr Karbowski
2015-01-16 18:25     ` Piotr Karbowski
2015-02-09 18:18       ` [BUMP] " Piotr Karbowski

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20141227181412.GG22149@ZenIV.linux.org.uk \
    --to=viro@zeniv.linux.org.uk \
    --cc=linux-kernel@vger.kernel.org \
    --cc=piotr.karbowski@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox