Age | Commit message (Collapse) | Author |
|
Found using the Clang Static Analyzer.
* trans/fakeroot.c (new_node): Do not leak a pointer to freed memory.
Store NULL at *np instead. This fixes a node use-after-free in
netfs_S_dir_lookup.
|
|
When using fat nodes, expressions of the form E->nn can be rewritten
as netfs_node_netnode (E). This is much faster as it only involves a
offset calculation. For reference, I used the following semantic
patch to create the patch:
@@
expression E;
@@
- E->nn
+ netfs_node_netnode (E)
* trans/fakeroot.c: Use netfs_node_netnode instead of np->nn.
|
|
Previously, fakeroot stored netnodes in the hash table. But we are
not interested in a cache for netnodes, we need a node cache. So
fakeroot kept pointers to the associated node object in each netnode
object.
Use fat netfs nodes, which combine node and netnode objects.
* trans/fakeroot.c (struct netnode): Remove np.
(idport_ihash): Fix ihash location pointer offset.
(new_node): Allocate fat nodes, store the node pointer in the hash
table.
(netfs_node_norefs): Adjust accordingly.
(netfs_S_dir_lookup): Likewise.
|
|
* trans/mtab.c (main): Fix initialization of mtab in one-shot mode.
|
|
As of recently, fakeroot would fail to create symlinks:
% fakeroot-hurd ln -s foo a
ln: failed to create symbolic link ‘a’: Operation not permitted
Fix this by overriding fshelp_isowner.
Various netfs functions will call fshelp_isowner to check whether USER
is allowed to do some operation. As fakeroot is not running within
the fakeauth'ed environment, USER contains the real user.
I have no explanation why this ever worked.
* trans/fakeroot.c (fshelp_isowner): New function.
|
|
* trans/fakeroot.c (main): Use C99-style struct initialization to
initialize argp. This avoids a warning about missing field
initializers.
|
|
* trans/fakeroot.c (netfs_attempt_chown): Fix comparison between
signed and unsigned integer expressions.
|
|
A spurious semicolon caused a control flow bug in check_openmodes,
leading to a port leak.
* trans/fakeroot.c (check_openmodes): Remove spurious semicolon.
|
|
GNU libc has provided the 'crypt' function in libcrypt for a long time,
making this check unnecessary.
* configure.ac: Remove libcrypt check and 'LIBCRYPT' substitution.
* config.make.in (LIBCRYPT): Remove.
* trans/Makefile (password-LDLIBS): Change $(LIBCRYPT) to -lcrypt.
* utils/Makefile (login-LDLIBS, addauth-LDLIBS, setauth-LDLIBS):
Likewise.
|
|
This enables the compiler to check that the server function
declarations match MIGs expectations. Fix a few oddities along the
way.
* console-client/trans.c: Include MIG-generated server header file(s).
* console/console.c: Likewise. Also, fix declarations.
* console/mutations.h (TIOCTL_IMPORTS): Just use libnetfs/priv.h.
* console/priv.h: Delete now unused file.
* ext2fs/storeinfo.c: Include MIG-generated server header file(s).
* fatfs/inode.c: Likewise.
* fatfs/main.c: Likewise. Also, fix declaration.
* isofs/inode.c: Likewise.
* libdiskfs/boot-start.c: Likewise.
* libdiskfs/file-chg.c: Include the correct MIG-generated server header file.
* libdiskfs/file-chmod.c: Include MIG-generated server header file(s).
* libdiskfs/file-get-fs-opts.c: Likewise.
* libdiskfs/init-startup.c: Likewise.
* libnetfs/file-get-children.c: Likewise.
* libnetfs/file-getcontrol.c: Include the correct MIG-generated server
header file.
* libnetfs/file-set-translator.c: Include MIG-generated server header file(s).
* libnetfs/fsstubs.c: Likewise.
* libtrivfs/file-access.c: Likewise.
* libtrivfs/file-chauthor.c: Likewise.
* libtrivfs/file-chflags.c: Likewise.
* libtrivfs/file-chg.c: Likewise.
* libtrivfs/file-chmod.c: Likewise.
* libtrivfs/file-chown.c: Likewise.
* libtrivfs/file-exec.c: Likewise.
* libtrivfs/file-get-children.c: Likewise.
* libtrivfs/file-get-fs-options.c: Likewise.
* libtrivfs/file-get-source.c: Likewise.
* libtrivfs/file-get-storage-info.c: Likewise.
* libtrivfs/file-get-trans.c: Likewise.
* libtrivfs/file-get-transcntl.c: Likewise.
* libtrivfs/file-getcontrol.c: Likewise.
* libtrivfs/file-getfh.c: Likewise.
* libtrivfs/file-getlinknode.c: Likewise.
* libtrivfs/file-lock.c: Likewise.
* libtrivfs/file-reparent.c: Likewise.
* libtrivfs/file-set-size.c: Likewise.
* libtrivfs/file-set-trans.c: Likewise.
* libtrivfs/file-statfs.c: Likewise.
* libtrivfs/file-sync.c: Likewise.
* libtrivfs/file-syncfs.c: Likewise.
* libtrivfs/file-utimes.c: Likewise.
* libtrivfs/fsys-forward.c: Likewise.
* libtrivfs/fsys-get-options.c: Likewise.
* libtrivfs/fsys-getroot.c: Likewise.
* libtrivfs/fsys-goaway.c: Likewise.
* libtrivfs/fsys-set-options.c: Likewise.
* libtrivfs/fsys-stubs.c: Likewise.
* libtrivfs/fsys-syncfs.c: Likewise.
* libtrivfs/io-async-icky.c: Likewise.
* libtrivfs/io-async.c: Likewise.
* libtrivfs/io-duplicate.c: Likewise.
* libtrivfs/io-identity.c: Likewise.
* libtrivfs/io-map.c: Likewise.
* libtrivfs/io-modes-get.c: Likewise.
* libtrivfs/io-modes-off.c: Likewise.
* libtrivfs/io-modes-on.c: Likewise.
* libtrivfs/io-modes-set.c: Likewise.
* libtrivfs/io-owner-get.c: Likewise.
* libtrivfs/io-owner-mod.c: Likewise.
* libtrivfs/io-pathconf.c: Likewise.
* libtrivfs/io-read.c: Likewise.
* libtrivfs/io-readable.c: Likewise.
* libtrivfs/io-reauthenticate.c: Likewise.
* libtrivfs/io-restrict-auth.c: Likewise.
* libtrivfs/io-revoke.c: Likewise.
* libtrivfs/io-seek.c: Likewise.
* libtrivfs/io-select.c: Likewise.
* libtrivfs/io-stat.c: Likewise.
* libtrivfs/io-stubs.c: Likewise.
* libtrivfs/io-version.c: Likewise.
* libtrivfs/io-write.c: Likewise.
* pfinet/tunnel.c: Likewise.
* storeio/io.c: Likewise.
* storeio/storeio.c: Likewise.
* term/users.c: Likewise.
* tmpfs/node.c: Likewise.
* trans/fakeroot.c: Likewise. Also, include all server headers that provide
the X_server_routine functions...
(netfs_demuxer): ... that were previously declared here.
* trans/fifo.c: Include MIG-generated server header file(s).
* trans/firmlink.c: Likewise.
* trans/hello-mt.c: Likewise.
* trans/hello.c: Likewise.
* trans/magic.c: Likewise.
* trans/mtab.c: Likewise.
* trans/new-fifo.c: Likewise.
* trans/null.c: Likewise.
* trans/proxy-defpager.c: Likewise.
* trans/streamio.c: Likewise.
* libdiskfs/fsmutations.h: Qualify the import with the libraries path.
Without this change, out-of-tree builds would no longer work.
* libnetfs/mutations.h: Likewise.
* libtrivfs/mig-mutate.h: Likewise.
|
|
* trans/Makefile: Add ifsock-MIGSFLAGS.
* trans/ifsock.c (S_ifsock_getsockaddr): Fix receiver lookup.
|
|
Previously, the mig mutator functions were in migsupport.c, preventing
them from being inlined into the mig-generated server functions. Put
them in mig-decls.h instead. Rename mutations.h to mig-mutate.h.
This is the naming convention used for pflocal.
* libtrivfs/fsmutations.h: Rename to mig-mutate.h, adopt imports.
* libtrivfs/Makefile: Adopt accordingly.
* libtrivfs/migsupport.c: Rename to mig-decls.h.
* libtrivfs/trivfs.h: Move dynamic classes/buckets declarations to
mig-decls.h, remove superfluous imports.
* exec/execmutations.h: Fix import.
* pfinet/mig-mutate.h: Likewise.
* trans/Makefile: Likewise.
|
|
|
|
Previously, map_device_to_path mapped unknown device strings to
"none". Return a copy of the original source string instead so that
e.g. nfs mount point points are properly handled.
* trans/mtab.c (map_device_to_path): Do not map unknown source strings
to "none".
|
|
Previously, the mtab translator would guess the source of a filesystem
translator from its last argument. This made all kinds of
non-filesystem translators appear in /proc/mounts, causing severe
problems due to umount --all removing vital passive translator
records.
Fix this by ignoring all translators that do not explicitly implement
file_get_source.
* trans/mtab.c (mtab_populate): Ignore translators that do not
implement file_get_source.
|
|
* hurd/fs.defs: Add file_get_children and file_get_source.
* hurd/fsys.defs: Remove fsys_get_children and fsys_get_source.
* libdiskfs/fsys-get-children.c: Rename and adapt accordingly.
* libdiskfs/fsys-get-source.c: Likewise.
* libnetfs/fsys-get-children.c: Likewise.
* libnetfs/fsys-get-source.c: Likewise.
* libtrivfs/fsys-get-children.c: Likewise.
* libtrivfs/fsys-get-source.c: Likewise.
* libdiskfs/diskfs.h: Adapt prototype and comment.
* libnetfs/netfs.h: Likewise.
* libtrivfs/trivfs.h: Likewise.
* libdiskfs/get-source.c: Adapt default implementation, provide
diskfs_disk_name by default.
* libnetfs/netfs.h: Adapt default implementation.
* libtrivfs/get-source.c: Likewise.
* libdiskfs/Makefile: Adapt accordingly.
* libnetfs/Makefile: Likewise.
* libtrivfs/Makefile: Likewise.
* trans/symlink.c: Likewise.
* trans/mtab.c: Likewise.
|
|
When a client finds a node from the hash table, it could happen that
another thread is still holding one reference on it before the current
thread has acquired its own. Simply checking for a non zero refcount isn't
enough, the new client must atomically acquire its own reference.
* trans/fakeroot.c (netfs_S_dir_lookup): Find and acquire node reference
while holding netfs_node_refcnt_lock.
|
|
* trans/fakeroot.c (netfs_S_dir_lookup): Fix node dereference.
|
|
Instead of the FAKE_REFERENCE flag, rework node caching so that nodes are
retained only if their attributes are actually changed. In addition, don't
remove unreferenced nodes from the hash table at protid release, since
their reference counter is unstable. Do it on node destruction, once the
reference counter has reached 0. This means lookups can return nodes not
referenced (other than by the hash table), a condition for which a check
is added. By never acquiring a reference on such nodes, their counter is
guaranteed to remain stable once unreferenced.
* trans/fakeroot.c (FAKE_REFERENCE): Remove macro.
(FAKE_DEFAULT): New macro.
(set_default_attributes): New function.
(set_faked_attribute): Likewise.
(netfs_node_norefs): Remove node from hash table, properly taking care
of all the locks involved.
(fakeroot_netfs_release_protid): Remove node handling code, merely call
netfs_release_protid.
(netfs_S_dir_lookup): Handle unreferenced nodes, call set_default_attributes
on node creation, remove call to netfs_attempt_chown.
(netfs_attempt_chown): Call set_faked_attribute instead of accessing faked
flags directly.
(netfs_attempt_chauthor): Likewise.
(netfs_attempt_chmod): Likewise.
(main): Likewise.
|
|
Unconditionally relay chmod requests instead of filtering those that
don't change the executable bit.
* trans/fakeroot.c (netfs_attempt_chmod): Unconditionally call file_chmod
with an unaltered mode.
|
|
This reverts commit 672005782e57e049c7c8f4d6d0b2a80c0df512b4.
That change is apparently not needed and introduced a deadlock.
* trans/fakeroot.c (netfs_attempt_mkfile): Unlock directory node before
creating new node.
|
|
* trans/fakeroot.c (netfs_S_dir_lookup): Deallocate rights to intermediate
file systems.
|
|
Use translation functions instead of doing the lookup manually.
* trans/Makefile (password-MIGSFLAGS): Add mutators.
* trans/password.c (S_password_check_user): Update accordingly.
(S_password_check_group): Likewise.
|
|
Traditionally, /proc/mounts includes only filesystem mount points.
Previously though, the mtab translator included any kind of
translator, like all /hurd/storeio translators. This causes problems
with umount --all as this would remove the passive translator records
from nodes in /dev.
Fix this by only listing filesystem-like translators by default.
Filesystem-like translators are identified by their response to
dir_readdir messages sent to their root node.
* trans/mtab.c (all_translators): New variable.
(options): Add flag to preserve the old behavior.
(parse_opt): Handle the new flag.
(is_filesystem_translator): New function.
(mtab_populate): Skip non-filesystem translators by default.
|
|
* trans/mtab.c (main): Use ports_manage_port_operations_multithread.
|
|
* trans/mtab.c (struct mtab): Add lock.
(open_hook): Initialize lock.
(close_hook): Destroy lock.
(trivfs_S_io_read): Lock mtab object, adjust error handling accordingly.
(trivfs_S_io_seek): Likewise.
(trivfs_S_io_readable): Likewise.
|
|
Previously the mtab detector tried to detect whether it talks to
itself by comparing the control port of the translator it currently
visits with its own. This was done to prevent deadlocks. However, this
did not detect non-trivial loops, i.e. two mtab translators would
still dead-lock each other.
Now that it is safe to actually file_name_lookup the root node of a
mtab translator without triggering the generation of content, this
logic can just be omitted.
* trans/mtab.c (mtab_populate): Remove the loop detection logic.
|
|
Previously the mtab content was generated in the open hook. Delay this
until the data is needed. A follow up patch will take advantage of
this to both simplify the logic in mtab_populate and make it more
robust at the same time.
* trans/mtab.c (open_hook): Do not eagerly populate the mtab.
(trivfs_S_io_read): Populate the mtab struct on demand.
(trivfs_S_io_seek): Likewise.
(trivfs_S_io_readable): Likewise.
|
|
Previously, fakeroot would not exit if a process outlived the original
process started by settrans. This caused bugs like this:
% fakeroot-hurd /bin/sh -c 'sleep 1&' 2>&1 | tee
<hangs>
Fix this by exiting if the last client of fakeroot goes away.
If noone has a right to any control or protid port, noone can ever
reacquire any such right. So it is safe to shutdown the fakeroot
translator in that case.
* trans/fakeroot.c (fakeroot_netfs_release_protid): Shutdown the
translator if the last protid object is destroyed and no control port
is around either.
|
|
* trans/fakeroot.c (netfs_S_dir_lookup): Remove dead code.
|
|
* trans/fakeroot.c (netfs_S_dir_lookup): Remove dead code.
|
|
* trans/fakeroot.c (netfs_S_dir_lookup): Drop else.
|
|
Previously, files created in the fakeroot environment were created
with the uid and gid of the user running fakeroot:
% fakeroot-hurd /bin/sh -c 'touch /tmp/$$; stat --format=%u:%g /tmp/$$'
1000:1000
* trans/fakeroot.c (netfs_S_dir_lookup): Fix ownership of newly
created files.
|
|
When a node has faked attributes, we cannot drop our node.
Reinitialize the lock box as if the node was dropped. This fixes the
following bug:
% fakeroot-hurd /bin/sh -c 'touch /tmp/$$.lock
chown 0 /tmp/$$.lock
l(){ flock /tmp/$$.lock true; }; l; l'
<hangs>
* trans/fakeroot.c (fake_node_dropweak): Unlock the node if the last
real reference is dropped but we keep a fake one.
|
|
Previously the node was not correctly torn down if adding the newly
created netnode to the hash table failed. Fix this by rearranging the
code, doing the hash table modification first because it is easier to
undo.
* trans/fakeroot.c (new_node): Fix the error handling.
|
|
The function new_node creates virtual nodes using netfs_make_node.
Nodes created with netfs_make_node already have a reference count of
one. Currently another reference is added in new_node. This prevents
the destruction of the node causing bugs like this:
% fakeroot-hurd sh -c 'l(){ flock /tmp/$$.lock true; }; l; l'
<hangs>
* trans/fakeroot.c (new_node): Fix reference count of newly created
nodes.
|
|
* trans/fakeroot.c (netfs_S_dir_lookup): Fix locking.
|
|
Previously, fakeroot tried to do too much in netfs_node_norefs. This
function is meant to deallocate nodes. Fakeroot however also tries to
remove the node from the hash table and to prolong the lifetime of the
node object by re-referencing it.
Removing the object from the hash table is highly problematic, because
at this point we already have the node locked. With proper locking in
netfs_S_dir_lookup, acquiring the hash table lock while we hold the
node locked results in dead-locks, releasing the node lock before
acquiring the hash table lock results in a race condition.
Prolonging the lifetime of the node by re-acquiring a reference is
clearly a hack that surprisingly works to some degree. The nodes
transbox, however, is already gone at this point.
This code was never actually run because of a reference-counting bug
in fakeroot.
Fix this by installing our own clean routine in the
netfs_protid_class. This function is called without the associated
node being locked, allowing us to acquire the locks in the proper
order and to keep the hash table locked while the node is being
destroyed.
* trans/fakeroot.c (netfs_node_norefs): Just free the associated
resources.
(fakeroot_netfs_release_protid): New function doing cleanly what
netfs_node_norefs did before.
(netfs_S_dir_lookup): Reuse the fake reference.
(main): Install fakeroot_netfs_release_protid as clean routine.
fixup_fix_refc_destruction
|
|
* trans/fakeroot.c (new_node): Acquire the nodes lock before releasing
the idport_ihash_lock. Return nodes locked.
(netfs_S_dir_lookup): Drop lock.
(netfs_attempt_mkfile): Likewise.
(main): Likewise.
|
|
* trans/fakeroot.c (netfs_attempt_mkfile): Keep dir locked until the
new node is created.
|
|
* trans/fakeroot.c (netfs_S_dir_lookup): Handle invalid responses to
dir_lookup requests.
|
|
Previously any FS_RETRY_NORMAL requests were handed back to the
client. Redo the lookup ourself instead. This saves us the burden to
create a fake node for the intermediate step, hand it back to the
client and handle another request from the client.
With this change there is no need to fiddle with the permission bits
as it was previously done.
* trans/fakeroot.c (netfs_S_dir_lookup): Redo the lookup transparently
for the user if FS_RETRY_NORMAL is requested.
fixup_improve_perf
|
|
Previously a pointer to the node was stored in the hash table. This
writes the locp pointer into the node object overwriting the next
pointer there. Store the pointer to the netnode instead.
* trans/fakeroot.c (struct netnode): Add field np.
(new_node): Initialize field np.
(new_node): Store nn instead of np into the hash table.
(netfs_S_dir_lookup): Adjust accordingly.
|
|
Previously fakeroot did not explicitly proxy io_identity requests, so
the default implementation from libnetfs handled them. But as the fsys
identity port returned was always netfs_fsys_identity, this broke the
getcwd logic (assuming /media/scratch is a translator):
% cd /media/scratch/foo && fakeroot-hurd pwd
/foo
Fix this by proxying io_identity requests. Since then no-one is
handing out our netfs_fsys_identity port anymore, an optimization in
netfs_fsys_identity is made obsolete by this change.
* trans/fakeroot.c (netfs_S_dir_lookup): Adjust code accordingly.
(netfs_S_io_identity): New function.
|
|
When looking up files, fakeroot intercepts reauthentication requests
and executes io_reauthenticate and auth_user_authenticate
transparently for the client. This, however, makes the client
incorrectly assume that the lookup is finished (assuming
/media/scratch is a translator):
% cd /media/scratch && fakeroot-hurd pwd
pwd: reading directory `..': Bad file descriptor
Make the reauthentication completely transparent to the client by
re-doing the lookup ourselves.
* trans/fakeroot.c (netfs_S_dir_lookup): Fix transparent reauthentication.
|
|
Previously, fakeroot failed to create files in certain circumstances,
e. g. assuming /tmp is a tmpfs and /tmp/some_file does not exist:
% cd /tmp && fakeroot-hurd /bin/sh -c ':>/tmp/some_file'
/bin/sh: 1: cannot create /tmp/some_file: Is a directory
Fix this by sanitizing the flags value not to contain O_WRITE if we're
not at the last path component.
* trans/fakeroot.c (netfs_S_dir_lookup): Strip O_WRITE from flags when
looking up all but the last path component.
|
|
Handle multiple request types as recommended by the Mach Server
Writer's Guide section 4, subsection "Handling Multiple Request
Types". This avoids initializing the reply message in every X_server
function. The reply message has already been properly initialized in
libports, so there is no need to call mig_reply_setup.
* trans/fakeroot.c (netfs_demuxer): Improve the demuxer function.
|
|
Any messages we do not intercept are forwarded to the underlying file.
* trans/fakeroot.c (netfs_demuxer): Remove unused declaration of
function netfs_ifsock_server.
|
|
Just like it always is in libnetfs' normal netfs_S_dir_lookup.
* trans/fakeroot.c (netfs_S_dir_lookup): Call netfs_validate_stat after
calling new_node.
|
|
Rename the global variable "path" to "target_path" to make it more
unambiguous.
* trans/mtab.c: Rename global variable "path".
|