[comp.protocols.nfs] Why not export /fs /fs/subdir?

felps@convex.com (Robert Felps) (06/13/91)

This may not be the correct group but I thought someone might be able
to answer the question.

Why can't the following be done?

EXPORTFS(8)        NFS Programmer's Reference        EXPORTFS(8)
...
WARNINGS
     You cannot export a directory that is either a parent- or a
     sub-directory of one that is currently exported and within
     the same filesystem. It would be illegal, for example, to
     export both /usr and /usr/local if both directories resided
     in the same disk partition.

sater@cs.vu.nl (Hans van Staveren) (06/14/91)

In article <felps.676828666@convex.convex.com> felps@convex.com (Robert Felps) writes:
>
>This may not be the correct group but I thought someone might be able
>to answer the question.
>
>Why can't the following be done?
>
>EXPORTFS(8)        NFS Programmer's Reference        EXPORTFS(8)
>...
>WARNINGS
>     You cannot export a directory that is either a parent- or a
>     sub-directory of one that is currently exported and within
>     the same filesystem. It would be illegal, for example, to
>     export both /usr and /usr/local if both directories resided
>     in the same disk partition.

It is a lot worse than that. One of the not too widely known facts about
the Sun NFS server implementation is that the checking for this sort of
access is in the mount daemon, and not in the NFS daemon.

This means that when you export /fs/foo where /fs is a filesystem a client can
mount /fs/foo and using the NFS handle returned do the NFS equivalent of
a cd .. and start running around the rest of /fs.

There are more problems, but since it seems that most people believe that
subtree exporting actually achieves anything I thought I should warn you.

	Hans van Staveren
	Vrije Universiteit
	Amsterdam, Holland

shirono@ssd.csd.harris.com (Roberto Shironoshita) (06/17/91)

In article <10199@star.cs.vu.nl> sater@cs.vu.nl (Hans van Staveren) writes:

> In article <felps.676828666@convex.convex.com> felps@convex.com (Robert Felps) writes:
> This means that when you export /fs/foo where /fs is a filesystem a
> client can mount /fs/foo and using the NFS handle returned do the NFS
> equivalent of a cd .. and start running around the rest of /fs.

The big assumption in the NFS server is that the client will translate
funny paths (e.g. UNIX's . and .., VMS's [-], etc.).  That way, the server
need not impose semantics that are beyond the concept of NFS (granted, work
is still needed in this area).  So, the onus is on the client to disallow
the scenario you mention (the Sun NFS client translates .. all by itself).
--

     Roberto Shironoshita      ||   Internet: shirono@ssd.csd.harris.com
      Harris Corporation       ||
   Computer Systems Division   ||   UUCP:     ...!uunet!hcx1!shirono
                               ||
DISCLAIMER: The opinions expressed here are my own; they in no way reflect the
            opinion or policies of Harris Corporation.

barmar@think.com (Barry Margolin) (06/18/91)

In article <SHIRONO.91Jun17112649@gcx1.ssd.csd.harris.com> shirono@ssd.csd.harris.com writes:
>In article <10199@star.cs.vu.nl> sater@cs.vu.nl (Hans van Staveren) writes:
>> This means that when you export /fs/foo where /fs is a filesystem a
>> client can mount /fs/foo and using the NFS handle returned do the NFS
>> equivalent of a cd .. and start running around the rest of /fs.
>So, the onus is on the client to disallow the scenario you mention.

What kind of security is that?  Isn't the point of /etc/exports that it
restricts who can access what?  If it depends on the client not to try to
violate some convention, then it's not much of a restriction, is it?

Consider the following common situation on servers of diskless workstations:

/export/root/foo -access=foo,root=foo
/export/root/bar -access=bar,root=bar

While most NFS implementations won't allow foo to access bar's partition, a
superuser on foo could easily write a program that sends fake NFS requests,
and then access server:/export/root/foo/../bar.
-- 
Barry Margolin, Thinking Machines Corp.

barmar@think.com
{uunet,harvard}!think!barmar

thurlow@convex.com (Robert Thurlow) (06/18/91)

In <1991Jun17.224716.4729@Think.COM> barmar@think.com (Barry Margolin) writes:

>/export/root/foo -access=foo,root=foo
>/export/root/bar -access=bar,root=bar

>While most NFS implementations won't allow foo to access bar's partition, a
>superuser on foo could easily write a program that sends fake NFS requests,
>and then access server:/export/root/foo/../bar.

/export/root/foo/.. is a directory vnode on the client machine, which
has no member 'bar' unless you've created one there.  Remember that
pathname lookups always happen one component at a time over NFS so that
a standard directory separator doesn't have to be defined.

Rob T
--
Rob Thurlow, thurlow@convex.com
An employee and not a spokesman for Convex Computer Corp., Dallas, TX

barmar@think.com (Barry Margolin) (06/18/91)

In article <thurlow.677210173@convex.convex.com> thurlow@convex.com (Robert Thurlow) writes:
>In <1991Jun17.224716.4729@Think.COM> barmar@think.com (Barry Margolin) writes:
>>While most NFS implementations won't allow foo to access bar's partition, a
>>superuser on foo could easily write a program that sends fake NFS requests,
>>and then access server:/export/root/foo/../bar.
>/export/root/foo/.. is a directory vnode on the client machine, which
>has no member 'bar' unless you've created one there.  Remember that
>pathname lookups always happen one component at a time over NFS so that
>a standard directory separator doesn't have to be defined.

What do vnodes have to do with anything?  My point about "fake NFS
requests" was that a user-written program could send the following RPC
operations (I'm using pseudocode, not precise representations of the
procedure calls):

	mount_handle = Mount("/export/root/foo");
	outer_handle = Lookup(mount_handle, "..");
	bar_handle = Lookup(outer_handle, "bar");
-- 
Barry Margolin, Thinking Machines Corp.

barmar@think.com
{uunet,harvard}!think!barmar

ginsburg@samsung.COM (Scott Ginsburg) (06/20/91)

barmar@think.com (Barry Margolin) writes:

>In article <thurlow.677210173@convex.convex.com> thurlow@convex.com (Robert Thurlow) writes:
>>In <1991Jun17.224716.4729@Think.COM> barmar@think.com (Barry Margolin) writes:
>>>While most NFS implementations won't allow foo to access bar's partition, a
>>>superuser on foo could easily write a program that sends fake NFS requests,
>>>and then access server:/export/root/foo/../bar.
>>/export/root/foo/.. is a directory vnode on the client machine, which
>>has no member 'bar' unless you've created one there.  Remember that
>>pathname lookups always happen one component at a time over NFS so that
>>a standard directory separator doesn't have to be defined.

>What do vnodes have to do with anything?  My point about "fake NFS
>requests" was that a user-written program could send the following RPC
>operations (I'm using pseudocode, not precise representations of the
>procedure calls):

>	mount_handle = Mount("/export/root/foo");
>	outer_handle = Lookup(mount_handle, "..");
>	bar_handle = Lookup(outer_handle, "bar");
>-- 
>Barry Margolin, Thinking Machines Corp.

>barmar@think.com
>{uunet,harvard}!think!barmar

This actually doesn't work, at least when the server is a Sun machine.
Assuming /etc/exports contains /export/root/foo and /export/root/bar

	mount_handle = Mount("/export/root/foo");

		returns OK

	outer_handle = Lookup(mount_handle, "..");

		returns OK

	bar_handle = Lookup(outer_handle, "bar");

		returns NFSERR_NOENT


The server is smarter than you think!

							Scott

thurlow@convex.com (Robert Thurlow) (06/22/91)

In <1991Jun18.040038.15141@Think.COM> barmar@think.com (Barry Margolin) writes:

>What do vnodes have to do with anything?  My point about "fake NFS
>requests" was that a user-written program could send the following RPC
>operations (I'm using pseudocode, not precise representations of the
>procedure calls):

>	mount_handle = Mount("/export/root/foo");
>	outer_handle = Lookup(mount_handle, "..");
>	bar_handle = Lookup(outer_handle, "bar");

Barry, a Sun-based client won't send such lookups to a server, but will
interpret the ".." with respect to its own virtual filesystems, and a
Sun-based server will interpret such lookups as if you'd really asked
about ".".  Have you tried this anywhere and had it give you access to
other filesystems?  I'd call systems like that "broken".

Rob T
--
Rob Thurlow, thurlow@convex.com
An employee and not a spokesman for Convex Computer Corp., Dallas, TX

droms@regulus.bucknell.edu (Ralph E. Droms) (06/22/91)

In article <thurlow.677535175@convex.convex.com> thurlow@convex.com (Robert Thurlow) writes:


   Barry, a Sun-based client won't send such lookups to a server, [...].

I think the point is not that a Sun-based client would send such
lookups to a server, but rather a hand-crafted program (we usually
site "enterprising students" as the source of such programs) could
issue an appropriate sequence of lookups to gain access to files
outside of the mounted subtree.

--
- Ralph Droms                 Computer Science Department
  droms@bucknell.edu          323 Dana Engineering
                              Bucknell University
  (717) 524-1145              Lewisburg, PA 17837

thurlow@convex.com (Robert Thurlow) (06/22/91)

In <DROMS.91Jun21231110@regulus.bucknell.edu> droms@regulus.bucknell.edu (Ralph E. Droms) writes:

>In article <thurlow.677535175@convex.convex.com> thurlow@convex.com (Robert Thurlow) writes:

>   Barry, a Sun-based client won't send such lookups to a server, [...].

>I think the point is not that a Sun-based client would send such
>lookups to a server, but rather a hand-crafted program (we usually
>site "enterprising students" as the source of such programs) could
>issue an appropriate sequence of lookups to gain access to files
>outside of the mounted subtree.

... and if you read the rest of my article, I stated that Sun servers
refused to cooperate with this.  I consider this the correct behaviour,
and think that any system that would permit a student from doing this
is broken.

Rob T
--
Rob Thurlow, thurlow@convex.com
An employee and not a spokesman for Convex Computer Corp., Dallas, TX

barmar@think.com (Barry Margolin) (06/22/91)

In article <thurlow.677535175@convex.convex.com> thurlow@convex.com (Robert Thurlow) writes:
>>	outer_handle = Lookup(mount_handle, "..");
>>	bar_handle = Lookup(outer_handle, "bar");
>Sun-based server will interpret such lookups as if you'd really asked
>about ".".  

If this is true, then that answers the original question about why you
can't export /foo and /foo/bar.  The server apparently treats each exported
directory as if it were the root of a virtual file system.  If /foo and
/foo/bar were exported, /foo/bar/.. would be seen as trying to back up
through that virtual root.

>	     Have you tried this anywhere and had it give you access to
>other filesystems?  I'd call systems like that "broken".

No, I haven't yet tried it, although I've got a good client testbed: a
Symbolics Lisp Machine with NFS client support.  On the Lisp Machine, the
entire protocol hierarchy is directly accessible from the user mode Lisp
interpreter, so I wouldn't have to reimplement anything.  Maybe when I get
some time I'll try it.

I based my original statement on the assumption that export "access="
restrictions are only applied by the Mount daemon, not the NFS daemon (the
"rw=", "anon=", and "root=" options clearly have to be implemented by the
NFS daemon, though, but they are less expensive because they don't require
dynamic netgroup lookups).


-- 
Barry Margolin, Thinking Machines Corp.

barmar@think.com
{uunet,harvard}!think!barmar

thurlow@convex.com (Robert Thurlow) (06/22/91)

In <1991Jun22.072758.5160@Think.COM> barmar@think.com (Barry Margolin) writes:

>In article <thurlow.677535175@convex.convex.com> thurlow@convex.com (Robert Thurlow) writes:
>>Sun-based server will interpret such lookups as if you'd really asked
>>about ".".  

>If this is true, then that answers the original question about why you
>can't export /foo and /foo/bar.  The server apparently treats each exported
>directory as if it were the root of a virtual file system.  If /foo and
>/foo/bar were exported, /foo/bar/.. would be seen as trying to back up
>through that virtual root.

Yes, it's one limiting factor, but I think that the NFS server could
detect the transition from /foo to /foo/bar and back again and do the
right thing.  The real reason you can't try to export both right now
is a check in exportfs(8) that punts /foo/bar, but I frankly have
not been convinced that this has to be that way forever.  A little
more sophistication in the server would seem to permit this.

>>	     Have you tried this anywhere and had it give you access to
>>other filesystems?  I'd call systems like that "broken".

>No, I haven't yet tried it, although I've got a good client testbed: a
>Symbolics Lisp Machine with NFS client support.

Cough!  Okay, I suppose for the purposes of this test it could be
good.  However, I'd urge you to not base your impressions of NFS
on this implementation, based on the difficulties people (myself
included) were having with interoperability with it at Connectathon.


Rob T
--
Rob Thurlow, thurlow@convex.com
An employee and not a spokesman for Convex Computer Corp., Dallas, TX

sater@cs.vu.nl (Hans van Staveren) (06/24/91)

In article <thurlow.677535175@convex.convex.com> thurlow@convex.com (Robert Thurlow) writes:
>In <1991Jun18.040038.15141@Think.COM> barmar@think.com (Barry Margolin) writes:
>
>>What do vnodes have to do with anything?  My point about "fake NFS
>>requests" was that a user-written program could send the following RPC
>>operations (I'm using pseudocode, not precise representations of the
>>procedure calls):
>
>>	mount_handle = Mount("/export/root/foo");
>>	outer_handle = Lookup(mount_handle, "..");
>>	bar_handle = Lookup(outer_handle, "bar");
>
>Have you tried this anywhere and had it give you access to
>other filesystems?  I'd call systems like that "broken".
>
>Rob T

We have tried it. I can assure you that at least SunOs 4.1.1 NFS servers
are broken in the sense you call it. They are also broken in a lot of other
senses, but you should await the CERT announcements for that.

Just in case you are not convinced, export a subdirectory of a file system
so we can mount it from here, send us the name of the machine, the name of
the exported subtree, and the name of a file on the same filesystem, but
not in the exported subtree, and we will mail you the contents of the
socalled unexported file.

	Hans van Staveren
	Vrije Universiteit
	Amsterdam, Holland

kelly@nersc.gov (Bruce E Kelly) (06/24/91)

In <thurlow.677535175@convex.convex.com> (Rob Thurlow) writes:


>>       mount_handle = Mount("/export/root/foo");
>>       outer_handle = Lookup(mount_handle, "..");
>>       bar_handle = Lookup(outer_handle, "bar");
>
>Barry, a Sun-based client won't send such lookups to a server, but will
>interpret the ".." with respect to its own virtual filesystems, and a
>Sun-based server will interpret such lookups as if you'd really asked
>about ".".  Have you tried this anywhere and had it give you access to
>other filesystems?  I'd call systems like that "broken".
>
>Rob T


Sun-based clients do such lookups.  If you cd to a mount point and pass
"./../" to the open system call the lookup and the getattr go to the
server and not the client.

Bruce Kelly

droms@regulus.bucknell.edu (Ralph E. Droms) (06/25/91)

In article <10284@star.cs.vu.nl> sater@cs.vu.nl (Hans van Staveren) writes:
   >
   >Have you tried this anywhere and had it give you access to
   >other filesystems?  I'd call systems like that "broken".
   >
   >Rob T

   We have tried it. I can assure you that at least SunOs 4.1.1 NFS servers
   are broken in the sense you call it.

Perhaps Rob T and I are not talking about the same situation.  Suppose
I have the following filesystem subtree on an NFS server S (where '*'
is some arbitrary path):

               *
              / \
             /   \
            A     B

and the export list on S:

*/A	-access=A
*/B	-access=B

I can handcraft a program that issues NFS requests (through callrpc)
from A to do:

     fh = mount("*/A");
     fh = lookup(fh, "..");
     fh = lookup(fh, "B");
     fh = lookup(fh, "bar");
     result = read(fh, buf);

buf now contains the contents of "*/B/bar", although A has not mounted
and S has explicitly exported "*/B" to be inaccessible to client A.

This experiment was run on between a Sun 4/20 client and a Sun 3/160
client, both running SunOS 4.1 (*not* 4.1.1).

The exported file system information is managed by the mount daemon
and protocol.  How would the NFS server learn of that information?

--
- Ralph Droms                 Computer Science Department
  droms@bucknell.edu          323 Dana Engineering
                              Bucknell University
  (717) 524-1145              Lewisburg, PA 17837

krey@ira.uka.de (Andreas Krey) (06/26/91)

In article <DROMS.91Jun25103646@regulus.bucknell.edu>, droms@regulus.bucknell.edu (Ralph E. Droms) writes:
|> In article <10284@star.cs.vu.nl> sater@cs.vu.nl (Hans van Staveren) writes:
|>    >
|>    >Have you tried this anywhere and had it give you access to
|>    >other filesystems?  I'd call systems like that "broken".
|>    >
|>    >Rob T
|> 
|>    We have tried it. I can assure you that at least SunOs 4.1.1 NFS servers
|>    are broken in the sense you call it.
|> 
|> Perhaps Rob T and I are not talking about the same situation.  Suppose
|> I have the following filesystem subtree on an NFS server S (where '*'
|> is some arbitrary path):
|> 
|>                *
|>               / \
|>              /   \
|>             A     B
|> 
|> and the export list on S:
|> 
|> */A	-access=A
|> */B	-access=B
|> 
|> I can handcraft a program that issues NFS requests (through callrpc)
|> from A to do:
|> 
|>      fh = mount("*/A");
|>      fh = lookup(fh, "..");
|>      fh = lookup(fh, "B");
|>      fh = lookup(fh, "bar");
|>      result = read(fh, buf);
|> 
|> buf now contains the contents of "*/B/bar", although A has not mounted
|> and S has explicitly exported "*/B" to be inaccessible to client A.
|> 
|> This experiment was run on between a Sun 4/20 client and a Sun 3/160
|> client, both running SunOS 4.1 (*not* 4.1.1).
|> 
|> The exported file system information is managed by the mount daemon
|> and protocol.  How would the NFS server learn of that information?
|> 
|> --
|> - Ralph Droms                 Computer Science Department
|>   droms@bucknell.edu          323 Dana Engineering
|>                               Bucknell University
|>   (717) 524-1145              Lewisburg, PA 17837

Important addition: On the server, A, B, and the directory named '*' must
be on the same disk partition. NFS only does lookups within a single
disk filesystem, so it always exports a full DISK filesystem even if
the mount point is not the root of that filesystem.

-- 
Andy

4/1/91 is gone and 4/1/92 yet to come. Applies to this article.