summaryrefslogtreecommitdiff
path: root/trans/fakeroot.c
AgeCommit message (Collapse)Author
2016-03-21netfs: Remove global reference count lock.Flavio Cruz
* libnetfs/drop-node.c: Remove use of netfs_node_refcnt_lock. * libnetfs/init-init.c: Remove netfs_node_refcnt_lock. * libnetfs/make-node.c: Initialize refcounts in refcounts_init. * libnetfs/netfs.h: Use refcounts_t for tracking node references. Remove netfs_node_refcnt_lock. Add netfs_nref_light, netfs_nrele_light and handler netfs_try_dropping_softrefs. Adjust comments. * libnetfs/nput.c: Use refcounts_t. Call netfs_try_dropping_softrefs to remove any soft reference that the translator might have acquired during the lifetime of the node. Implement empty netfs_try_dropping_softrefs. * libnetfs/nref.c: Implement netfs_nref_light. * libnetfs/nrele.c: Use refcounts_t and netfs_try_dropping_softrefs. Implement netfs_nrele_light. * ftpfs/dir.c: Use netfs_nref without locking the old netfs_node_refcnt_lock. * ftpfs/node.c: Likewise. * usermux/mux.c: Use netfs_nref to increase hard references of the node. * hostmux/mux.c: Use netfs_nref to increase hard references of the node. * trans/fakeroot.c (new_node): Use a light reference when storing a node in the hash table. * trans/fakeroot.c (netfs_try_dropping_softrefs): Implement netfs_try_dropping_softrefs to remove the node from the hash table. * trans/fakeroot.c (netfs_node_norefs): Remove code to remove the node from the hash table. * trans/fakeroot.c (netfs_S_dir_lookup): Simplify lookup code since we don't need to lock netfs_node_refcnt_lock anymore. * procfs/netfs.c: Remove use of netfs_node_refcnt_lock. * nfs/cache.c: Add mutex to handle exclusive access to nodehash. This replaces the use of netfs_node_refcnt_lock. * nfs/cache.c (lookup_handle): Use nodehash_ihash_lock when accessing nodehash. Use netfs_nref_light to add one soft reference to the node just added to nodehash. * nfs/cache.c (netfs_node_norefs): Use netfs_nref. Don't use netfs_node_refcnt_lock and don't remove the node from nodehash here. * nfs/cache.c (netfs_try_dropping_softrefs): Drop the light reference when the node has no more hard references. * nfs/cache.c (recache_handle): Use nodehash_ihash_lock instead. * nfs/ops.c (netds_attempt_unlink): Use refcounts_references. * console/console.c (netfs_node_norefs): Use a soft reference to store a node in dir_node, cons_node, disp_node, inp_node. * console/console.c (netfs_try_dropping_softrefs): When dropping all soft references remove node pointer from the fields above.
2016-02-15Make fakeroot forward send errors instead of crashingSamuel Thibault
* trans/fakeroot.c (netfs_demuxer): When forwarding an unknown request fail, forward the error instead of crashing.
2016-02-14Fix hang on reauthenticationSamuel Thibault
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'.
2015-10-20Make fakerooted access() return real accessSvante Signell
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.
2015-10-12Make dir_lookup create files with user permissions enabledSamuel Thibault
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.
2015-08-14Fake full file access only for faked nodesSamuel Thibault
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.
2015-08-14Make fakeroot return file types from underly fsSamuel Thibault
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.
2015-06-17Cope with scripts which chmod -x directoriesSvante Signell
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.
2015-05-23fakeroot: Fix reopening files after a chmodSamuel Thibault
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.
2015-05-23Make comment clearerSamuel Thibault
* trans/fakeroot.c (check_openmodes): Make comment clearer about missing new openmodes.
2015-05-23Make sure to record only RWX open modesSamuel Thibault
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.
2015-05-14Fix creating named sockets inside fakeroot-hurdSvante Signell
* trans/fakeroot.c (netfs_set_translator): New function.
2014-12-10fakeroot: Fix initializing default faked field of nodesSamuel Thibault
* trans/fakeroot.c (new_node): Initialize faked field to FAKE_DEFAULT.
2014-12-09Fix mode of nodes created with mkfileSamuel Thibault
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.
2014-12-07trans/fakeroot: make the demuxer payload-awareJustus Winter
* trans/fakeroot.c (netfs_demuxer): Make the demuxer payload-aware.
2014-06-18trans/fakeroot: fix error handlingJustus Winter
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.
2014-05-28trans/fakeroot: use netfs_node_netnode instead of np->nnJustus Winter
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.
2014-05-28trans/fakeroot: use fat nodes to simplify the node cacheJustus Winter
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.
2014-05-22trans/fakeroot: override fshelp_isownerJustus Winter
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.
2014-05-16trans/fakeroot: use C99-style struct initializationJustus Winter
* trans/fakeroot.c (main): Use C99-style struct initialization to initialize argp. This avoids a warning about missing field initializers.
2014-05-16trans/fakeroot: fix comparison between signed and unsignedJustus Winter
* trans/fakeroot.c (netfs_attempt_chown): Fix comparison between signed and unsigned integer expressions.
2014-05-16trans/fakeroot: remove spurious semicolonJustus Winter
A spurious semicolon caused a control flow bug in check_openmodes, leading to a port leak. * trans/fakeroot.c (check_openmodes): Remove spurious semicolon.
2014-04-15Include the MIG-generated server header filesJustus Winter
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.
2014-02-07trans/fakeroot: fix cached node retrieval on lookupRichard Braun
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.
2014-02-06trans/fakeroot: fix netfs_S_dir_lookupRichard Braun
* trans/fakeroot.c (netfs_S_dir_lookup): Fix node dereference.
2014-02-05trans/fakeroot: rework node cachingRichard Braun
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.
2014-02-05trans/fakeroot: fix chmodRichard Braun
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.
2014-02-05Revert "trans: fix locking issue in fakeroot"Richard Braun
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.
2014-02-05trans/fakeroot: fix right leakRichard Braun
* trans/fakeroot.c (netfs_S_dir_lookup): Deallocate rights to intermediate file systems.
2013-12-19trans/fakeroot: shutdown the translator if the last client is goneJustus Winter
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.
2013-12-10trans/fakeroot: remove dead codeJustus Winter
* trans/fakeroot.c (netfs_S_dir_lookup): Remove dead code.
2013-12-10trans/fakeroot: remove dead codeJustus Winter
* trans/fakeroot.c (netfs_S_dir_lookup): Remove dead code.
2013-12-10trans/fakeroot: drop elseJustus Winter
* trans/fakeroot.c (netfs_S_dir_lookup): Drop else.
2013-12-10trans/fakeroot: fix ownership of newly created filesJustus Winter
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.
2013-12-09trans: unlock nodes with faked attributes in fakerootJustus Winter
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.
2013-12-09trans: improve the error handling in fakeauthJustus Winter
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.
2013-12-09trans: fix reference counting bug in fakerootJustus Winter
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.
2013-12-09trans: fix locking in fakeroot's netfs_S_dir_lookupJustus Winter
* trans/fakeroot.c (netfs_S_dir_lookup): Fix locking.
2013-12-09trans: fix reference counting and destruction of fake nodesJustus Winter
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
2013-12-09trans: return nodes locked when creating fake nodes in fakerootJustus Winter
* 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.
2013-12-09trans: fix locking issue in fakerootJustus Winter
* trans/fakeroot.c (netfs_attempt_mkfile): Keep dir locked until the new node is created.
2013-12-09trans: handle invalid responses to dir_lookup requests in fakerootJustus Winter
* trans/fakeroot.c (netfs_S_dir_lookup): Handle invalid responses to dir_lookup requests.
2013-12-09trans: improve the performance of dir_lookup in fakerootJustus Winter
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
2013-12-09trans: fix the use of the hash table in fakeroot.cJustus Winter
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.
2013-12-04trans: make the fakeroot environment more transparentJustus Winter
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.
2013-12-04trans: fix transparent reauthentication in fakerootJustus Winter
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.
2013-12-04trans: fix the creation of files in fakerootJustus Winter
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.
2013-12-04trans: improve the netfs_demuxer function in fakeroot.cJustus Winter
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.
2013-12-04trans: remove unused declaration from fakeroot.cJustus Winter
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.
2013-11-19Make sure created netfs nodes have stat validatedSamuel Thibault
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.