2002-04-11 23:21:25

by xystrus

[permalink] [raw]
Subject: link() security

Hi all,

If this subject has been beaten to death in the past, a link to the
discussion is really all I need...

Is there a good reason why a user can successfully link() a file to
which they do not have any access?

Here's a scenario:

Many linux systems, like Slackware and SuSE, favor the permissions
1777 for the mail spool directory. This is a good policy from a
security perspective, as it prevents mail utilities from requiring
SUID/SGID root or mail privileges to create a user's spool and/or lock
files.

Now, people often point to several problems with this scheme. Such
as the following:

* users can create an unlimited number of files in this directory,
potentially using up all availabile inodes

* users can use the spool as scratch space, and potentially fill up
the spool filesystem

* users can create links to other users' spool files.

The first two really are very minor problems in comparison to a
potential security breach (priviledge elevation), and can be solved
with quota and/or site policy. Troublesome users who ignore policy
can be dealt with appropriately.

The last one is a bit sticky though. As a regular user, I can create
a hard link to someone's spool file, and call it whatever I want.
This isn't a major problem, because the resulting link retains the
permissions and ownership of the original file; therefore a user who
does this can't gain access to anything they didn't already have
access to... However, it certainly can constitute an abuse of
resources and/or site policy.

There are cases where this can be a security problem though; and
what's more, there's no apparent way to identify who created the link,
since the link retains ownership of the original file. If, for
example, a malicious user noticed that a particular new user's spool
file had not been created, he could link(mymailbox, newusermailbox).
And now (ignoring locking issues in the spool area), one of two things
will happen:

a) if the mail delivery programs run with privileges (despite not
needing to with 1777 permissions on the spool), the new user's
mail will be delivered to the malicious user's spool.

b) if they don't run with privileges, a mail delivery error should
result, alerting the system administrators to the problem.

Either way, this isn't really a great situation. But here's the worst
part: a malicious user can frame someone, say another user they hold
a grudge against, as having done this. Since the link() call succeeds
regardless of permissions on the file, the malicious user can also
call link(framedusermailbox, newusermailbox)! The system
administration team has no way to identify who created the file. They
can't even look and see who was on at time of creation, because the
creation time is the same as that of the original file. Worse still,
system administrators who are not aware of this behavior of link() may
mistakenly believe that the file was created by the framed user, and
recommend expulsion or termination of their employment/access/whatever
on that basis.

I've tested that this works on Red Hat 7.1 with pristine 2.4.17
sources and using the ln command. I have not actually written a
program that calls link() in this manner. However the ln command is
not SUID, so I can imagine no other way this would work...

In my opinion, the solution to this problem is to check that the file
being linked is owned by the UID of the calling process, or that the
UID is root (or that the process has the appropriate capabilities -- a
facility that I'm not overly familiar with). If not, the call to
link() should fail with EACCES or EPERM.


Thanks,
Xy


2002-04-12 01:15:31

by Chris Wright

[permalink] [raw]
Subject: Re: link() security

* xystrus ([email protected]) wrote:
>
> Is there a good reason why a user can successfully link() a file to
> which they do not have any access?

Other than the fact that it's standard behaviour? ;-) Well, the SUS
actually makes an allowance for this:

"The implementation may require that the calling process has
permission to access the existing file."

If you are interested, the Openwall patch does just this (among other things)
http://openwall.com. Work based on Solar Designer's Openwall patch has
been brought forward to more recent 2.4 and 2.5 kernels. Both the
following projects implement the Openwall secure link feature:

http://grsecurity.net
http://lsm.immunix.org

This can break some applications that make assumptions wrt. link(2)
(Courier MTA for example).

cheers,
-chris

2002-04-13 17:02:37

by xystrus

[permalink] [raw]
Subject: Re: link() security

On Sat, Apr 13, 2002 at 05:59:54PM +0100, Alan Cox wrote:
> > http://openwall.com. Work based on Solar Designer's Openwall patch has
> > been brought forward to more recent 2.4 and 2.5 kernels. Both the
> > following projects implement the Openwall secure link feature:
> >
> > http://grsecurity.net
> > http://lsm.immunix.org
> >
> > This can break some applications that make assumptions wrt. link(2)
> > (Courier MTA for example).
>
> How practical is it to make this a mount option and to do so cleanly ?

Perhaps two options: one to allow creation of the link only when the
UIDs match; and the other to allow the link when GIDs match, to keep
Courier happy?

2002-04-13 17:26:30

by Alan

[permalink] [raw]
Subject: Re: link() security

> http://openwall.com. Work based on Solar Designer's Openwall patch has
> been brought forward to more recent 2.4 and 2.5 kernels. Both the
> following projects implement the Openwall secure link feature:
>
> http://grsecurity.net
> http://lsm.immunix.org
>
> This can break some applications that make assumptions wrt. link(2)
> (Courier MTA for example).

How practical is it to make this a mount option and to do so cleanly ?

2002-04-13 17:48:21

by Hank Leininger

[permalink] [raw]
Subject: Re: link() security

On 2002-04-13, xystrus <[email protected]> wrote:

> On Sat, Apr 13, 2002 at 05:59:54PM +0100, Alan Cox wrote:
> > > http://openwall.com. Work based on Solar Designer's Openwall patch
> > > has been brought forward to more recent 2.4 and 2.5 kernels. Both
> > > the following projects implement the Openwall secure link feature:
> > >
> > > http://grsecurity.net
> > > http://lsm.immunix.org
> > >
> > > This can break some applications that make assumptions wrt. link(2)
> > > (Courier MTA for example).
> >
> > How practical is it to make this a mount option and to do so cleanly ?

...I like the mount option idea, will explore for my next patch... ;)

> Perhaps two options: one to allow creation of the link only when the
> UIDs match; and the other to allow the link when GIDs match, to keep
> Courier happy?

Well, if UIDs match there's no problem. From Openwall (2.2.20 fs/namei.c
at/near line 1312):
if (current->fsuid != inode->i_uid &&
...other tests

I've been using a modification[1] of the Openwall patch to allow the GID
case just as you describe, for some in-house secure drop-directory where
multiple daemons share a GID to play in their queue directory. I've never
used courier but it sounds like that may work w/this change as well. From
2.2.20-hap-5 fs/namei.c line 1318:
#ifdef CONFIG_SECURE_NOTSOMUCH
/*
* Let users hard link to files in their group.
*/
current->fsgid != inode->i_gid &&
#endif

This works well, but the CONFIG_ option name is chosen for a reason; this
has some side effects which may not be desirable. Allowing GID matches
will often result in users being able to hard link to each others files, on
systems where users are all in group 'users' by default (and users have
files in non-0700 directories).

I know the grsecurity guys have ported most of both Openwall and HAP to
2.4, not positive if they carried over the NOTSOMUCH option but it'd be
simple to add. Keep in mind all this violates POSIX standards so isn't
likely to ever be in-kernel, but the patches should be maintained for some
reasonably large value of $forever.

[1] http://www.theaimsgroup.com/~hlein/hap-linux/, the patch has many
other things, just search for CONFIG_SECURE_NOTSOMUCH.

--
Hank Leininger <[email protected]>

2002-04-14 01:49:47

by Chris Wright

[permalink] [raw]
Subject: Re: link() security

* Alan Cox ([email protected]) wrote:
>
> How practical is it to make this a mount option and to do so cleanly ?

Well, it's not too bad. Below is a patch (albeit quick and dirty)
that adds a MS_SECURE_LINK mount option to enforce this behaviour.
To simplify testing, I cheated and piggy backed the MS_SECURE_LINK option
on the MS_NOSUID option. So a simple 'mount -o nosuid,remount /foo'
enables this. The secure link test allows a hard link if you own the
target file or are in the same group _and_ can (by group) write to
the file, or have proper capability, of course. Patch is against
2.4.19-pre5-ac3.

cheers,
-chris

--- 2.4.19-pre5-ac3/fs/namespace.c.link Sat Apr 13 18:06:21 2002
+++ 2.4.19-pre5-ac3/fs/namespace.c Sat Apr 13 18:12:11 2002
@@ -707,8 +707,10 @@
return -EINVAL;

/* Separate the per-mountpoint flags */
- if (flags & MS_NOSUID)
+ if (flags & MS_NOSUID) {
mnt_flags |= MNT_NOSUID;
+ flags |= MS_SECURE_LINK;
+ }
if (flags & MS_NODEV)
mnt_flags |= MNT_NODEV;
if (flags & MS_NOEXEC)
--- 2.4.19-pre5-ac3/fs/namei.c.link Sat Apr 13 18:06:21 2002
+++ 2.4.19-pre5-ac3/fs/namei.c Sat Apr 13 18:12:11 2002
@@ -1614,6 +1614,11 @@
error = -EPERM;
if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
goto exit_lock;
+ if (IS_SECURE_LINK(inode) && (!capable(CAP_FOWNER) &&
+ current->fsuid != inode->i_uid &&
+ (current->fsgid != inode->i_gid ||
+ !(inode->i_mode & S_IWGRP))))
+ goto exit_lock;
if (!dir->i_op || !dir->i_op->link)
goto exit_lock;

--- 2.4.19-pre5-ac3/include/linux/fs.h.link Sat Apr 13 18:06:21 2002
+++ 2.4.19-pre5-ac3/include/linux/fs.h Sat Apr 13 18:15:38 2002
@@ -111,6 +111,7 @@
#define MS_MOVE 8192
#define MS_REC 16384
#define MS_VERBOSE 32768
+#define MS_SECURE_LINK 65536
#define MS_ACTIVE (1<<30)
#define MS_NOUSER (1<<31)

@@ -118,7 +119,7 @@
* Superblock flags that can be altered by MS_REMOUNT
*/
#define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_NOATIME|\
- MS_NODIRATIME)
+ MS_NODIRATIME|MS_SECURE_LINK)

/*
* Old magic mount flag and mask
@@ -161,6 +162,7 @@
#define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE)
#define IS_NOATIME(inode) (__IS_FLG(inode, MS_NOATIME) || ((inode)->i_flags & S_NOATIME))
#define IS_NODIRATIME(inode) __IS_FLG(inode, MS_NODIRATIME)
+#define IS_SECURE_LINK(inode) __IS_FLG(inode, MS_SECURE_LINK)

#define IS_DEADDIR(inode) ((inode)->i_flags & S_DEAD)

2002-04-15 14:44:32

by Patrick J. LoPresti

[permalink] [raw]
Subject: Re: link() security

xystrus <[email protected]> writes:

> Many linux systems, like Slackware and SuSE, favor the permissions
> 1777 for the mail spool directory. This is a good policy from a
> security perspective, as it prevents mail utilities from requiring
> SUID/SGID root or mail privileges to create a user's spool and/or lock
> files.

Actually, that is a horrible policy from a security perspective. The
shared mail spool itself is a poor design and always has been.

A better design is to use a separate spool directory for each user
(/var/spool/mail/user/ or ~user/mail/ or somesuch), and only allow
that user to access it at all. This solves *all* of the security
problems you mention:

*) It avoids attacks based on race conditions, because you cannot
create files in somebody else's spool.

*) Admins can manage space with quotas or partitions just like they
do for user home directories (i.e., it is a solved problem).

*) You cannot link() to somebody else's spool file because you
cannot even read the directory in which it resides.

The solution to a fundamentally broken spool design is to fix that
design, not to patch the kernel in nonstandard ways to plug just one
of its multiple flaws.

And yes, there are MTAs which use a directory per user by default.
Fix your MTA, do not hack the kernel.

All just My Opinion, of course.

- Pat

2002-04-15 19:25:41

by H. Peter Anvin

[permalink] [raw]
Subject: Re: link() security

Followup to: <[email protected]>
By author: "Patrick J. LoPresti" <[email protected]>
In newsgroup: linux.dev.kernel
> Actually, that is a horrible policy from a security perspective. The
> shared mail spool itself is a poor design and always has been.
>
> A better design is to use a separate spool directory for each user
> (/var/spool/mail/user/ or ~user/mail/ or somesuch), and only allow
> that user to access it at all. This solves *all* of the security
> problems you mention:
>
> *) It avoids attacks based on race conditions, because you cannot
> create files in somebody else's spool.
>
> *) Admins can manage space with quotas or partitions just like they
> do for user home directories (i.e., it is a solved problem).
>
> *) You cannot link() to somebody else's spool file because you
> cannot even read the directory in which it resides.
>
> The solution to a fundamentally broken spool design is to fix that
> design, not to patch the kernel in nonstandard ways to plug just one
> of its multiple flaws.

Not to mention the fact that the single file mailbox design is itself
flawed. Mailboxes are fundamentally directories, which news server
authors quickly realized.

-hpa
--
<[email protected]> at work, <[email protected]> in private!
"Unix gives you enough rope to shoot yourself in the foot."
http://www.zytor.com/~hpa/puzzle.txt <[email protected]>

2002-04-15 19:36:44

by Chris Adams

[permalink] [raw]
Subject: Re: link() security

Once upon a time, H. Peter Anvin <[email protected]> said:
>Not to mention the fact that the single file mailbox design is itself
>flawed. Mailboxes are fundamentally directories, which news server
>authors quickly realized.

Funny that news server authors realized that storing messages in files
by themselves is a bad idea, while at the same time mail server authors
realized that storing messages together in a single file is a bad idea.
Which one is right? Both? Neither?
--
Chris Adams <[email protected]>
Systems and Network Administrator - HiWAAY Internet Services
I don't speak for anybody but myself - that's enough trouble.

2002-04-15 19:55:40

by H. Peter Anvin

[permalink] [raw]
Subject: Re: link() security

Followup to: <[email protected]>
By author: Chris Adams <[email protected]>
In newsgroup: linux.dev.kernel
>
> Once upon a time, H. Peter Anvin <[email protected]> said:
> >Not to mention the fact that the single file mailbox design is itself
> >flawed. Mailboxes are fundamentally directories, which news server
> >authors quickly realized.
>
> Funny that news server authors realized that storing messages in files
> by themselves is a bad idea, while at the same time mail server authors
> realized that storing messages together in a single file is a bad idea.
> Which one is right? Both? Neither?
>

It depends on your access patterns. Newer news server use what I
would classify as custom filesystems (which is what binary databases
are, by and large) rather than "single files."

-hpa
--
<[email protected]> at work, <[email protected]> in private!
"Unix gives you enough rope to shoot yourself in the foot."
http://www.zytor.com/~hpa/puzzle.txt <[email protected]>

2002-04-15 20:36:37

by Patrick J. LoPresti

[permalink] [raw]
Subject: Re: link() security

"H. Peter Anvin" <[email protected]> writes:

> > Funny that news server authors realized that storing messages in files
> > by themselves is a bad idea, while at the same time mail server authors
> > realized that storing messages together in a single file is a bad idea.
> > Which one is right? Both? Neither?
> >
>
> It depends on your access patterns. Newer news server use what I
> would classify as custom filesystems (which is what binary databases
> are, by and large) rather than "single files."

Exactly. Although I would go farther.

I would not be at all surprised if a traditional news spool worked
just fine on a "real" high-performance file system; i.e., one whose
lookup/creat/unlink was not linear in the number of directory entries.
I wonder how well an old-fashioned news spool would perform on XFS,
for instance.

"One file per message" has many advantages, both for news and for
mail. The biggest advantage is conceptual simplicity. It is really
nice when you can use traditional Unix tools (like grep, mv, rm) to
fix things when they break. Because they always break, sooner or
later.

Sure, you may wind up with 50,000 files in one directory. But I would
rather rely on the filesystem wizards to deal with that than switch to
some obscure custom database format. Maybe that's just me...

- Pat

2002-04-15 21:41:26

by xystrus

[permalink] [raw]
Subject: Re: link() security

On Mon, Apr 15, 2002 at 10:44:30AM -0400, Patrick J. LoPresti wrote:
> A better design is to use a separate spool directory for each user
> (/var/spool/mail/user/ or ~user/mail/ or somesuch), and only allow
> that user to access it at all. This solves *all* of the security
> problems you mention:

I'll agree with the above, however consider that there are other
reasons to have drwxrwxrwt directories besides a mail spool. My point
was not that link() should be modified because it makes mail spools
that use this feature less secure; my point was that (IMO) link should
be modified because it does not make sense to allow users to create
hard links to files they have no access to, in general. The mail
spool example was simply one common example.

IMO, if I have created a file, and I own the file, then there are only
two users who should get to decide whether that file gets deleted or
not: me, and root. Regular users should not be able to create hard
links to my files, potentially without me knowing about it. Allowing
them to do so means that you allow users who do not own a resource,
and have no access to that resource, to potentially manage control of
that resource to some extent. I don't see how this policy makes any
sense. It allows that a file I created may be hanging around despite
the fact that I think it's been deleted. And that just seems like a
very bad idea to me.

> The solution to a fundamentally broken spool design is to fix that
> design, not to patch the kernel in nonstandard ways to plug just one
> of its multiple flaws.

Rephrased, your argument is basically that it is unwise to continue a
behavior which is fundamentally flawed just because it is a standard
behavior. That is precisely my argument WRT the current behavior of
link().

> All just My Opinion, of course.

Ditto. :)

Xy

2002-04-15 22:30:40

by Alan

[permalink] [raw]
Subject: Re: link() security

> Not to mention the fact that the single file mailbox design is itself
> flawed. Mailboxes are fundamentally directories, which news server
> authors quickly realized.

And then unrealized when they hit performance limitations. Its a trade off
and one that most news systems seem to prefer to use a custom database
for

2002-04-15 23:05:26

by H. Peter Anvin

[permalink] [raw]
Subject: Re: link() security

Alan Cox wrote:
>>Not to mention the fact that the single file mailbox design is itself
>>flawed. Mailboxes are fundamentally directories, which news server
>>authors quickly realized.
>
> And then unrealized when they hit performance limitations. Its a trade off
> and one that most news systems seem to prefer to use a custom database
> for

Well, a database is basically a custom filesystem.

-hpa

2002-04-15 23:10:25

by Alan

[permalink] [raw]
Subject: Re: link() security

> > And then unrealized when they hit performance limitations. Its a trade off
> > and one that most news systems seem to prefer to use a custom database
> > for
>
> Well, a database is basically a custom filesystem.

I would have to disagree. There are fundamentally different transaction
semantics between the two as well as indexing constraints. I can't for
example find commit() and rollback() in posix.1 8)


2002-04-15 23:14:40

by H. Peter Anvin

[permalink] [raw]
Subject: Re: link() security

Alan Cox wrote:
>>>And then unrealized when they hit performance limitations. Its a trade off
>>>and one that most news systems seem to prefer to use a custom database
>>>for
>>
>>Well, a database is basically a custom filesystem.
>
> I would have to disagree. There are fundamentally different transaction
> semantics between the two as well as indexing constraints. I can't for
> example find commit() and rollback() in posix.1 8)
>

OK, perhaps I should have been more explicit...

A filesystem is *one kind* of database.

The operations that various databases implement differ -- not all
databases have commit()/rollback(), nor do all of them implement
relationals, object linking, etc.

The point was mostly that storing mail in a (basically) unstructured
flat-file format isn't really consistent with the operations you want to
perform on it. I didn't mean the directory/file format was necessarily
the ultimate solution, only that (a) it works better than mbox, (b) it's
been around for a long time.

-hpa

2002-04-16 00:01:49

by Kurt Wall

[permalink] [raw]
Subject: Re: link() security

Scribbling feverishly on April 15, H. Peter Anvin managed to emit:

[schnip]

> The point was mostly that storing mail in a (basically) unstructured
> flat-file format isn't really consistent with the operations you want to
> perform on it. I didn't mean the directory/file format was necessarily
> the ultimate solution, only that (a) it works better than mbox, (b) it's
> been around for a long time.

[nod]

I suppose it made sense back when we made our 1s and 0s by hand, but
whoever (would dare) take credit for "designing" the UNIX mbox "format"
needs a remedial course if file format design.

K
--
Are you ever going to do the dishes? Or will you change your major to biology?

2002-04-16 01:37:36

by H. Peter Anvin

[permalink] [raw]
Subject: Re: link() security

Followup to: <[email protected]>
By author: "Patrick J. LoPresti" <[email protected]>
In newsgroup: linux.dev.kernel
> >
> > It depends on your access patterns. Newer news server use what I
> > would classify as custom filesystems (which is what binary databases
> > are, by and large) rather than "single files."
>
> Exactly. Although I would go farther.
>
> I would not be at all surprised if a traditional news spool worked
> just fine on a "real" high-performance file system; i.e., one whose
> lookup/creat/unlink was not linear in the number of directory entries.
> I wonder how well an old-fashioned news spool would perform on XFS,
> for instance.
>
> "One file per message" has many advantages, both for news and for
> mail. The biggest advantage is conceptual simplicity. It is really
> nice when you can use traditional Unix tools (like grep, mv, rm) to
> fix things when they break. Because they always break, sooner or
> later.
>
> Sure, you may wind up with 50,000 files in one directory. But I would
> rather rely on the filesystem wizards to deal with that than switch to
> some obscure custom database format. Maybe that's just me...
>

I think the biggest problem with the one-file-per-message format is
that you still want to maintain some kind of metadata (.overview
files.) This is cached information, but still needs to be maintained,
so you don't end up opening up every file to get the overview data.
With a application-specific store, you can make that more explicit.

-hpa
--
<[email protected]> at work, <[email protected]> in private!
"Unix gives you enough rope to shoot yourself in the foot."
http://www.zytor.com/~hpa/puzzle.txt <[email protected]>