Age | Commit message (Collapse) | Author |
|
|
|
Some filesystems have buggy semantics where stat(2) will return incorrect
sizes for files for a while after some changes, sometimes, unless they've
been fsync'd. We still want to disable fsync most of the time, but enabling
it for specific programs can be useful.
Signed-off-by: Peter Seebach <peter.seebach@windriver.com>
|
|
Most pseudo operations don't actually USE the server's response. So
why wait for a response?
This patch introduces a new message type, PSEUDO_MSG_FASTOP. It
also tags pseudo operation types with whether or not they need to
give a response. This requires updates to maketables to allow non-string
types for additional columns, and the addition of some quotes to the
SQL query enums/query_type.in table.
A few routines are altered to change their behavior and whether or not
they perform a stat operation. The only operations that do wait are
OP_FSTAT and OP_STAT, OP_MKNOD, and OP_MAY_UNLINK. Rationale:
You can't query the server for replacement information and not wait for
it. Makes no sense.
There's extra checking in mknod, because we really do want to fail out
if we couldn't do that -- that implies that we haven't created a thing
that will look like a node.
The result from OP_MAY_UNLINK is checked because it's used to determine
whether we need to send a DID_UNLINK or CANCEL_UNLINK. It might be cheaper
to send two messages without waiting than to send one, wait, and maybe
send another, but I don't want to send invalid messages.
This is highly experimental.
|
|
There were a couple of cases where pseudo built against GLIBC_2.7 or
newer was ending up with dependencies on symbols which required
GLIBC_2.7. With these gone, it appears that a libpseudo.so can be
used on an older host in some cases. None were particularly important
or intentional:
1. pseudo_util was conditionally calling open() with only two arguments,
which can invoke a new __open2() function in some systems. Don't care,
and the docs specifically state that the mode argument is "ignored" when
O_CREAT is absent, so it's not necessary to omit it.
2. The calls to sscanf/fscanf in pseudo_client.c were getting translated
into a special new iso_c99 sscanf/fscanf, and we don't care because we're
not using those features; #define _GNU_SOURCE suppresses the extra-compliant
behavior.
Signed-off-by: seebs <peter.seebach@windriver.com>
|
|
The _plain thing was added because of clashes between Linux
("struct stat64 for 64-bit file sizes") and Darwin ("struct stat
is already 64 bits"). But it turns out not to be enough,
because stat will *fail* if it cannot represent a file size,
so when something like unlinkat() calls a non-64-bit stat in
order to determine whether a file exists, it gets the wrong
answer if the file is over 2GB in size.
Solution: Continue using PSEUDO_STATBUF, and also provide
defines for base_stat() which can be either real_stat() or
real_stat64(), etcetera.
This eliminates any reason to need the _plain functions. It
also suggests that the other real___fxstatat() calls should
someday go away because that is an ugly, ugly, implementation
detail.
As part of testing this, fix up some bitrot which affected
Darwin (such as the continue outside of a loop, but inside
an #ifdef; that was left over from the conversion of
init_one_wrapper to a separate function).
|
|
1. Fix *at() where dirfd is obtained through dirfd(DIR *).
The dirfd(DIR *) interface allows you to get the fd for a DIR *,
meaning you can use it with openat(), meaning you can need its
path. This causes a segfault. Also fixed the base_path
code not to segfault in that case, but first fix the
underlying problem.
2. Implement renameat()
After three long years, someone tried to use this. This was impossibly
hard back when pseudo was written, because there was only one dirfd
provided for. Thing is, now, the canonicalization happens in wrapfuncs,
so a small tweak to makewrappers to recognize that oldpath should use
olddirfd if it exists is enough to get us fully canonicalized paths
when needed.
|
|
2011-11-01:
* (mhatle) Stop valgrind from reporting use of uninitialized
memory from pseudo_client:client_ping()
Signed-off-by: Mark Hatle <mark.hatle@windriver.com>
|
|
Change from internal PSEUDO_RELOADED to external PSEUDO_UNLOAD environment
variable. Enable external programs to have a safe and reliable way to unload
pseudo on the next exec*. PSEUDO_UNLOAD also will disable pseudo if we're in a
fork/clone situation in the same way PSEUDO_DISABLED=1 would.
Rename the PSEUDO_DISABLED tests, and create a similar set for the new
PSEUDO_UNLOAD.
Signed-off-by: Mark Hatle <mark.hatle@windriver.com>
|
|
|
|
|
|
This is a spiffied-up rebase of a bunch of intermediate changes, presented
as a whole because it is, surprisingly, less confusing that way. The basic
idea is to separate the guts code into categories ranging from generic
stuff that can be the same everywhere and specific variants. The big scary
one is the Darwin support, which actually seems to run okay on 64-bit OS X
10.6. (No other variants were tested.) The other example given is support
for the old clone() syscall on RHEL 4, which affects some wrlinux use cases.
There's a few minor cleanup bits here, such as a function with inconsistent
calling conventions, but nothing really exciting.
|
|
|
|
directly rather than via an on-demand spawn from the client, the
directory is never created.
|
|
This is fussy, because we have to actually do the path search ourselves
as best we can to handle unqualified paths. The result, though, is
more meaningful logs.
Along the way, fix some bitrot in the comments in pseudo_fix_path and
friends.
|
|
It'd be handy for the WR build system if new state directories could
be created as needed. It is made so. And to answer the first
question everyone, including me, has on reading this: You can't
do system("mkdir -p ...") because the invoked shell would need to
run under pseudo, so it'd have to check for a server, and...
|
|
When pseudo is disabled, we skip a bunch of the prefix, localstate, etc
processing. This allows pseudo to run with a directory that does not yet
exist.
Signed-off-by: Mark Hatle <mark.hatle@windriver.com>
|
|
2010-12-09:
* (mhatle) Add doc/program_flow to attempt to explain startup/running
* (mhatle) guts/* minor cleanup
* (mhatle) Reorganize into a new constructor for libpseudo ONLY
pseudo main() now manually calls the util init
new / revised init for client, wrappers and utils
* (mhatle) Add central "reinit" function
* (mhatle) Add manul execv* functions
* (mhatle) rename pseudo_populate_wrappers to pseudo_check_wrappers
Signed-off-by: Mark Hatle <mark.hatle@windriver.com>
|
|
* (mhatle) Add guts/clone.c to cleanup the clone support
* (mhatle) guts/clone.c only run setupenv and reinit when NOT PSEUDO_RELOADED
* (mhatle) guts/execve.c whitespace fixe
* (mhatle) guts/fork.c similar to guts/clone.c change
* (mhatle) pseudo_client.c add reinit function
* (mhatle) pseudo_client.c revise client reset, include code from pseudo_wrappers.c
* (mhatle) pseudo_server.c move the pid writing to the parent
* (mhatle) pseudo_wrappers.c clone cleanup and populate cleanup
Signed-off-by: Mark Hatle <mark.hatle@windriver.com>
|
|
be out of sync in a very inconvenient way.
Changes include:
* Some whitespace fixes, also move the pseudo_variables definition
into pseudo_util.c since it's not used anywhere else.
* Further improvements in the fork() support:
We now recognize both positive and negative forms of PSEUDO_DISABLED,
so we can distinguish between "it was removed from the environment
by env -i" (restore the old value) and "it was intentionally turned
off" (the new value wins).
* clone(2) support. This is a little primitive, and programs might still
fail horribly due to clone's semantics, but at least it's there and
passes easy test cases.
Plus a big patch from Mark Hatle:
Cleanup fork/clone and PSEUDO_DISABLED
guts/fork.c:
* cleanup function and make it more robust
* be sure to call pseudo_setupenv prior to pseudo_client_reset
to match exec behavior
pseudo_wrappers.c:
* fix mismatched type in execl_to_v call via typecast
* Simplify fork call via single call to wrap_fork()
* be sure to save pseudo_disabled
* be sure to call pseudo_setupenv prior to pseudo_client_reset
to match exec behavior
tests:
* Add a test of whether pseudo can be disabled/enabled on a fork.
Signed-off-by: Mark Hatle <mark.hatle@windriver.com>
|
|
are generated from text files and templates, making it now (we hope)
impossible for the list of strings to get out of sync with the
enum.
|
|
|
|
bug in the speculative-unlink operation.
The intent is to mark and then confirm or cancel the delete. This
removes the quirk where we tried to stash old database entries,
which didn't handle directories anyway; "rmdir non-empty-directory"
is a bit too common a case to dismiss as unthinkable.
|
|
Fixed a couple of allocation issues, corrected an off-by-one
error in environment setup.
|
|
Add local variable cache via get_value and set_value. The local cache
is setup at constructor time (or soon after).
Rewrite the pseudo_setupenv and pseudo_dropenv routines, add a new
pseudo_setupenvp and pseudo_dropenvp as well to handle the execve
cases.
We can now successfully use /usr/bin/env -i env and get pseudo values
back!
|
|
|
|
Add PSEUDO_BINDIR, PSEUDO_LIBDIR, and PSEUDO_LOCALSTATEDIR to allow for more
easy customization of PSEUDO components at run-time. If these are not set
they will be automatically generated based on the existing PSEUDO_PREFIX path.
PSEUDO_BINDIR = PSEUDO_PREFIX /bin
PSEUDO_LIBDIR = PSEUDO_PREFIX /lib
PSEUDO_LOCALSTATEDIR = PSEUDO_PREFIX /var/pseudo
Signed-off-by: Mark Hatle <mark.hatle@windriver.com>
|
|
In fakechroot, which pseudo tries to match the functionality of,
the default behavior when creating a symlink with an absolute target
is to prepend the chroot path, so that underlying syscalls will
get the right file.
It is necessary to be able to disable this behavior to create target
filesystems in some cases. To that end, support a new environment
variable, PSEUDO_NOSYMLINKEXP, which disables that behavior.
|
|
You can't use setenv() to modify the environment that will
be passed to a child process through execve()...
Also, fix the setupenv() to use PSEUDO_SUFFIX if defined.
Use execve() to spawn child processes, so we can use setupenv()
and dropenv().
|
|
|
|
Send program name (program_invocation_name from glibc) along with the
tag.
Along the way, restructure the fds/pids/tags arrays to be an array
of client structures in pseudo_server, and add the message type
to the set of things logged -- logging that a message was a ping is
more useful than appending the text "ping" to it. Add support
for type and program to pseudolog.
Add deletion to pseudolog.
Handle usage message formatting when there's an odd number of known
specifiers for pseudolog.
Conflicts:
ChangeLog.txt
pseudo_server.c
|
|
* Add lckpwdf/ulckpwdf to guts/README
* Remove arguments from function pointer arguments.
While in theory the compar function pointer has always taken
"const struct dirent **", some systems (many) have declared
it instead as taking "const void *". For now, just omit
the types; a pointer to function taking unknown arguments
is a compatible type, and we never call the functions, we
just pass them to something else.
* Handle readlinkat() on systems without *at functions
* Fix pseudo_etc_file (spotted by "fortify")
When O_CREAT can be a flag, 0600 mode is needed. While we're
at it, remove a bogus dummy open.
* Fix mkdtemp()
Was returning the address of the internal buffer rather than the
user-provided buffer. Also fixed a typo in an error message.
* Don't call fgetgrent_r() with a null FILE *.
* A couple of other typo-type fixes.
|
|
It's not enough to rely on the usual chroot() stuff affecting the
file open, not least because these use the glibc-internal __open
which is not currently intercepted, but also because we want to
use the PSEUDO_PASSWD path when that's set but there's no chroot().
There's some extra magic in pseudo_etc_file to support these
operations, since they can legitimately create a file rather
than opening an existing one.
|
|
Migrate the stable part of the wrapper code (not machine-generated)
out of makewrappers, to make it easier to maintain.
|
|
Spotted some glibc extensions to file modes, altered fopen logic.
Fix handling for the case where the underlying pseudo_pwd_fd or
pseudo_grp_fd are closed.
|
|
This is a first pass at handling password/group calls, allowing
the use of custom password/group files. In particular, when
chroot()ed to a particular directory, pseudo picks files in
that directory by default, to improve support for the typical
use case where pseudo uses chroot() only to jump into a virtual
target filesystem.
|
|
|
|
This allows us to track execution, although the tracking for it
requires some additional thought -- the basic assumption is that we
don't want to canonicalize names into the chroot() directory, but
since all the filename canonicalization assumes that we want this,
that will take some sneaking. It's a little useful as is, though,
so I'm running with it.
|
|
This patch adds support for checking whether a file was opened for
reading, writing, or both, as well as tracking append flags. It is
not very well tested. This is preparation for improved host
contamination checking.
|
|
None of them seem to have been genuine problems, but it's prettier now,
and some were questionable.
|
|
Add chroot() and a large number of things needed to make it work.
The list of intercepted calls is large but not exhaustive.
|
|
* Improve makewrappers handling of function pointer arguments.
* Regenerate wrappers when makewrappers is touched.
* Move path resolution from pseudo_client_op into wrapper
functions.
* Eliminate dependency on PATH_MAX.
* Related cleanup, such as tracking CWD better, and using
the tracked value for getcwd().
|
|
For reasons not clear to me, early iterations of pseudo_client.c
used errno %d instead of calling strerror(). Since I already
called strerror() elsewhere in the file, calling it a few more
times isn't a problem.
|
|
|