plash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Plash] Plash 1.9: constructing file namespaces is more flexible


From: Mark Seaborn
Subject: [Plash] Plash 1.9: constructing file namespaces is more flexible
Date: Sun, 10 Jul 2005 02:06:14 +0100 (BST)

There's a new version of Plash, 1.9.  It also has a new location on
the Web.  You can get it from:
http://plash.beasts.org


In this version, I have changed the implementation of how file
namespaces are constructed for processes.

When the shell processes a command, it constructs a tree representing
the filesystem namespace, indicating where to attach filesystem
objects (files, directories and symlinks) in the namespace.  For
example, the command:

  some-command /home/fred/my-file.txt /bin/new-prog=EXPR

would produce a tree like the following:

/
 * etc: ATTACH
 * usr: ATTACH
 * lib: ATTACH
 * bin: ATTACH
    * new-prog: ATTACH
 * home
    * fred
       * my-file.txt: ATTACH

Each node in the tree is a "struct node".

At the paths "/usr", "/lib", etc. are attached real directory objects
that correspond to directories on a Linux filesystem.

The tree nodes for "/" and "/home", however, do not correspond to any
directory on a Linux filesystem.  The shell traverses this tree, and
for these tree nodes, it creates "fabricated" directory objects that
are implemented by a server process.  This is implemented in
build-fs.c.  Fabricated directories are implemented in
filesys-obj-fab.c.

In the old version of the code, the information in a "struct node" was
copied to create a fabricated directory.

Also, when it reached a node that had an object attached to it, the
code would not look at any other nodes attached *below* the node.  So,
in the example above, "/bin/new-prog" would be ignored because a
directory was attached at "/bin".  "/bin/new-prog" would not be
visible in the filesystem.  The code did not have a way of combining
the "new-prog" entry with the contents of "/bin".

In the new version of the code, the information in a "struct node" is
not copied.  There is a new kind of fabricated directory object (see
build-fs-dynamic.c) which has a pointer to a "struct node".  This
means that the tree nodes can be modified, and the changes will be
visible to processes using this directory structure.

Furthermore, the new code allows objects to be attached below
directories that are attached to the tree.  The new fabricated
directory objects can combine directory listings so that
"/bin/new-prog" will be visible in the example above (as well as other
entries in the directory attached at the path "/bin").  This is
similar to union directories, but the semantics are slightly
different.

This change means that two things are immediately possible:

 * When you run a program you can grant it read-only access to a
   directory, but read-write-create access to an object inside that
   directory.  (This means that the caveat mentioned in the note for
   version 1.5 no longer applies.)

 * Using the "PATH=EXPR" syntax, you can add entries to or replace
   entries in directories, without changing the directory, including
   those that are implicitly included in a process's file namespace,
   such as "/bin" and "/usr".  (This means that the caveat in the note
   for version 1.6 no longer applies.)

This change is an important step for a couple of features that are
planned for the future:

 * Implementing a "powerbox" for GUI programs.  The user could, over
   the lifetime of a process, grant it access to files in addition to
   the ones it was granted when it was created.  These files will be
   attached into the filesystem by modifying the "struct node"s.

 * At the moment, Plash doesn't grant access to "/tmp" by default.
   But it could grant every program access to its own private
   temporary directory, mapped into the file namespace as "/tmp".
   Below this we'll need to attach "/tmp/.X11-unix/X0" -- the socket
   that X11 clients use to connect to the X server.

This facility is similar to mount points in Linux and Plan 9 (mount
points are system-wide in Linux but per-process in Plan 9).  However,
it has slightly different semantics.  In Linux, mount points are
implemented on the basis of the identity of directories, using their
inode numbers; one directory is redirected to another directory.  In
Plash, attaching objects works on the basis of pathnames, not
directories' identities.

In both Linux and Plan 9, a directory must exist before you can mount
another directory at that point to replace it.  This is not the case
in Plash.  When you attach an object at "/bin", it adds a "bin" entry
to the root directory.  When you then attach an object at "/bin/foo",
the directory at "/bin" will be unioned with a "foo" entry.  Mount
points are limited to directories, while Plash allows you to attach
files, symlinks and other objects too.

Other changes
-------------

In libc, the functions set{,e,re,res}{u,g}id() have been made into
no-ops, which always return indicating success.

This is to deal with programs such as mkisofs and GNU make which make
pointless calls to setreuid32().  mkisofs and make call setreuid32()
with the current UID.  Ordinarily this should succeed and do nothing.
But Plash's libc fakes the current UID: it has getuid() return the
shell's UID (stored in the environment variable PLASH_FAKE_UID) rather
than the process's UID.  mkisofs and make's call to setreuid32() will
fail and they will exit.

The reason for faking the UID was to get gnuclient to work -- gnuserv
uses the user's UID in the filename of the socket it creates in /tmp.
But maybe this was not worth it.  Either way, UID-related functions in
libc aren't useful under Plash and can be turned into no-ops.
Ideally, they should be logged.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]