Age | Commit message (Collapse) | Author |
|
* trans/fakeroot.c (netfs_demuxer): When forwarding an unknown request fail,
forward the error instead of crashing.
|
|
One needs to keep the port being reauthenticated alive until we are sure the
server has complete authentication.
* libfshelp/fetch-root.c (fshelp_fetch_root): Deallocate `port' after
auth_user_authenticate has completed.
* trans/fakeroot.c (netfs_S_dir_lookup): Likewise with `file'.
|
|
Various realworld tests would otherwise think they can write to /, while
they actually can't.
* trans/fakeroot.c (netfs_report_access): Call file_check_access instead of
returning O_RDWR|O_EXEC when faking mode too.
|
|
So we will always be able to re-open them.
* trans/fakeroot.c (netfs_S_dir_lookup): Call real_from_fake_mode() on modes
before calling the underlying filesystem's dir_lookup.
|
|
Otherwise some scripts may try to modify system files just because they find
they seem to be able to.
* trans/fakeroot.c (netfs_report_access): When FAKE_MODE is not set on
`np', call file_check_access on the underlying node instead of returning
O_RDWR|O_EXEC.
|
|
Fakeroot does not support faking them anyway, and they may change on the
underlying fs, e.g. when creating a local socket.
* trans/fakeroot.c (netfs_validate_stat): Return S_IFMT part of st_mode as
provided by underlying filesystem.
|
|
As well as other potential mode changes which are indeed supposed to still
work as root.
* trans/fakeroot.c (netfs_attempt_chmod): Always set S_IRUSR and S_IWUSR in
real_mode, and set S_IXUSR also when this is a directory.
|
|
Huge thanks to Svante Signell for having tracked the bug.
* trans/fakeroot.c (netfs_attempt_chmod): Make the file_chmod call
additionally include the modes from nn->openmodes.
|
|
* trans/fakeroot.c (check_openmodes): Make comment clearer about missing new
openmodes.
|
|
Thanks Svante Signell for the investigation and proposed patch.
* trans/fakeroot.c (new_node): Assert that `openmodes' includes only
O_RDWR|O_EXEC
(check_openmodes): Likewise with `newmodes'.
(netfs_S_dir_lookup): Keep only O_RDWR|O_EXEC from `flags' when calling
new_node.
|
|
* trans/fakeroot.c (netfs_set_translator): New function.
|
|
* trans/fakeroot.c (new_node): Initialize faked field to FAKE_DEFAULT.
|
|
Their faked field was not initialized.
Thanks a lot to Svante Signell for the investigation
* trans/fakeroot.c (new_node): Initialize faked field of nn to 0.
(netfs_attempt_mkfile): Call set_default_attributes on newly-allocated node,
and if the real mode is not the same as the requested mode, fake the mode.
|
|
* trans/fakeroot.c (netfs_demuxer): Make the demuxer payload-aware.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
Replies are directly sent from client to actual server.
* trans/fakeroot.c (netfs_demuxer): Return MIG_NO_REPLY, to notify server loop
that no reply should be sent.
|