2009-10-25 19:12:04

by Pavel Machek

[permalink] [raw]
Subject: symlinks with permissions


...yes, they do exist, in /proc/self/fd/* . Unfortunately, their
permissions are not actually checked during open, resulting in
(obscure) security hole: if you have fd open for reading, you can
reopen it for write, even through unix permissions would not allow
that.

Now... I'd like to close the hole. One way would be to actually check
symlink permissions on open -- because those symlinks already have
correct permissions.

But ... then I got lost in vfs. Can someone help? Is there better way?

Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html


2009-10-26 18:04:56

by Pavel Machek

[permalink] [raw]
Subject: Re: symlinks with permissions

On Mon 2009-10-26 13:57:49, Trond Myklebust wrote:
> On Mon, 2009-10-26 at 18:46 +0100, Jan Kara wrote:
> > That's what I'd think as well but it does not as I've just learned and
> > tested :) proc_pid_follow_link actually directly gives a dentry of the
> > target file without checking permissions on the way.

It is weider. That symlink even has permissions. Those are not
checked, either.

> I seem to remember that is deliberate, the point being that a symlink
> in /proc/*/fd/ may contain a path that refers to a private namespace.

Well, it is unexpected and mild security hole.

Part of the problem is that even if you have read-only
filedescriptor, you can upgrade it to read-write, even if path is
inaccessible to you.

So if someone passes you read-only filedescriptor, you can still write
to it.
Pavel

--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

2009-10-26 16:31:56

by Jan Kara

[permalink] [raw]
Subject: Re: symlinks with permissions

Hi,

On Sun 25-10-09 07:29:53, Pavel Machek wrote:
> ...yes, they do exist, in /proc/self/fd/* . Unfortunately, their
> permissions are not actually checked during open, resulting in
> (obscure) security hole: if you have fd open for reading, you can
> reopen it for write, even through unix permissions would not allow
> that.
>
> Now... I'd like to close the hole. One way would be to actually check
> symlink permissions on open -- because those symlinks already have
> correct permissions.
Hmm, I'm not sure I understand the problem. Symlink is just a file
containing a path. So if you try to open a symlink, you will actually open
a file to which the path points. So what security problem is here? Either
you can open the file symlink points to for writing or you cannot...
Anyway, if you want to play with this,
fs/proc/base.c:proc_pid_follow_link
is probably the function you are interested in.

Honza
--
Jan Kara <[email protected]>
SUSE Labs, CR

2009-10-26 16:57:25

by Serge E. Hallyn

[permalink] [raw]
Subject: Re: symlinks with permissions

Quoting Jan Kara ([email protected]):
> Hi,
>
> On Sun 25-10-09 07:29:53, Pavel Machek wrote:
> > ...yes, they do exist, in /proc/self/fd/* . Unfortunately, their
> > permissions are not actually checked during open, resulting in
> > (obscure) security hole: if you have fd open for reading, you can
> > reopen it for write, even through unix permissions would not allow
> > that.
> >
> > Now... I'd like to close the hole. One way would be to actually check
> > symlink permissions on open -- because those symlinks already have
> > correct permissions.
> Hmm, I'm not sure I understand the problem. Symlink is just a file
> containing a path. So if you try to open a symlink, you will actually open
> a file to which the path points. So what security problem is here? Either
> you can open the file symlink points to for writing or you cannot...
> Anyway, if you want to play with this,
> fs/proc/base.c:proc_pid_follow_link
> is probably the function you are interested in.

The problem he's trying to address is that users may try to protect
a file by doing chmod 700 on the parent dir, but leave the file itself
accessible. They don't realize that merely having a task with an open
fd to that file gives other users another path to the file.

Whether or not that's actually a problem is open to debate, but I think
he's right that many users aren't aware of it.

-serge

2009-10-26 17:35:15

by J. Bruce Fields

[permalink] [raw]
Subject: Re: symlinks with permissions

On Mon, Oct 26, 2009 at 11:57:29AM -0500, Serge E. Hallyn wrote:
> Quoting Jan Kara ([email protected]):
> > Hi,
> >
> > On Sun 25-10-09 07:29:53, Pavel Machek wrote:
> > > ...yes, they do exist, in /proc/self/fd/* . Unfortunately, their
> > > permissions are not actually checked during open, resulting in
> > > (obscure) security hole: if you have fd open for reading, you can
> > > reopen it for write, even through unix permissions would not allow
> > > that.
> > >
> > > Now... I'd like to close the hole. One way would be to actually check
> > > symlink permissions on open -- because those symlinks already have
> > > correct permissions.
> > Hmm, I'm not sure I understand the problem. Symlink is just a file
> > containing a path. So if you try to open a symlink, you will actually open
> > a file to which the path points. So what security problem is here? Either
> > you can open the file symlink points to for writing or you cannot...
> > Anyway, if you want to play with this,
> > fs/proc/base.c:proc_pid_follow_link
> > is probably the function you are interested in.
>
> The problem he's trying to address is that users may try to protect
> a file by doing chmod 700 on the parent dir, but leave the file itself
> accessible. They don't realize that merely having a task with an open
> fd to that file gives other users another path to the file.
>
> Whether or not that's actually a problem is open to debate, but I think
> he's right that many users aren't aware of it.

If /proc/self/fd/23 is a symlink to /home/me/privatedir/secret, then an
open("proc/self/fd/23",...) still traverses the whole /home/.../secret
path, and needs appropriate permissions at each step, doesn't it?

Probably I'm just terminally confused....

--b.

2009-10-26 17:46:32

by Jan Kara

[permalink] [raw]
Subject: Re: symlinks with permissions

On Mon 26-10-09 13:36:29, J. Bruce Fields wrote:
> On Mon, Oct 26, 2009 at 11:57:29AM -0500, Serge E. Hallyn wrote:
> > Quoting Jan Kara ([email protected]):
> > > Hi,
> > >
> > > On Sun 25-10-09 07:29:53, Pavel Machek wrote:
> > > > ...yes, they do exist, in /proc/self/fd/* . Unfortunately, their
> > > > permissions are not actually checked during open, resulting in
> > > > (obscure) security hole: if you have fd open for reading, you can
> > > > reopen it for write, even through unix permissions would not allow
> > > > that.
> > > >
> > > > Now... I'd like to close the hole. One way would be to actually check
> > > > symlink permissions on open -- because those symlinks already have
> > > > correct permissions.
> > > Hmm, I'm not sure I understand the problem. Symlink is just a file
> > > containing a path. So if you try to open a symlink, you will actually open
> > > a file to which the path points. So what security problem is here? Either
> > > you can open the file symlink points to for writing or you cannot...
> > > Anyway, if you want to play with this,
> > > fs/proc/base.c:proc_pid_follow_link
> > > is probably the function you are interested in.
> >
> > The problem he's trying to address is that users may try to protect
> > a file by doing chmod 700 on the parent dir, but leave the file itself
> > accessible. They don't realize that merely having a task with an open
> > fd to that file gives other users another path to the file.
> >
> > Whether or not that's actually a problem is open to debate, but I think
> > he's right that many users aren't aware of it.
>
> If /proc/self/fd/23 is a symlink to /home/me/privatedir/secret, then an
> open("proc/self/fd/23",...) still traverses the whole /home/.../secret
> path, and needs appropriate permissions at each step, doesn't it?
>
> Probably I'm just terminally confused....
That's what I'd think as well but it does not as I've just learned and
tested :) proc_pid_follow_link actually directly gives a dentry of the
target file without checking permissions on the way.

Honza
--
Jan Kara <[email protected]>
SUSE Labs, CR

2009-10-26 17:57:54

by Serge E. Hallyn

[permalink] [raw]
Subject: Re: symlinks with permissions

Quoting J. Bruce Fields ([email protected]):
> On Mon, Oct 26, 2009 at 11:57:29AM -0500, Serge E. Hallyn wrote:
> > Quoting Jan Kara ([email protected]):
> > > Hi,
> > >
> > > On Sun 25-10-09 07:29:53, Pavel Machek wrote:
> > > > ...yes, they do exist, in /proc/self/fd/* . Unfortunately, their
> > > > permissions are not actually checked during open, resulting in
> > > > (obscure) security hole: if you have fd open for reading, you can
> > > > reopen it for write, even through unix permissions would not allow
> > > > that.
> > > >
> > > > Now... I'd like to close the hole. One way would be to actually check
> > > > symlink permissions on open -- because those symlinks already have
> > > > correct permissions.
> > > Hmm, I'm not sure I understand the problem. Symlink is just a file
> > > containing a path. So if you try to open a symlink, you will actually open
> > > a file to which the path points. So what security problem is here? Either
> > > you can open the file symlink points to for writing or you cannot...
> > > Anyway, if you want to play with this,
> > > fs/proc/base.c:proc_pid_follow_link
> > > is probably the function you are interested in.
> >
> > The problem he's trying to address is that users may try to protect
> > a file by doing chmod 700 on the parent dir, but leave the file itself
> > accessible. They don't realize that merely having a task with an open
> > fd to that file gives other users another path to the file.
> >
> > Whether or not that's actually a problem is open to debate, but I think
> > he's right that many users aren't aware of it.
>
> If /proc/self/fd/23 is a symlink to /home/me/privatedir/secret, then an
> open("proc/self/fd/23",...) still traverses the whole /home/.../secret
> path, and needs appropriate permissions at each step, doesn't it?
>
> Probably I'm just terminally confused....

No, never mind, I misread his earlier email. Sorry.

-serge

2009-10-26 17:58:03

by Trond Myklebust

[permalink] [raw]
Subject: Re: symlinks with permissions

On Mon, 2009-10-26 at 18:46 +0100, Jan Kara wrote:
> That's what I'd think as well but it does not as I've just learned and
> tested :) proc_pid_follow_link actually directly gives a dentry of the
> target file without checking permissions on the way.
>
> Honza

I seem to remember that is deliberate, the point being that a symlink
in /proc/*/fd/ may contain a path that refers to a private namespace.

Cheers
Trond

2009-10-26 18:01:09

by J. Bruce Fields

[permalink] [raw]
Subject: Re: symlinks with permissions

On Mon, Oct 26, 2009 at 06:46:31PM +0100, Jan Kara wrote:
> On Mon 26-10-09 13:36:29, J. Bruce Fields wrote:
> > On Mon, Oct 26, 2009 at 11:57:29AM -0500, Serge E. Hallyn wrote:
> > > Quoting Jan Kara ([email protected]):
> > > > Hi,
> > > >
> > > > On Sun 25-10-09 07:29:53, Pavel Machek wrote:
> > > > > ...yes, they do exist, in /proc/self/fd/* . Unfortunately, their
> > > > > permissions are not actually checked during open, resulting in
> > > > > (obscure) security hole: if you have fd open for reading, you can
> > > > > reopen it for write, even through unix permissions would not allow
> > > > > that.
> > > > >
> > > > > Now... I'd like to close the hole. One way would be to actually check
> > > > > symlink permissions on open -- because those symlinks already have
> > > > > correct permissions.
> > > > Hmm, I'm not sure I understand the problem. Symlink is just a file
> > > > containing a path. So if you try to open a symlink, you will actually open
> > > > a file to which the path points. So what security problem is here? Either
> > > > you can open the file symlink points to for writing or you cannot...
> > > > Anyway, if you want to play with this,
> > > > fs/proc/base.c:proc_pid_follow_link
> > > > is probably the function you are interested in.
> > >
> > > The problem he's trying to address is that users may try to protect
> > > a file by doing chmod 700 on the parent dir, but leave the file itself
> > > accessible. They don't realize that merely having a task with an open
> > > fd to that file gives other users another path to the file.
> > >
> > > Whether or not that's actually a problem is open to debate, but I think
> > > he's right that many users aren't aware of it.
> >
> > If /proc/self/fd/23 is a symlink to /home/me/privatedir/secret, then an
> > open("proc/self/fd/23",...) still traverses the whole /home/.../secret
> > path, and needs appropriate permissions at each step, doesn't it?
> >
> > Probably I'm just terminally confused....
> That's what I'd think as well but it does not as I've just learned and
> tested :) proc_pid_follow_link actually directly gives a dentry of the
> target file without checking permissions on the way.

Got it, thanks.--b.

2009-10-26 18:22:21

by Trond Myklebust

[permalink] [raw]
Subject: Re: symlinks with permissions

On Sun, 2009-10-25 at 10:36 +0100, Pavel Machek wrote:
> Well, it is unexpected and mild security hole.
>
> Part of the problem is that even if you have read-only
> filedescriptor, you can upgrade it to read-write, even if path is
> inaccessible to you.
>
> So if someone passes you read-only filedescriptor, you can still write
> to it.
> Pavel

If someone passes you a file descriptor, can't you in any case play
games with, openat(fd,"",O_RDWR), in order to achieve the same thing? I
must admit I haven't tried it yet, but at a first glance I can't see
anything that prevents me from doing this...

Cheers
Trond

2009-10-26 18:34:23

by J. Bruce Fields

[permalink] [raw]
Subject: Re: symlinks with permissions

On Sun, Oct 25, 2009 at 10:36:04AM +0100, Pavel Machek wrote:
> On Mon 2009-10-26 13:57:49, Trond Myklebust wrote:
> > On Mon, 2009-10-26 at 18:46 +0100, Jan Kara wrote:
> > > That's what I'd think as well but it does not as I've just learned and
> > > tested :) proc_pid_follow_link actually directly gives a dentry of the
> > > target file without checking permissions on the way.
>
> It is weider. That symlink even has permissions. Those are not
> checked, either.
>
> > I seem to remember that is deliberate, the point being that a symlink
> > in /proc/*/fd/ may contain a path that refers to a private namespace.
>
> Well, it is unexpected and mild security hole.
>
> Part of the problem is that even if you have read-only
> filedescriptor, you can upgrade it to read-write, even if path is
> inaccessible to you.
>
> So if someone passes you read-only filedescriptor, you can still write
> to it.

By the way, nfs-exporting a filesystem also allows bypassing lookup
permissions: anyone on the network can access an inode directly (using
an nfs filehandle) without necessarily traversing any path to that
inode. (Assuming they can guess the filehandle--probably doable in most
cases.)

Not arguing for or against, just another data point.

--b.

2009-10-27 08:11:48

by Pavel Machek

[permalink] [raw]
Subject: Re: symlinks with permissions

On Mon 2009-10-26 14:22:16, Trond Myklebust wrote:
> On Sun, 2009-10-25 at 10:36 +0100, Pavel Machek wrote:
> > Well, it is unexpected and mild security hole.
> >
> > Part of the problem is that even if you have read-only
> > filedescriptor, you can upgrade it to read-write, even if path is
> > inaccessible to you.
> >
> > So if someone passes you read-only filedescriptor, you can still write
> > to it.
>
> If someone passes you a file descriptor, can't you in any case play
> games with, openat(fd,"",O_RDWR), in order to achieve the same thing? I
> must admit I haven't tried it yet, but at a first glance I can't see
> anything that prevents me from doing this...

According to my documentation, openat needs directory fd.
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

2009-10-27 10:27:38

by Jamie Lokier

[permalink] [raw]
Subject: Re: symlinks with permissions

Pavel Machek wrote:
> On Mon 2009-10-26 14:22:16, Trond Myklebust wrote:
> > On Sun, 2009-10-25 at 10:36 +0100, Pavel Machek wrote:
> > > Well, it is unexpected and mild security hole.
> > >
> > > Part of the problem is that even if you have read-only
> > > filedescriptor, you can upgrade it to read-write, even if path is
> > > inaccessible to you.
> > >
> > > So if someone passes you read-only filedescriptor, you can still write
> > > to it.
> >
> > If someone passes you a file descriptor, can't you in any case play
> > games with, openat(fd,"",O_RDWR), in order to achieve the same thing? I
> > must admit I haven't tried it yet, but at a first glance I can't see
> > anything that prevents me from doing this...
>
> According to my documentation, openat needs directory fd.

Correct. There has been something about fstatat() and similar
allowing a non-directory when passed a NULL path, but openat() does
not. (It's probably ok to extend openat() to allow a NULL path, if it
does the equivalent of re-opening /proc/self/fd/NN).

I think this whole issue is neatly solved by enforcing the file access
mode for open(/proc/PID/fd/NN) to be a safe subset of the original
file access mode.

It should use the original file access mode so that O_APPEND can
be enforced too. Checking symlink permissions wouldn't do that.

Anything you can change with fcntl(F_SETFL) is fair game for changing.

The ptrace permission check is nice, but even with ptrace you can't
convert a read-only descriptor to a writable one (or write-only to
readable, or append-only to writable, etc.)

-- Jamie

2009-10-28 04:16:00

by Eric W. Biederman

[permalink] [raw]
Subject: Re: symlinks with permissions

Pavel Machek <[email protected]> writes:

> On Mon 2009-10-26 13:57:49, Trond Myklebust wrote:
>> On Mon, 2009-10-26 at 18:46 +0100, Jan Kara wrote:
>> > That's what I'd think as well but it does not as I've just learned and
>> > tested :) proc_pid_follow_link actually directly gives a dentry of the
>> > target file without checking permissions on the way.
>
> It is weider. That symlink even has permissions. Those are not
> checked, either.
>
>> I seem to remember that is deliberate, the point being that a symlink
>> in /proc/*/fd/ may contain a path that refers to a private namespace.
>
> Well, it is unexpected and mild security hole.

/proc/<pid>/fd is only viewable by the owner of the process or by
someone with CAP_DAC_OVERRIDE. So there appears to be no security
hole exploitable by people who don't have the file open.

> Part of the problem is that even if you have read-only
> filedescriptor, you can upgrade it to read-write, even if path is
> inaccessible to you.
>
> So if someone passes you read-only filedescriptor, you can still write
> to it.

Openly if you actually have permission to open the file again. The actual
permissions on the file should not be ignored.

Eric

2009-10-28 08:17:00

by Pavel Machek

[permalink] [raw]
Subject: Re: symlinks with permissions

On Tue 2009-10-27 21:15:54, Eric W. Biederman wrote:
> Pavel Machek <[email protected]> writes:
>
> > On Mon 2009-10-26 13:57:49, Trond Myklebust wrote:
> >> On Mon, 2009-10-26 at 18:46 +0100, Jan Kara wrote:
> >> > That's what I'd think as well but it does not as I've just learned and
> >> > tested :) proc_pid_follow_link actually directly gives a dentry of the
> >> > target file without checking permissions on the way.
> >
> > It is weider. That symlink even has permissions. Those are not
> > checked, either.
> >
> >> I seem to remember that is deliberate, the point being that a symlink
> >> in /proc/*/fd/ may contain a path that refers to a private namespace.
> >
> > Well, it is unexpected and mild security hole.
>
> /proc/<pid>/fd is only viewable by the owner of the process or by
> someone with CAP_DAC_OVERRIDE. So there appears to be no security
> hole exploitable by people who don't have the file open.

Please see bugtraq discussion at
http://seclists.org/bugtraq/2009/Oct/179 .

(In short, you get read-only fd, and you can upgrade it to read-write
fd. Yes, you are the owner of the process, but you are not owner of
the file the fd refers to.)

> > Part of the problem is that even if you have read-only
> > filedescriptor, you can upgrade it to read-write, even if path is
> > inaccessible to you.
> >
> > So if someone passes you read-only filedescriptor, you can still write
> > to it.
>
> Openly if you actually have permission to open the file again. The actual
> permissions on the file should not be ignored.

The actual permissions of the file are not ignored, but permissions of
the containing directory _are_. If there's 666 file in 700 directory,
you can reopen it read-write, in violation of directory's 700
permissions.
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

2009-10-28 11:25:31

by Eric W. Biederman

[permalink] [raw]
Subject: Re: symlinks with permissions

Pavel Machek <[email protected]> writes:

> On Tue 2009-10-27 21:15:54, Eric W. Biederman wrote:
>> Pavel Machek <[email protected]> writes:
>>
>> > On Mon 2009-10-26 13:57:49, Trond Myklebust wrote:
>> >> On Mon, 2009-10-26 at 18:46 +0100, Jan Kara wrote:
>> >> > That's what I'd think as well but it does not as I've just learned and
>> >> > tested :) proc_pid_follow_link actually directly gives a dentry of the
>> >> > target file without checking permissions on the way.
>> >
>> > It is weider. That symlink even has permissions. Those are not
>> > checked, either.
>> >
>> >> I seem to remember that is deliberate, the point being that a symlink
>> >> in /proc/*/fd/ may contain a path that refers to a private namespace.
>> >
>> > Well, it is unexpected and mild security hole.
>>
>> /proc/<pid>/fd is only viewable by the owner of the process or by
>> someone with CAP_DAC_OVERRIDE. So there appears to be no security
>> hole exploitable by people who don't have the file open.
>
> Please see bugtraq discussion at
> http://seclists.org/bugtraq/2009/Oct/179 .
>
> (In short, you get read-only fd, and you can upgrade it to read-write
> fd. Yes, you are the owner of the process, but you are not owner of
> the file the fd refers to.)

Assuming you have permission to open it read-write.

>> > Part of the problem is that even if you have read-only
>> > filedescriptor, you can upgrade it to read-write, even if path is
>> > inaccessible to you.
>> >
>> > So if someone passes you read-only filedescriptor, you can still write
>> > to it.
>>
>> Openly if you actually have permission to open the file again. The actual
>> permissions on the file should not be ignored.
>
> The actual permissions of the file are not ignored, but permissions of
> the containing directory _are_. If there's 666 file in 700 directory,
> you can reopen it read-write, in violation of directory's 700
> permissions.

I can see how all of this can come as a surprise. However I don't see
how any coder who is taking security seriously and being paranoid about
security would actually write code that would have a problem with this.

Do you know of any cases where this difference matters in practice?

It looks to me like it has been this way for better than a decade
without problems so there is no point in changing it now.

Eric

2009-10-28 16:34:36

by Casey Schaufler

[permalink] [raw]
Subject: Re: symlinks with permissions

Pavel Machek wrote:
> On Tue 2009-10-27 21:15:54, Eric W. Biederman wrote:
>
>> Pavel Machek <[email protected]> writes:
>>
>>
>>> On Mon 2009-10-26 13:57:49, Trond Myklebust wrote:
>>>
>>>> On Mon, 2009-10-26 at 18:46 +0100, Jan Kara wrote:
>>>>
>>>>> That's what I'd think as well but it does not as I've just learned and
>>>>> tested :) proc_pid_follow_link actually directly gives a dentry of the
>>>>> target file without checking permissions on the way.
>>>>>
>>> It is weider. That symlink even has permissions. Those are not
>>> checked, either.
>>>
>>>
>>>> I seem to remember that is deliberate, the point being that a symlink
>>>> in /proc/*/fd/ may contain a path that refers to a private namespace.
>>>>
>>> Well, it is unexpected and mild security hole.
>>>
>> /proc/<pid>/fd is only viewable by the owner of the process or by
>> someone with CAP_DAC_OVERRIDE. So there appears to be no security
>> hole exploitable by people who don't have the file open.
>>
>
> Please see bugtraq discussion at
> http://seclists.org/bugtraq/2009/Oct/179 .
>
> (In short, you get read-only fd, and you can upgrade it to read-write
> fd. Yes, you are the owner of the process, but you are not owner of
> the file the fd refers to.)
>
>
>>> Part of the problem is that even if you have read-only
>>> filedescriptor, you can upgrade it to read-write, even if path is
>>> inaccessible to you.
>>>
>>> So if someone passes you read-only filedescriptor, you can still write
>>> to it.
>>>
>> Openly if you actually have permission to open the file again. The actual
>> permissions on the file should not be ignored.
>>
>
> The actual permissions of the file are not ignored, but permissions of
> the containing directory _are_. If there's 666 file in 700 directory,
> you can reopen it read-write, in violation of directory's 700
> permissions.
> Pavel
>

There is no security violation here. Consider the case where
the file is unlinked after it is opened. What directory permissions
would matter in that case? Or what about the case where the file
has a link count of 2, say /a/foo and /b/ish are hard links. If
/a is 777 and /b is 700 what would your position be regarding
the file descriptor obtained by opening /b/ish? The path name is
an ethereal convenience and once traversed has no bearing on the
security state of the object. You need to change the semantics
of Linux (and Unix) file systems for your concern to make any
sense at all.

2009-10-28 19:45:03

by Jamie Lokier

[permalink] [raw]
Subject: Re: symlinks with permissions

Casey Schaufler wrote:
> Pavel Machek wrote:
> > The actual permissions of the file are not ignored, but permissions of
> > the containing directory _are_. If there's 666 file in 700 directory,
> > you can reopen it read-write, in violation of directory's 700
> > permissions.
> > Pavel
>
> There is no security violation here. Consider the case where
> the file is unlinked after it is opened. What directory permissions
> would matter in that case?

That's an even worse security violation.

If you have a file opened read-only which is unlinked (and there's no
other file descriptors to it), it is impossible to modify the file
except through this quirk of /proc/NN/fd. In traditional unix, it is
impossible to modify full stop. Even root can't write to it.

Paths are in this discussion as an *example* of something that cannot
be done except through /proc/NN/fd. Paths are not the issue.

As you've noticed, the same security hole occurs for files which have
been unlinked and don't have any path.

The real issue is gaining more access to an open file than you had before.

> Or what about the case where the file
> has a link count of 2, say /a/foo and /b/ish are hard links. If
> /a is 777 and /b is 700 what would your position be regarding
> the file descriptor obtained by opening /b/ish?

It depends on the flag passed to open() when the file descriptor is
obtained. That's where the pseudo-symlink permission comes from,
which is what Pavel is getting it.

> The path name is an ethereal convenience and once traversed has no
> bearing on the security state of the object.

That's right. The security state should depend _only_ on the
file open mode, that is O_RDONLY/WRONLY/RDWR/APPEND.

That is more or less what Pavel is saying too, because the
pseudo-symlink permission is calculated from the file open mode
(except for O_APPEND, which is why it shouldn't be done using the
pseudo-symlink permission). Ignore the path aspect, it's just a distraction.

-- Jamie

2009-10-28 21:03:30

by Pavel Machek

[permalink] [raw]
Subject: Re: symlinks with permissions

Hi!

> >> > Well, it is unexpected and mild security hole.
> >>
> >> /proc/<pid>/fd is only viewable by the owner of the process or by
> >> someone with CAP_DAC_OVERRIDE. So there appears to be no security
> >> hole exploitable by people who don't have the file open.
> >
> > Please see bugtraq discussion at
> > http://seclists.org/bugtraq/2009/Oct/179 .
> >
> > (In short, you get read-only fd, and you can upgrade it to read-write
> > fd. Yes, you are the owner of the process, but you are not owner of
> > the file the fd refers to.)
>
> Assuming you have permission to open it read-write.

Please see the bugtraq discussion.

It works even if you would not have permission to write to it with
/proc unmounted.

> >> Openly if you actually have permission to open the file again. The actual
> >> permissions on the file should not be ignored.
> >
> > The actual permissions of the file are not ignored, but permissions of
> > the containing directory _are_. If there's 666 file in 700 directory,
> > you can reopen it read-write, in violation of directory's 700
> > permissions.
>
> I can see how all of this can come as a surprise. However I don't see
> how any coder who is taking security seriously and being paranoid about
> security would actually write code that would have a problem with
> this.

So, there's "surprise" that gives _you_ write access to my files. You
agree that it is surprising, and you would not have write access to my
file if /proc was not mounted.

Call it "security surprise" if you prefer. But many people call it
"security hole".

> Do you know of any cases where this difference matters in practice?

No. Do you have a proof that it does not matter anywhere?

> It looks to me like it has been this way for better than a decade
> without problems so there is no point in changing it now.

Unix compatibility?
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

2009-10-28 21:06:27

by Pavel Machek

[permalink] [raw]
Subject: Re: symlinks with permissions


> > Please see bugtraq discussion at
> > http://seclists.org/bugtraq/2009/Oct/179 .
> >
> > (In short, you get read-only fd, and you can upgrade it to read-write
> > fd. Yes, you are the owner of the process, but you are not owner of
> > the file the fd refers to.)
> >
> > The actual permissions of the file are not ignored, but permissions of
> > the containing directory _are_. If there's 666 file in 700 directory,
> > you can reopen it read-write, in violation of directory's 700
> > permissions.

>
> There is no security violation here. Consider the case where

You are able to write to my files, when unix permissions forbid
that. How do you call that? Strange behaviour of /proc/*/fd/ symlink
that is not really a symlink allows that.

See bugtraq discussion at http://seclists.org/bugtraq/2009/Oct/179 .
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

2009-10-28 22:48:08

by David Wagner

[permalink] [raw]
Subject: Re: symlinks with permissions

Casey Schaufler wrote:
> There is no security violation here. Consider the case where
> the file is unlinked after it is opened. What directory permissions
> would matter in that case?

Where are you going with this?

Suppose I open a file in read-only mode. Suppose moreover I only
have permission to read the file but not write it (given the full
permissions on the path to the file). Suppose that someone else deletes
the file. Then the OS had darn well better prevent me from upgrading
my read-only file descriptor to a read-write file descriptor. If some
OS feature created a backdoor that allowed me to upgrade my read-only
file descriptor to read-write access (even in cases where the file and
directory permissions would prevent me from directly opening the file in
read-write mode), then we'd darn well consider that a security violation.
That is roughly analogous to what is happening here.

I do think Pavel's attack is a security violation. I don't understand
why there is any debate about this; it seems pretty clear-cut to me.
It may be an obscure corner-case, but it still seems like a cut-and-dry
security violation. (Incidentally, I found the quality of some of the
discussion on bugtraq pretty disappointing as well.)

> The path name is
> an ethereal convenience and once traversed has no bearing on the
> security state of the object.

I think you've missed the point of Pavel's attack. Pavel's attack allows
a malicious process to take an existing read-only file descriptor and
turn it into a read-write file descriptor, in cases where the filesystem
permission bits should not have allowed the malicious process to do that.
*That* is the security violation. *That* should not be allowed.

Perhaps take a look at Pavel's post describing the attack again?

2009-10-29 02:20:22

by Eric W. Biederman

[permalink] [raw]
Subject: Re: symlinks with permissions

Pavel Machek <[email protected]> writes:

> Hi!
>
>> >> > Well, it is unexpected and mild security hole.
>> >>
>> >> /proc/<pid>/fd is only viewable by the owner of the process or by
>> >> someone with CAP_DAC_OVERRIDE. So there appears to be no security
>> >> hole exploitable by people who don't have the file open.
>> >
>> > Please see bugtraq discussion at
>> > http://seclists.org/bugtraq/2009/Oct/179 .
>> >
>> > (In short, you get read-only fd, and you can upgrade it to read-write
>> > fd. Yes, you are the owner of the process, but you are not owner of
>> > the file the fd refers to.)
>>
>> Assuming you have permission to open it read-write.
>
> Please see the bugtraq discussion.
>
> It works even if you would not have permission to write to it with
> /proc unmounted.
>
>> >> Openly if you actually have permission to open the file again. The actual
>> >> permissions on the file should not be ignored.
>> >
>> > The actual permissions of the file are not ignored, but permissions of
>> > the containing directory _are_. If there's 666 file in 700 directory,
>> > you can reopen it read-write, in violation of directory's 700
>> > permissions.
>>
>> I can see how all of this can come as a surprise. However I don't see
>> how any coder who is taking security seriously and being paranoid about
>> security would actually write code that would have a problem with
>> this.
>
> So, there's "surprise" that gives _you_ write access to my files. You
> agree that it is surprising, and you would not have write access to my
> file if /proc was not mounted.

I also find it a surprise you would ever make a file world writable.

I find it a surprise that in any application that cared you would allow the
file to be opened, or passed through a unix domain socket and then have
the permissions changed.

> Call it "security surprise" if you prefer. But many people call it
> "security hole".
>
>> Do you know of any cases where this difference matters in practice?
>
> No. Do you have a proof that it does not matter anywhere?
>
>> It looks to me like it has been this way for better than a decade
>> without problems so there is no point in changing it now.
>
> Unix compatibility?

Thinking about this proc fundamentally gives you the ability to create
(via open) a new file descriptor for a file you already have open.

That is the design and things are working by design.

I do see a security issue in your example, but the security issue I
see is how you have chosen to use the linux facilities, that have been
there for ages. Facilities cloned from plan 9 and apparently
available in slightly different forms on many unix variants existence.
/dev/fd/N is not a linuxism.

To close this whole would require some sort of stacking inode that
when opened opened the real fs inode. With all kinds of convolutions
and complications. Just to close the issue that some idiot might
give someone a fd to a world writeable file that they don't want
them to open.

Given this is an old well established facility with a long tradition,
that does not appear to be easy or simple to exploit. I believe the burden
of proof has not been met to say the design has a security issue.

I certainly am not interested in debugging or maintaining the stacking
inode code that would be necessary to close this theoretical corner
case. There are much more real bugs that need attention.

Eric

2009-10-29 04:13:21

by Casey Schaufler

[permalink] [raw]
Subject: Re: symlinks with permissions

David Wagner wrote:
> Casey Schaufler wrote:
>
>> There is no security violation here. Consider the case where
>> the file is unlinked after it is opened. What directory permissions
>> would matter in that case?
>>
>
> Where are you going with this?
>

Probably straight into a level of obscurity that only a
very small fraction of us care about, but hear me out.

> Suppose I open a file in read-only mode. Suppose moreover I only
> have permission to read the file but not write it (given the full
> permissions on the path to the file).

Ok. The parenthetical clause is a problem. Once you have the file
descriptor the path that you used to get it is completely irrelevant.
Not just unimportant. It matters not at all. The only thing that
matters at that point are the mode bits on the file itself. Why?
If /a/foo is a hard link to /b/bar (for the uninitiated that means
that foo and bar are on the same file system and share an inode
number) there is absolutely no way to tell, given a file descriptor,
which path was used to open the file. Further, it is no longer
necessary that foo, bar, a, or b even exist any longer. So if
/proc/8675309/fd/3 is accessable for write access to a process it
does not matter one horse's pitutte what the mode bits on a or b
might be. Period.

> Suppose that someone else deletes
> the file. Then the OS had darn well better prevent me from upgrading
> my read-only file descriptor to a read-write file descriptor.

Nope. Not if the mode bits on the file allow it. How you got to
the file matters not at all. The mode of the path you happened to
use matters not at all. What matters are the mode bit on the file
itself.

> If some
> OS feature created a backdoor that allowed me to upgrade my read-only
> file descriptor to read-write access (even in cases where the file and
> directory permissions would prevent me from directly opening the file in
> read-write mode), then we'd darn well consider that a security violation.
> That is roughly analogous to what is happening here.
>

No, I don't believe that is correct. Unless I read the discussion
incorrectly, the file has to be writeable for the "exploit" to
work. The reason that it looks like an exploit is that the mode bits
on the containing directory "should" prevent the requested access,
but in reality /proc/8675309/fs/3 provides an alternative pathname
to the object, just as having a hard link or an alternative mount
point might. Neither of those cases is an "exploit", although I can
easily understand how they might appear to be to those who are
unfamiliar with the acyclic graph that is the Linux (Unix) file
system name space.

> I do think Pavel's attack is a security violation. I don't understand
> why there is any debate about this; it seems pretty clear-cut to me.
> It may be an obscure corner-case, but it still seems like a cut-and-dry
> security violation. (Incidentally, I found the quality of some of the
> discussion on bugtraq pretty disappointing as well.)
>

Sorry if my arguments lack clarity. It's been a rough year.

The only access that really matters is that of the object itself.
The path you use to get to it only matters during the resolution
of the path, after which it is, and must be, irrelevant. If there
is a path that leads to the object that is constructed some other
way, as the "fd" bit of /proc is, then the semantics of that path's
construction are what matter for the resolution of that path. Since
they have no way or reason to determine what the original
resolution path might have been there is no point in whinging
that the access of the /proc/8675309/fd/3 path is different from
the /a/foo path any more than there is that /b/bar might be
different.

>
>> The path name is
>> an ethereal convenience and once traversed has no bearing on the
>> security state of the object.
>>
>
> I think you've missed the point of Pavel's attack. Pavel's attack allows
> a malicious process to take an existing read-only file descriptor and
> turn it into a read-write file descriptor, in cases where the filesystem
> permission bits should not have allowed the malicious process to do that.
> *That* is the security violation. *That* should not be allowed.
>

Again, once the file descriptor exists the only mode bits
(Or Smack label, or SELinux context, or ACL) that matters is
that of the object itself. It is perfectly OK to change a RO
to an RW if the mode bits allow it.

> Perhaps take a look at Pavel's post describing the attack again?

Yeah, I did that. It still looks like the complaint is that
/proc/8675309/fd/3 gives you the ability to gain RW access to
an object for which you have RW access.

Look, with hard links and the various mount options available
today you just can't count on setting the mode on a directory
to completely protect the files that it references. Look carefully
at the semantics of directories. They do not contain files. They
contain names of files. Setting the mode on a directory protects
access to the name of a file, not access to the file. There are
multiple ways to name a file, and access to any of the names of
a file to which you have access is sufficient to get you access
to the file.

As always, I could be missing something completely, but I have
been arguing Unix/Linux file system security issues for longer
than some of the people reading this have been alive.

Now, ask me if I think that /proc/8675309/fd/3 is a good idea,
and we'll have a different discussion, but from an old school
security standpoint (objects, subjects, accesses) there just is
not a problem.

If you want to introduce the notion that the pathname used to
access a file matters on subsequent access control decisions, well,
good luck, but don't say I didn't warn you.

2009-10-29 07:53:54

by David Wagner

[permalink] [raw]
Subject: Re: symlinks with permissions

Casey Schaufler wrote:
>David Wagner wrote:
>> Suppose I open a file in read-only mode. Suppose moreover I only
>> have permission to read the file but not write it (given the full
>> permissions on the path to the file).
>
> Ok. The parenthetical clause is a problem. Once you have the file
> descriptor the path that you used to get it is completely irrelevant.
> [... rest of argument about how the system *has* to work ...]

Are you trying to infer how Linux *does* work, based on how
it *could possibly* work? If so, why not just check directly
how it does work?

Are you trying to argue how Linux *should* work, based upon limits
on how it *could* work? If so, you've missed an option: Linux could
refuse to expose a way to upgrade a read-only file descriptor to
a read-write file descriptor through /proc.

Suppose I have a read-only file descriptor, and the file that I originally
opened is now writeable. Are you assuming that Linux provides some
mechanism to turn this into a read-write file descriptor (regardless of
permissions on the rest of the path to that file; and apart from the /proc
mechanism Pavel identifies)? If so, what mechanism did you have in mind?

I don't know of any mechanism that provides this functionality.

For example, as far as I know, fcntl(fd, F_SETFL) does not allow you
to change an existing file descriptor from O_RDONLY mode to O_WRONLY or
O_RDWR, regardless of filesystem permission bits.

Put another way, I think you are right that it is not possible for
Linux to look at the path permissions after the file has been opened.
The conclusion you draw is that therefore Linux does or should provide
some way to upgrade a O_RDONLY file descriptor into O_RDWR mode based on
looking only at the file (but not path) permissions. But I don't think
that follows. I think the real situation is that Linux doesn't provide
any such way to upgrade a O_RDONLY file descriptor into O_RDWR mode (well,
except through the problematic /proc interface that Pavel describes,
which is exactly the problem).

Put yet another way, if Linux *can't* look at the path permissions, then
it *had better not* expose a way to turn a O_RDONLY file descriptor into
a O_RDWR file descriptor; anything else is a security violation.

> No, I don't believe that is correct. Unless I read the discussion
> incorrectly, the file has to be writeable for the "exploit" to
> work. The reason that it looks like an exploit is that the mode bits
> on the containing directory "should" prevent the requested access,
> but in reality /proc/8675309/fs/3 provides an alternative pathname
> to the object, just as having a hard link or an alternative mount
> point might. Neither of those cases is an "exploit", although I can
> easily understand how they might appear to be to those who are
> unfamiliar with the acyclic graph that is the Linux (Unix) file
> system name space.

I am familiar with the acylic graph that is, etc., etc. Nonetheless
I still consider Pavel's attack a security violation. Before the
/proc interface in question was introduced, it was an invariant that
nothing a malicious user could do would enable it to access the file.
Programs could rely upon this invariant. The /proc interface breaks
this invariant and creates a sneaky way that a malicious user could
access files that he couldn't have accessed in the absence of the /proc
mechanism. That's not something application writers can reasonably
be expected to expect. That makes it a security violation. /proc
shouldn't be providing backdoors: ways to access files that you could
not have accessed in the absence of /proc.

> The only access that really matters is that of the object itself.
> The path you use to get to it only matters during the resolution
> of the path, after which it is, and must be, irrelevant. If there
> is a path that leads to the object that is constructed some other
> way, as the "fd" bit of /proc is, then the semantics of that path's
> construction are what matter for the resolution of that path. Since
> they have no way or reason to determine what the original
> resolution path might have been there is no point in whinging
> that the access of the /proc/8675309/fd/3 path is different from
> the /a/foo path any more than there is that /b/bar might be
> different.

I'm not convinced. Your reasoning seems to be "Since we can't look
at the path, therefore Linux has to look at only the file and allow
upgrading a read-only file descriptor to a read-write file descriptor
if the permission bits on the file allow it, without regard to the path
permissions". My position is "If we can't look at the path, then Linux
can't tell whether it is safe to upgrade a read-only file descriptor to a
read-write file descriptor, so in this case Linux must not provide a way
to upgrade a read-only file descriptor to a read-write file descriptor
when the filepath might have been unopenable for writing (e.g., due to
path permissions)". See the difference? You assume, in case of doubt,
upgrading has to be allowed. I say, that's not the only possibility.
I say, in case of doubt, upgrading can -- and should -- be denied.

> Yeah, I did that. It still looks like the complaint is that
> /proc/8675309/fd/3 gives you the ability to gain RW access to
> an object for which you have RW access.

Nope. The complaint is that /proc gives me a sneaky way to gain RW
access to an object for which I otherwise would not have been able to
gain RW access. In the absence of the /proc mechanism and Pavel's sneaky
attack, I would not have been able to gain write access to the object.

> Look, with hard links and the various mount options available
> today you just can't count on setting the mode on a directory
> to completely protect the files that it references.

Hard links: Yes you can count on this to protect files, if you set up
the directory yourself and set it up properly. Pavel's attack protects
against hard links. Read his attack script more carefully.

Mount options: Care to explain further? I don't immediately see the
relevance.

2009-10-29 11:03:53

by Pavel Machek

[permalink] [raw]
Subject: Re: symlinks with permissions

Hi!

> >> It looks to me like it has been this way for better than a decade
> >> without problems so there is no point in changing it now.
> >
> > Unix compatibility?
>
> Thinking about this proc fundamentally gives you the ability to create
> (via open) a new file descriptor for a file you already have open.

Yes. Problem is that by using /proc, I can work-around open(READONLY)
restriction and work-around open(APPEND_ONLY) restriction.

> I do see a security issue in your example, but the security issue I
> see is how you have chosen to use the linux facilities, that have been
> there for ages. Facilities cloned from plan 9 and apparently
> available in slightly different forms on many unix variants existence.
> /dev/fd/N is not a linuxism.
>
> To close this whole would require some sort of stacking inode that
> when opened opened the real fs inode. With all kinds of convolutions
> and complications. Just to close the issue that some idiot might
> give someone a fd to a world writeable file that they don't want
> them to open.

Ok, so you agree issue is there. Good.

Now, fix for READONLY issue should be fairly simple: follow link in
/proc/*/fd/* should check the link permissions, and return
read-only/write-only descriptors as neccessary.

Basically, that follow link should behave as dup(), not as open().

> I certainly am not interested in debugging or maintaining the stacking
> inode code that would be necessary to close this theoretical corner
> case. There are much more real bugs that need attention.

But if we can get trivial 10-liner, that should be acceptable, right?
Pavel

--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

2009-10-29 16:23:54

by Eric W. Biederman

[permalink] [raw]
Subject: Re: symlinks with permissions

Pavel Machek <[email protected]> writes:

> Hi!
>
>> >> It looks to me like it has been this way for better than a decade
>> >> without problems so there is no point in changing it now.
>> >
>> > Unix compatibility?
>>
>> Thinking about this proc fundamentally gives you the ability to create
>> (via open) a new file descriptor for a file you already have open.
>
> Yes. Problem is that by using /proc, I can work-around open(READONLY)
> restriction and work-around open(APPEND_ONLY) restriction.

If you are allowed to do that simply opening the inode.

I can also use a bind mount on the file before you lock down
permissions instead of proc in your example to achieve the same
affect. An extra path to an inode.

In general there is not a way to lock down the path to a file to a
more restrictive set of permissions after it has been opened. Not
until sys_revoke or similar syscall has been implemented. Even then I
am a bit dubious.

>> I do see a security issue in your example, but the security issue I
>> see is how you have chosen to use the linux facilities, that have been
>> there for ages. Facilities cloned from plan 9 and apparently
>> available in slightly different forms on many unix variants existence.
>> /dev/fd/N is not a linuxism.
>>
>> To close this whole would require some sort of stacking inode that
>> when opened opened the real fs inode. With all kinds of convolutions
>> and complications. Just to close the issue that some idiot might
>> give someone a fd to a world writeable file that they don't want
>> them to open.
>
> Ok, so you agree issue is there. Good.

I don't agree that the kernel has a problem. I agree that there
is a security hole in your example.

I don't believe you can rely on the directory permissions in the general
case to control access to a file.

> Now, fix for READONLY issue should be fairly simple: follow link in
> /proc/*/fd/* should check the link permissions, and return
> read-only/write-only descriptors as neccessary.

The follow_link is just a follow link. Either we add an extra path
to the fd or we don't. Follow link doesn't know it is being used for open.

That isn't completely correct. You might be able to look at the
intent and if it is LOOKUP_OPEN and the open mode is compatible return
the original file descriptor. Even if you do that and the kernel is
guaranteed to take that path in all examples that still leaves an
extra path for syscalls that don't require a filedesciptor to use.

> Basically, that follow link should behave as dup(), not as open().

There are reasons why an open is an open here. I don't remember the
details but I found the archive of that conversation once. Maybe it was
just technical limitations of the time.

>> I certainly am not interested in debugging or maintaining the stacking
>> inode code that would be necessary to close this theoretical corner
>> case. There are much more real bugs that need attention.
>
> But if we can get trivial 10-liner, that should be acceptable, right?

How many linux shell scripts and other applications that use /dev/fd/N
or /proc/self/fd/N will you be breaking?

Closing a theoretical security hole at the expense of breaking real
applications is a show stopper.

Feel free to play and test but I'm still not buying it.

Eric

2009-10-30 14:07:51

by Pavel Machek

[permalink] [raw]
Subject: Re: symlinks with permissions

Hi!


> > Perhaps take a look at Pavel's post describing the attack again?
>
> Yeah, I did that. It still looks like the complaint is that
> /proc/8675309/fd/3 gives you the ability to gain RW access to
> an object for which you have RW access.
>
> Look, with hard links and the various mount options available
> today you just can't count on setting the mode on a directory
> to completely protect the files that it references. Look carefully

Look again. I can count on paths if I can prevent mounts and
hardlinks. Mounts are irrelevant as they are root-only, and I was
checking for hardlinks.

> Now, ask me if I think that /proc/8675309/fd/3 is a good idea,
> and we'll have a different discussion, but from an old school

Cool, so we actually agree, and can drop this thread?
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

2009-10-30 18:36:03

by Pavel Machek

[permalink] [raw]
Subject: Re: symlinks with permissions

Hi!

> > Basically, that follow link should behave as dup(), not as open().
>
> There are reasons why an open is an open here. I don't remember the
> details but I found the archive of that conversation once. Maybe it was
> just technical limitations of the time.

That would be really really useful to bring

> >> I certainly am not interested in debugging or maintaining the stacking
> >> inode code that would be necessary to close this theoretical corner
> >> case. There are much more real bugs that need attention.
> >
> > But if we can get trivial 10-liner, that should be acceptable, right?
>
> How many linux shell scripts and other applications that use /dev/fd/N
> or /proc/self/fd/N will you be breaking?

Zero. (Well unless someone is exploiting it in wild).

> Closing a theoretical security hole at the expense of breaking real
> applications is a show stopper.

I don't plan to remove /proc/*/fd; but I would like it to behave like
dup().

(I still hope some security team does work for me :-).
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

2009-10-30 20:37:24

by Nick Bowler

[permalink] [raw]
Subject: Re: symlinks with permissions

On 19:35 Fri 30 Oct , Pavel Machek wrote:
> > How many linux shell scripts and other applications that use /dev/fd/N
> > or /proc/self/fd/N will you be breaking?
>
> Zero. (Well unless someone is exploiting it in wild).

I've definitely written at least one script before that does something
along the lines of 'echo foo > /dev/fd/N'. It's not one that I remember
anything else about, so perhaps its behaviour would be unaffected by
forbidding this if the particular file descriptor did not originally
have read-write permissions. I have a hard time believing that amongst
millions of users, not one of them has a script that would be affected.

Frankly, I don't understand what is particularly surprising about the
fact that people can write to files with world write permissions.

--
Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)

2009-10-30 23:03:46

by Eric W. Biederman

[permalink] [raw]
Subject: Re: symlinks with permissions

Pavel Machek <[email protected]> writes:

>> >> I certainly am not interested in debugging or maintaining the stacking
>> >> inode code that would be necessary to close this theoretical corner
>> >> case. There are much more real bugs that need attention.
>> >
>> > But if we can get trivial 10-liner, that should be acceptable, right?
>>
>> How many linux shell scripts and other applications that use /dev/fd/N
>> or /proc/self/fd/N will you be breaking?
>
> Zero. (Well unless someone is exploiting it in wild).

There are other differences like different offsets etc that may matter.

>> Closing a theoretical security hole at the expense of breaking real
>> applications is a show stopper.
>
> I don't plan to remove /proc/*/fd; but I would like it to behave like
> dup().
>
> (I still hope some security team does work for me :-).

Seriously turning this into dup is about 20 lines of code in follow
link. Just look at the open intent in the nameidata. nfs should
have an exampled of using the open intent somewhere.

I bet you will get a lot more traction and discussion if you write
a basic mostly working version of the patch.

Eric

2009-10-31 02:30:21

by Jamie Lokier

[permalink] [raw]
Subject: Re: symlinks with permissions

Eric W. Biederman wrote:
> Pavel Machek <[email protected]> writes:
> >> How many linux shell scripts and other applications that use /dev/fd/N
> >> or /proc/self/fd/N will you be breaking?
> >
> > Zero. (Well unless someone is exploiting it in wild).
>
> There are other differences like different offsets etc that may matter.
>
> >> Closing a theoretical security hole at the expense of breaking real
> >> applications is a show stopper.
> >
> > I don't plan to remove /proc/*/fd; but I would like it to behave like
> > dup().
> >
> > (I still hope some security team does work for me :-).

Yes, it must not be like dup(), sharing the file pointer, because I'm
sure that really will break some programs.

Like all the ones using gnulib (formerly libiberty) which use
/proc/self/fd/N/path/to/file to implement fake openat(N,"path/to/file").

> I bet you will get a lot more traction and discussion if you write
> a basic mostly working version of the patch.

I agree, and I'll be happy to review/break it ;-)

-- Jamie

2009-10-31 04:09:39

by Casey Schaufler

[permalink] [raw]
Subject: Re: symlinks with permissions

Pavel Machek wrote:
> Hi!
>
>
>
>>> Perhaps take a look at Pavel's post describing the attack again?
>>>
>> Yeah, I did that. It still looks like the complaint is that
>> /proc/8675309/fd/3 gives you the ability to gain RW access to
>> an object for which you have RW access.
>>
>> Look, with hard links and the various mount options available
>> today you just can't count on setting the mode on a directory
>> to completely protect the files that it references. Look carefully
>>
>
> Look again. I can count on paths if I can prevent mounts and
> hardlinks.

But you can't. I refer you back to the long and tedious arguments
against pathname based access controls. At any given time the only
access controls that you can actually count on are those on the
object itself.


> Mounts are irrelevant as they are root-only,

That hardly makes them irrelevant. It makes them explicable, and
thus generally acceptable, but as always, with privilege comes
responsibility.

> and I was checking for hardlinks.
>

So that was not an issue in this particular case.

>> Now, ask me if I think that /proc/8675309/fd/3 is a good idea,
>> and we'll have a different discussion, but from an old school
>>
>
> Cool, so we actually agree, and can drop this thread?
> Pavel
>

The "fd" file system was introduced in SystemV long before Linux
was on anyone's radar. It was a response to the fact that a born
shell script (not Born Again SHell, SHell) couldn't redirect to
arbitrary descriptors the way that csh could. It was an amazing
example of every problem looking like a nail to the wielder of
the special purpose file system hammer. I dislike the /proc/.../fd
scheme for the same reasons, not because it is a security issue.
I would have preferred that the shell code get improved instead.
But, as I say, my opinion and $4.35 will get you the beverage of
your choice at Starbuck's.

2009-11-01 09:23:30

by David Wagner

[permalink] [raw]
Subject: Re: symlinks with permissions

Casey Schaufler wrote:
>Pavel Machek wrote:
>> Look again. I can count on paths if I can prevent mounts and
>> hardlinks.
>
> But you can't.

Yes, he can and did. See Pavel's original post with his
attack script. It's all there!

Hardlinks: in his *original* post, listing the attack script,
Pavel checks the hardlink count, which does defend against
hardlinks. So can we drop the hardlink objection?

Mounts: can only be exploited by root. On many Linux systems,
one cannot defend against a threat model where root is malicious,
and as a consequence, root-only attacks are out of scope for
those systems. For those systems, this /proc mechanism is
a security hole: it enables attacker to do bad stuff they
couldn't have done without it.

> I refer you back to the long and tedious arguments
> against pathname based access controls.

I don't find that reference helpful. Those arguments don't
seem relevant to this situation, as far as I can see. I would
find specificity more useful than analogies.

Pavel has provided a concrete attack script. If you believe
that the protections afforded by that script can be circumvented,
how about showing us the specific attack, described to a similar
level of concreteness and specifity, that demonstrates how to
upgrade the read-only fd to a read-write fd without using /proc?

Put another way: if you are right that the arguments about
pathname based access controls apply here and lead to the
conclusions you are espousing, then you should be able to
exhibit a specific, concrete, fully specified attack on Pavel's
script, without using /proc. Right?

2009-11-01 17:43:56

by Casey Schaufler

[permalink] [raw]
Subject: Re: symlinks with permissions

David Wagner wrote:
> Casey Schaufler wrote:
>
>> Pavel Machek wrote:
>>
>>> Look again. I can count on paths if I can prevent mounts and
>>> hardlinks.
>>>
>> But you can't.
>>
>
> Yes, he can and did. See Pavel's original post with his
> attack script. It's all there!
>
> Hardlinks: in his *original* post, listing the attack script,
> Pavel checks the hardlink count, which does defend against
> hardlinks. So can we drop the hardlink objection?
>
> Mounts: can only be exploited by root. On many Linux systems,
> one cannot defend against a threat model where root is malicious,
> and as a consequence, root-only attacks are out of scope for
> those systems. For those systems, this /proc mechanism is
> a security hole: it enables attacker to do bad stuff they
> couldn't have done without it.
>
>
>> I refer you back to the long and tedious arguments
>> against pathname based access controls.
>>
>
> I don't find that reference helpful. Those arguments don't
> seem relevant to this situation, as far as I can see. I would
> find specificity more useful than analogies.
>
> Pavel has provided a concrete attack script. If you believe
> that the protections afforded by that script can be circumvented,
> how about showing us the specific attack, described to a similar
> level of concreteness and specifity, that demonstrates how to
> upgrade the read-only fd to a read-write fd without using /proc?
>
> Put another way: if you are right that the arguments about
> pathname based access controls apply here and lead to the
> conclusions you are espousing, then you should be able to
> exhibit a specific, concrete, fully specified attack on Pavel's
> script, without using /proc. Right?
>

No. The going in premise, that the behavior is a security flaw,
is incorrect. The mode bits on the file allow the requested access.
What the mode bits were when the file was opened, and what the mode
bits on the path used to get to the file were at the time of
the open are irrelevant and no amount of sound logic that assumes
otherwise has any value.

I can accept that you don't like the behavior. The behavior is
nonetheless consistent with the access controls of the file system.
If you change the current behavior you will introduce an arbitrary
special case to the file system object access control model. It is
unfortunate that the people who invented the fd file system (now
implemented as part of /proc) did not take the consequences of
adding an additional object naming mechanism for files into
account, but they were hardly the first to skip that step and I
dare say that they weren't the last.

So "fix" the "problem". You'll just be replacing one questionable
behavior with another, and you'll be making the security model
one paragraph harder to describe.

> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
>
>

2009-11-01 20:39:28

by David Wagner

[permalink] [raw]
Subject: Re: symlinks with permissions

Casey Schaufler wrote:
>David Wagner wrote:
>> Pavel has provided a concrete attack script. If you believe
>> that the protections afforded by that script can be circumvented,
>> how about showing us the specific attack, described to a similar
>> level of concreteness and specifity, that demonstrates how to
>> upgrade the read-only fd to a read-write fd without using /proc?
>>
>> Put another way: if you are right that the arguments about
>> pathname based access controls apply here and lead to the
>> conclusions you are espousing, then you should be able to
>> exhibit a specific, concrete, fully specified attack on Pavel's
>> script, without using /proc. Right?
>
> No. The going in premise, that the behavior is a security flaw,
> is incorrect. The mode bits on the file allow the requested access.

I see. May I conclude that you are unable to answer my challenge?

I challenged you to show exactly how else a non-root user could gain write
access to the file, in Pavel's script, other than using /proc/../fd/...
Based on the fact that you have repeatedly declined to answer this
challenge, it sounds like I can safely conclude that you do not know of
any other way that a non-root user can accomplish this, in the situation
Pavel outlines.

So, it sounds like we have agreement that:

* In the situation Pavel outlines, a malicious non-root user
given read-only access to the file can use /proc/../fd/.. to
upgrade that fd to read-write access.

* If /proc/../fd/.. didn't exist, the non-root user would not have
been able to do that.

So the /proc/../fd/.. mechanism is enabling a malicious user to get
access that they would not have been able to get in the absence of
this mechanism.

Do you agree with that summary?


The above are the facts, as I see them. (In contrast, the following is
my opinion: It is my opinion that these facts demonstrate that this is
a security violation.) But I'm not asking for your feedback about my
opinion; I'm asking you about the facts. Do you agree with my statement
of the facts?

2009-11-01 22:05:53

by Casey Schaufler

[permalink] [raw]
Subject: Re: symlinks with permissions

David Wagner wrote:
> Casey Schaufler wrote:
>
>> David Wagner wrote:
>>
>>> Pavel has provided a concrete attack script. If you believe
>>> that the protections afforded by that script can be circumvented,
>>> how about showing us the specific attack, described to a similar
>>> level of concreteness and specifity, that demonstrates how to
>>> upgrade the read-only fd to a read-write fd without using /proc?
>>>
>>> Put another way: if you are right that the arguments about
>>> pathname based access controls apply here and lead to the
>>> conclusions you are espousing, then you should be able to
>>> exhibit a specific, concrete, fully specified attack on Pavel's
>>> script, without using /proc. Right?
>>>
>> No. The going in premise, that the behavior is a security flaw,
>> is incorrect. The mode bits on the file allow the requested access.
>>
>
> I see.

Good.

> May I conclude that you are unable to answer my challenge?
>

I don't care about your challenge. The challenge is not relevant.

> I challenged you to show exactly how else a non-root user could gain write
> access to the file, in Pavel's script, other than using /proc/../fd/...
>

It does not matter if there is no other way to achieve the result.
The reality is that the file system security model allows the access.

> Based on the fact that you have repeatedly declined to answer this
> challenge, it sounds like I can safely conclude that you do not know of
> any other way that a non-root user can accomplish this, in the situation
> Pavel outlines.
>

Great Godfrey Daniels! I have declined to address your challenge
because it is completely pointless.

> So, it sounds like we have agreement that:
>
> * In the situation Pavel outlines, a malicious non-root user
> given read-only access to the file can use /proc/../fd/.. to
> upgrade that fd to read-write access.
>

You don't have to introduce malice. The rules allow the access.
I understand that you don't like the implication of the rule.

> * If /proc/../fd/.. didn't exist, the non-root user would not have
> been able to do that.
>

I understand that you don't like the implications of /proc/.../fd/...
but the rules say that if you have this mechanism it should behave
the way it does.

> So the /proc/../fd/.. mechanism is enabling a malicious user to get
> access that they would not have been able to get in the absence of
> this mechanism.
>
>

It does not matter if there is no other way to achieve the result.
The reality is that the file system security model allows the access.
There is no need for the user to be malicious. The activity is
allowed by the rules.

> Do you agree with that summary?
>

No. You are ignoring the system security policy exactly the
same way that I am ignoring the truly unnatural behavior of this
aspect of /proc.

>
> The above are the facts, as I see them. (In contrast, the following is
> my opinion: It is my opinion that these facts demonstrate that this is
> a security violation.) But I'm not asking for your feedback about my
> opinion; I'm asking you about the facts. Do you agree with my statement
> of the facts?
>

Sorry, but I've been in too many arguments where rational
but inappropriate conclusions have been presented because
the original premise is flawed. Your assertion is that this
is a security exploit, but you have never made an argument
that any aspect of security policy has been violated. That
is the "fact" I care about. Show me the policy violation.

> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
>
>