Age | Commit message (Collapse) | Author |
|
Signed-off-by: Ross Burton <ross.burton@arm.com>
|
|
The xattr functions need to use a specific version of the symbols to avoid
calling into libattr.so, which on Tumbleweed causes failures[1].
However on arm64 systems the glibc version is different. This means that
searching for llistattr(GLIBC_2.3) fails to initially match the symbol in
libc.so, and instead if libattr.so is linked then the symbol in that library
is used. This is simply a wrapper that is intended to call the symbol in
libc.so but instead calls the symbol in pseudo, so infinite loops.
Using the just-added architecture overrides, add the right versions for
arm64 systems so the correct symbols in libc.so are found.
[ YOCTO #14133 ]
[1] b94fa2fc81cde25865ee223ca437d07377229a53
Signed-off-by: Ross Burton <ross.burton@arm.com>
|
|
Pseudo allows wrappers to define special comments in the wrapper lists to
pass extra arguments such as version=GLIBC_2.3 to control which symbol
version to search for. However, these arguments can be architecture-specific.
When parsing the arguments, check for flags that end in the architecture name
(as returned by platform.machine()) and use those values instead.
Signed-off-by: Ross Burton <ross.burton@arm.com>
|
|
An except statement was still using Python 2 syntax so caused
SyntaxErrors if the exception was raised.
Signed-off-by: Ross Burton <ross.burton@arm.com>
|
|
pseudo_get_value() returns newly allocated memory that the caller must free,
so add some free() calls.
Signed-off-by: Ross Burton <ross.burton@arm.com>
|
|
Pseudo has to call deprecated functions because it is wrapping them, so
disable deprecation warnings.
Signed-off-by: Ross Burton <ross.burton@arm.com>
|
|
Slightly alter a fallthrough comment so that GCC recognises it, and
add a default: case to a switch which explicitly only handles a few
values.
Signed-off-by: Ross Burton <ross.burton@arm.com>
|
|
Use strcmp() insead of memcmp() when searching for keys as otherwise
the comparison will run off the end of the NULL-terminated string.
Signed-off-by: Ross Burton <ross.burton@arm.com>
|
|
Newer versions of glibc have a lchmod function which we need to wrap.
Add this, and tweak fchmodat to be able to handle the "no symlink
resolution" case rather than duplicate code.
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
|
|
This also plugs a memory leak by making sure env is freed.
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
|
|
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
|
|
The logfile path should be more visible so it's easier investigate the error.
Signed-off-by: Tomasz Dziendzielski <tomasz.dziendzielski@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
|
|
Similar to mkstemp64 when oflags=0, therefore move the wrapper and call
from mkstemp64. Note that some glibc versions would have one but not the other
so ensure fall back to the real function is correct on those versions.
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
|
|
There is magic in the posts where specific variable names have specific
magic. For that magic to work, "path" needs to be used not "pathname" as
is currently there. Fix this, which fixes path issues on systems using
statx (Ubuntu 20.04 in particular).
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
|
|
We're seeing systems in the wild (e.g. ubuntu 20.04) which call
with a dirfd set to the full filename and path set to "". Since
this seems to be expected to work, handle it accordingly.
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
|
|
Some operations may call unlink() on an open fd, then call fchown/fchmod/fstat
on that fd. This would currently readd its entry to the database, which
is necessary to preserve its permissions information however since that
file will be lost when it is closed, we don't want the DB entry to persist.
Marking it as may_unlink means the code will know its likely been deleted
and ignore the entry later, giving improved behaviour that simple path
mismatch warnings. We can use an nlink of zero to detect this.
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
|
|
In the xattr handling functions, if result is NULL, which it can be
with the path ignore code, there is a NULL pointer dereference and
segfault. Everywhere else checks result first, this appears to just
be an omission.
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
|
|
Consider what happens if a program does:
fd = fopen("A")
link("A", "B")
unlink("A")
fchown(fd)
Assuming we can't use the database, in order to handle this correctly,
we need to change the open fd to point at B when A us unlinked.
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
|
|
Rather than mapping mismatched inode entries to paths, thrown an abort()
instead. Add a new result type to allow the server to pass back
this instruction to the client.
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
|
|
Currently, pseudo considers any path accessed whist its running to be
a valid entry to track in its database. The way OpenEmbedded uses pseudo,
there are paths we care about accesses to from a pseudo perspective and paths
which we simply don't care about.
This patch adds a PSEUDO_IGNORE_PATHS environment variable which is a comma
separated list of path prefixes to ignore accesses to.
To do this, we add some functions which can check a path argument or a file
descriptor argument and use these in the pseudo wrappers where path or fd
arguments are present. Where paths are being ignored, we skip straight to
the underlying real function.
Psuedo needs to keep track of the open fd mappings to files so we still need
to allow those cases into the pseudo_op function. Specficially this means
OP_CLOSE, OP_OPEN, OP_DUP and OP_CHDIR.
Apart from OP_OPEN which could call the server, the other operations are client
side only so passed through. We 'tag' the functions using these operations so
that the path ignore code isn't triggered. For OP_OPEN we exit early and skip
the server op. We also have a catch all in client_op to ensure any operatings
we didn't manage to skip early still get skipped correctly.
OP_CHROOT is a special case. Where ignored path prefixes are used as a chroot,
for the lifetime of the chroot, the path is effectively dropped from the
PSEUDO_IGNORE_PATHS list. Whilst slightly counter intuaitive, this turned out
to be the most effective way to do things due to commands like useradd and
their use of chroots.
For sqlite3 and appropriate path filtering in OE, this took the database from
45,000 entries to about 180. For dbus this was 88,000 down to 760. Given the
number of client to server trips these numbers of paths involves, the win
is seemingly worthwhile.
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
|
|
When we see cases where the inode no longer matches the file path, pseudo
notices but currently reuses the database entry. This can happen where for
example, a file is deleted and a new file created outside of pseudo where
the inode number is reused.
Change this to ignore the likely stale database entry instead. We're
seeing bugs where inode reuse for deleted files causes permission corruption.
(See bug #14057 for example). We don't want to delete the database entry
as the permissions may need to be applied to that file (and testing shows
we do need the path matching code which handles that).
I appreciate this should never happen under the original design of pseudo
where all file accesses are monitored by pseudo. The reality is to do that,
we'd have to run pseudo:
a) for all tasks
b) as one pseudo database for all of TMPDIR
Neither of these is realistically possible for performance reasons.
I believe pseudo to be much better at catching all accesses than it
might once have been. As such, these "fixups" are in the cases I've
seen in the logs, always incorrect.
It therefore makes more sense to ignore the database data rather than
corrupt the file permissions or worse. Looking at the pseudo logs
in my heavily reused build directories, the number of these
errors is staggering. This issue would explain many weird bugs we've
seen over the years.
There is a risk that we could not map permissions in some case where
we currently would. I have not seen evidence of this in any logs I've
read though. This change, whilst going against the original design,
is in my view the safer option for the project at this point given we
don't use pseudo as originally designed and never will be able to.
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
|
|
The pseudo rename guts test for an item being renamed to
itself, only after information about it has been deleted.
We move the test to before we play with the database.
Note that pseudo does not support renameat2().
Signed-off-by: Joe Slater <joe.slater@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
|
|
If the in-memory database is not being used, enable WAL mode on the
database to ensure that the database is resilient to pseudo shutting
down unexpectedly (or being terminated by the OS). This allows projects
to make the reliability vs. performance tradeoff: If they want
performance they can use the in-memory database; if they want resilience
they can disable the in-memory database and WAL will prevent database
corruption.
Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
|
|
Linux 3.15 and newer introduced new open file description locks.
Currently pseudo prints a warning if fcntl is used with OFD locks:
unknown fcntl argument 37, assuming long argument.
However, calls to fcntl with a OFC lock set need a struct flock
pointer. Treat F_OFD_GETLK (and friends) like F_GETLK (and friends).
This issue has been observed with ostree. Comparing strace output
between two runs with/without this patch shows the same fcntl calls,
hence it seems not to matter in practice.
Signed-off-by: Stefan Agner <stefan@agner.ch>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
|
|
Signed-off-by: Johannes Beisswenger <johannes.beisswenger@cetitec.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
|
|
The file mode was accidentally overwritten with only the permission
bits, causing the server to falsely assume that the database was
corrupted (because the msg_header.mode did not contain S_IFDIR
anymore) even though it was the client doing the corruption.
In practice that had the effect of leaking the UID of the user, into
the pseudo environment.
This fixes Bug 13959 -- https://bugzilla.yoctoproject.org/show_bug.cgi?id=13959
Signed-off-by: Johannes Beisswenger <johannes.beisswenger@cetitec.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
|
|
pseudo: ENOSYS for 'fsetxattr'.
which was being caused by dlsym() for that function returning NULL. This
appears to be due to it finding an unresolved symbol in libacl for this
symbol in libattr. It hasn't been resolved so its NULL. dlerror() returns
nothing since this is a valid symbol entry, its just not the one we want.
We can add the glibc version string for the symbol we actually want so we get
that version rather than the libattr/libacl one.
To quote libattr:
"""
These dumb wrappers are for backwards compatibility only.
Actual syscall wrappers are long gone to libc.
"""
and they are simply wrappers around the libc version so our attaching
to the libc versions should intercept any accesses via these too.
RP 2020/06/22
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org
Upstream-Status: Pending [discussed with seebs on irc and appears the correct fix]
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
|
|
'pseudo_access_t' is a type, so use typedef.
Fixes building pseudo with gcc 10 where -fno-common is the default.
Signed-off-by: Jacob Kroon <jacob.kroon@gmail.com>
Upstream-Status: Submitted [https://lists.openembedded.org/g/openembedded-core/message/137758]
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
|
|
If the user decides to fix a database, remove the files that do not
exist anymore.
If only DB test is selected do not change the behaviour (return error).
Signed-off-by: Ricardo Ribalda <ricardo@ribalda.com>
Upstream-Status: Submitted [https://lists.openembedded.org/g/openembedded-core/message/137045]
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
|
|
seccomp. Therefore intercept the seccomp syscall and alter it, pretending that
seccomp was setup when in fact we do nothing. If we error as unsupported,
utilities like file will exit with errors so we can't just disable it.
Also, it fails to compile pseudo-native on centos 7:
| ports/linux/pseudo_wrappers.c: In function ‘prctl’:
| ports/linux/pseudo_wrappers.c:129:14: error: ‘SECCOMP_SET_MODE_FILTER’ undeclared (first use in this function)
| if (cmd == SECCOMP_SET_MODE_FILTER) {
| ^
Add macro guard for seccomp to avoid the failure.
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
|
|
Latest versions of attr have removed the xattr.h header,
with the rationale that libc is providing the same wrappers.
attr/attributes.h is providing the ENOATTR definition.
Upstream-Status: Pending
Signed-off-by: Alexander Kanavin <alex.kanavin@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
|
|
Linux system's realpath() remove trailing slashes, but pseudo's doesn't, need
make them identical.
E.g., the following code (rel.c) prints '/tmp' with system's realpath, but
pseudo's realpath prints '/tmp/':
#include <stdio.h>
#include <limits.h>
#include <stdlib.h>
int main() {
char out[PATH_MAX];
printf("%s\n", realpath("/tmp/", out));
return 0;
}
$ bitbake base-passwd -cdevshell # For pseudo env
$ gcc rel.c
$ ./a.out
/tmp/ (but should be /tmp)
This patch fixes the problem.
Upstream-Status: Submitted [https://lists.yoctoproject.org/g/poky/message/11879]
Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
|
|
Modern distros (e.g. fedora30) are starting to use the new statx() syscall through
the newly exposed glibc wrapper function in software like coreutils (e.g. the ls
command). Add support to intercept this to pseudo.
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Upstream-Status: Submitted [Emailed to seebs]
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
|
|
Changelog indicates they should be compatible.
Upstream-Status: Pending
Signed-off-by: Alexander Kanavin <alex.kanavin@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
|
|
Currently if we max out the maximum number of files, pseudo can deadlock, unable to
accept new connections yet unable to move forward and unblock the other processes
waiting either.
Rather than hang, when this happens, close out inactive connections, allowing us
to accept the new ones. The disconnected clients will simply reconnect. There is
a small risk of data loss here sadly but its better than hanging.
RP
2017/4/25
Upstream-Status: Submitted [Peter is aware of the issue]
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
|
|
server shutdowns.
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
|
|
When statting a file that we may or may not be opening with O_NOFOLLOW,
we should use lstat (or AT_SYMLINK_NOFOLLOW) to try to get information
about the right file.
Also when we want to check whether a bit is set, we should use & rather
than |. I am an experienced programmer and know the difference between
those.
|
|
Did you know that, similar to AT_SYMLINK_NOFOLLOW, there's
an O_NOFOLLOW available in flags for open/openat?
I didn't.
|
|
This adds SPDX license headers to all source files in pseudo so license
identification models current best practise.
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
|
|
Clean up the "unused parameter" warnings in renameat2.
|
|
This is a heck of a special case: If you call open on a FIFO/pipe,
and you didn't have O_NONBLOCK, and you used O_RDONLY or O_WRONLY,
but not O_RDWR, the open can block forever. Unfortunately, pseudo
assumes syscalls complete. We attempt to drop the lock and restore
our state, then recover it later.
Why? Because the .NET runtime does this for a debug hook.
|
|
So renameat2 now has a glibc wrapper in some recent glibc, which
means that mv can use it, and thus bypass all our clever testing,
and since we can't intercept the actual syscall (gnulib's implementation
apparently doesn't hit the glibc syscall() wrapper?), this results
in files being moved without pseudo knowing about them.
Implementing the semantics properly is Very Hard, but possibly we
can just fail politely for now.
We'll be back to this later.
|
|
We've had really weird sporadic things, but it looks like the
underlying problem is that something's getting symlinked over
(which is clearly impossible), but we're nuking everything with
that inode, rather than just the entry for that path, and this
is causing us to drop ownership info for an existing thing.
|
|
Since msg->pathlen is set to len in the first branch, we can share the
final submit-and-check-for-success part of the two branches.
Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
Signed-off-by: Seebs <seebs@seebs.net>
|
|
MSG_NOSIGNAL has been in Linux since 2.2, and has been standardized in
POSIX 2008. Using that when available avoids the overhead of the two
syscalls to set and restore the SIGPIPE handler. Moreover, we can
eliminate one write() call by making use of sendmsg() to do
scatter-gather I/O.
Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
Signed-off-by: Seebs <seebs@seebs.net>
|
|
Turns out you need <stdint.h> for int64_t and friends and
some systems were picking it up implicitly and others weren't.
|
|
bind_int doesn't handle 64-bit ints on most targets, we need
bind_int64, and weren't using it. What a silly bug. Caught
and fixed by <Jack.Fewx@dell.com>.
Signed-off-by: seebs <seebs@seebs.net>
|
|
|
|
So ino_t is uint64_t, sqlite field types are magical and erratic and
if a value doesn't fit inside signed int64, it gets converted to
float64. of course. This means that the top half of the inode range
produces invalid-ish values, because a 64-bit double is typically
53 bits of mantissa, so a value around 2^64 will convert to a float64
value which is going to compare equal to at least 2^10 other integer
values if they were also converted to float64. Which makes weird
problems.
|
|
openat() was passing its flags unaltered to pseudo_root_path(), which
assumes that a flags argument other than 0 means "don't follow symlinks
in last path component". This is completely wrong, and I have no idea
how it survived this long unnoticed.
Now, if a plain flags variable is set and not overruled by a
comment like /* flags=... */, it's masked with AT_SYMLINK_NOFOLLOW,
as there are other values fstatat() and friends can take, and the
openat() flags are just overridden with 0. (The only meaningful case
would be O_NOFOLLOW, but O_NOFOLLOW instructs us to *fail* in the
open if the path is a symlink, so we don't care.)
Signed-off-by: Seebs <seebs@seebs.net>
|