AgeCommit message (Collapse)AuthorFilesLines
2019-08-02use *correct* flags for open/openat, also apply them for related statHEADross/mastermasterSeebs3-12/+30
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.
2019-08-01handle O_NOFOLLOW in flags for open/openatSeebs2-6/+9
Did you know that, similar to AT_SYMLINK_NOFOLLOW, there's an O_NOFOLLOW available in flags for open/openat? I didn't.
2019-05-15Add SPDX-License-Identifier: LGPL-2.1-only to filesRichard Purdie260-343/+542
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>
2019-04-10fix warnings in renameat2Seebs2-0/+6
Clean up the "unused parameter" warnings in renameat2.
2019-04-10Try to handle blocking open.Seebs2-0/+41
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.
2019-04-09don't renameat2 pleaseSeebs3-0/+23
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.
2019-04-09partial fix (??) for an ownership corruption problemSeebs2-4/+7
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.
2018-12-15pseudo_ipc.c: eliminate some code duplicationSeebs2-11/+9
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>
2018-12-15Use MSG_NOSIGNAL if available.Seebs2-13/+53
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>
2018-11-29add missing <stdint.h>Seebs2-0/+6
Turns out you need <stdint.h> for int64_t and friends and some systems were picking it up implicitly and others weren't.
2018-09-20also make sure inodes are 64-bit values to SQLSeebs2-9/+12
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>
2018-09-20fix gcc7 warningSeebs2-0/+2
2018-09-20attempt to handle large inode valuesSeebs2-24/+52
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.
2018-04-13Fix symlink following errorsSeebs3-3/+4
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>
2018-04-13Fix one more stray slashSeebs2-1/+3
After the rest of the restandardization on "path does not have to be slash-terminated", I missed the case where you get an absolute symlink, which could result in a path starting with an extra slash. Signed-off-by: Seebs <seebs@seebs.net>
2018-04-13Less chatty debuggingSeebs3-2/+14
Stop producing the path mismatch messages for things with multiple links. We could probably make this smarter, but for now this is sufficient to reduce the spam. pseudo_debug(0, ...) now produces a message, as a special case. Signed-off-by: Seebs <seebs@seebs.net>
2018-04-03Change copyright default.Seebs2-1/+9
Too lazy to go back and change it, so Wind River can keep the copyright on my shiny new completely-unused syscall internals, but I'm fixing the default copyright message for new wrappers. Signed-off-by: Seebs <seebs@seebs.net>
2018-03-31initialize wrappers in syscall wrapperSeebs2-9/+12
But what if syscall(2) was the *first* function with a wrapper that you called? Also reduced amount of argument-copying in syscall(2), on further study, anything with off_t arguments has less than 6 arguments by enough to keep the total argument count down. Signed-off-by: Seebs <seebs@seebs.net>
2018-03-31don't change errno in pseudo_fix_pathSeebs2-2/+19
Two issues: (1) pseudo_fix_path could call lstat("") which generated ENOENT, (2) some people, and I'm totally not staring intently at cross-localedef here, don't know that it is in general *not* valid to check errno unless an operation has failed, and the mere fact that something set errno does not mean that the error indicated actually occurred or has any relevance to you. Nonetheless, pseudo_fix_path now saves and restores errno, and cross-localedef can just go ahead and check it as though it were guaranteed not to sometimes get set even though no error occurred. Signed-off-by: Seebs <seebs@seebs.net>
2018-03-30Fix sticky bits and a couple of test cases.Seebs3-0/+25
Merge fixes from Richard Tollerton and associated test cases and permissions fixes. Signed-off-by: Seebs <seebs@seebs.net>
2018-03-30Recently (2015) coreutils cp -Rp changed its behavior such that chmod()Seebs1-0/+19
is followed by setxattr(); previously it was the other way around. This broke pseudo when a copied directory has one of the special bits (setuid, setgid, sticky) set; the special bit wound up getting removed. Root cause is that ACLs never included special bits in the first place, so we need to merge them back in ourselves. [YOCTO #12379] Signed-off-by: Richard Tollerton <rich.tollerton@ni.com>
2018-03-30Update README and ChangeLog.Seebs2-0/+12
Signed-off-by: Seebs <seebs@seebs.net>
2018-03-30rework path computationsSeebs2-84/+90
The path logic had gotten gradually more baroque, originally from the need to handle trailing slashes in paths (because we need "*/" to be a glob that matches only directories), then from the need not to handle "regularfile/." and the like. The revised solution is to move the invariant from "partial path always ends with slash" to "appending always adds a slash". Because this implies wanting to know the type of the current partial path, and we also check the type of the new path whenever we append an element, we now have a shared stat buf for those. (With some manual tweaking, such as an empty path is implicitly root and thus a directory, and anything in which we want to expand a symlink is a directory.) Signed-off-by: Seebs <seebs@seebs.net>
2018-03-30refix path againSeebs1-7/+9
wasn't gracefully handling the empty-path case, such as the initial slash at the beginning of a path. this is just a staging point, i need to reeimplement these cleanly. Signed-off-by: Seebs <seebs@seebs.net>
2018-03-30don't add quite so many slashesSeebs1-10/+28
pseudo_append_elements was unconditionally adding a slash after each element. this means that if it gets called more than once, as when processing symlinks, you end up with trailing slashes. change it to add infix slashes. This code probably wants a rethink. Signed-off-by: Seebs <seebs@seebs.net>
2018-03-29Experimental syscall(2) wrapper.Seebs5-0/+65
This wrapper should allow us to reject renameat2 attempts by coreutils, letting us regain functionality on FC27 and related systems. This is not safe/portable/etc even by pseudo's standards, and arguably it should be a separate and optional port. [Amended commit: Don't include the dodgy renameat2 wrapper which it turns out we'd never hit anyway.] Signed-off-by: Seebs <seebs@seebs.net>
2018-03-06Improve path handling by not dereferencing filesSeebs2-40/+72
The path handling was stripping /., or moving back up a level for /.., even when the current thing was a plain file, resulting in the surprising behavior that "a/." was a valid name for a file called a, which canonicalized without the extra directory. This breaks some stuff occasionally. (Related to, but not the same as, the previous issues with the use of trailing slashes in names to match only directories.) This is not yet well-tested. Signed-off-by: Seebs <seebs@seebs.net>
2018-03-01Don't delete things and not create them.Seebs2-2/+11
When OP_CREAT comes in, if there's an existing entry with the same inode, we nuke that entry because CREAT implies a new file got that inode, and if there's an existing entry with the same path, we don't create a link, because there's already something there. So if there's a single entry with the same path and inode, it gets deleted and not recreated. Oops. Now distinguishing between a single exact match of both path and inode, and distinct matches by path and by inode. This addresses a use case where parallel creations could in theory cause pseudo to mistakenly drop database entries, potentially. (I could only trigger it by doing this to files which had existing entries, and then deleting the files outside of pseudo, though.) Signed-off-by: seebs <seebs@seebs.net>
2018-02-26Handle more mk*stemp* functions.Seebs6-35/+93
The mkostemps() family are all bad but people use them so here we are. Since mkstemp(), mkstemps(), and mkostemp() can all be implemented by calling mkostemps() with additional zeroes passed in, do it that way. Signed-off-by: Seebs <seebs@seebs.net>
2018-02-19Epoll: use the correct clientSeebs2-5/+9
So in the non-listen-fd case, apparently I broke the code to use the index of the returned event, rather than the corresponding ID value registered with epoll, as the index into the clients array. This, of course, was nonsense, and explains why we were seeing a ton of attempts to modify client 0. This also reverts the previous, incorrect, attempt to address all those messages. Signed-off-by: seebs <seebs@seebs.net>
2018-02-16Allow closing client 0Seebs2-1/+4
It seems like the epoll setup can in some cases end up with a client #0, which the code would refuse to close, so it just looped forever. Only reject negative numbers, not zero. Signed-off-by: seebs <seebs@seebs.net>
2018-02-15Handle O_TMPFILE more betterSeebs2-2/+7
O_TMPFILE is, on at least one system, (__O_TMPFILE | O_DIRECTORY), so (flags & O_TMPFILE) can be non-zero even when O_TMPFILE was not set. Signed-off-by: Seebs <seebs@seebs.net>
2018-01-20Fix openat flag #ifdef typopseudo-1.9.0PSEUDO_1_9_0Seebs3-2/+6
Whoops, missed this one. Reported/submitted by <joshua.g.lock@linux.intel.com>. Signed-off-by: Seebs <seebs@seebs.net>
2018-01-16Half-undo FASTOPSeebs3-55/+63
FASTOP is logically fine as long as there's no errors, but if there could be errors, we lose error detection. Responding instantly with a trivial ACK for FASTOP messages slightly reduces performance but improves reliability and seems to work better. Signed-off-by: Seebs <seebs@seebs.net>
2018-01-16Add statvfs wrapperSeebs5-1/+36
Patch was submitted by <dan.dedrick@gmail.com>, revised to make it a subport in case someone cares about a Linux system which doesn't have this function. (Which is probably unlikely, but I am a cautious sort.) Signed-off-by: Seebs <seebs@seebs.net>
2018-01-16Merge epoll supportSeebs5-27/+240
Original commit message: The idea came up here: https://bugzilla.yoctoproject.org/show_bug.cgi?id=11309 and here: http://lists.openembedded.org/pipermail/openembedded-core/2017-August/141491.html Signed-off-by: Alexander Kanavin <alexander.kanavin@linux.intel.com> I've adapted this to make epoll a configure-time option; you must use --enable-epoll to get the new behavior. I've also confirmed that it builds both ways and appears to run, and restored the SIGUSR2 functionality (except for the state check) for the epoll case. Signed-off-by: Seebs <seebs@seebs.net>
2018-01-16Drop diagnostic for missing "real" functionsSeebs2-16/+6
It turns out that these diagnostics can be spurious now on some hosts, also that they've probably been wrong forever; for instance, on some Linux, there's not a real "mknod" function and probably never was, so reporting this error is pointless. Signed-off-by: Seebs <seebs@seebs.net>
2018-01-16Handle long lines in /etc/groupSeebs6-39/+148
This allows the pseudo /etc/group to contain extremely long lines, e.g. when a group has a lot of members. Without this, chown and chgrp fail for group names that occur after such long lines. Signed-off-by: Zoltán Böszörményi <zboszor@pr.hu> Signed-off-by: Seebs <seebs@seebs.net> --- ports/darwin/guts/getgrouplist.c | 54 +++++++++++++++++++++++++++----------- ports/linux/guts/getgrouplist.c | 54 +++++++++++++++++++++++++++----------- ports/uids_generic/guts/getgrent.c | 26 +++++++++++++++--- ports/uids_generic/guts/getgrgid.c | 26 +++++++++++++++--- ports/uids_generic/guts/getgrnam.c | 25 +++++++++++++++--- 5 files changed, 146 insertions(+), 39 deletions(-)
2018-01-16handle O_TMPFILE and linkat()Seebs3-48/+129
This is a rework which replaces a previous patch. In this version, files created with O_TMPFILE don't get recorded in the database at all, but if we get a link request for /proc/self/fd/N, and the corresponding file is not in the database, we send a CREAT request for it instead of a LINK, and that appears to work with a MUCH reduced chance of database leakage. Also the O_TMPFILE won't be creating bogus database entries anymore. Signed-off-by: Seebs <seebs@seebs.net> linkat fix
2017-12-18Print list of clients on SIGUSR2Seebs2-0/+36
This patch relates to some debugging of handling of large numbers of clients, but actually it seems useful to have, so checking it in. Signed-off-by: Seebs <seebs@seebs.net>
2017-04-13Prevent bash from segfaulting when unloading pseudoSeebs2-1/+6
bash's extremely fancy internal awareness of how the environment looks means that, if you directly call the underlying libc "unsetenv" on a variable, bash can end up trying to access a null pointer. Fixing this generically is actually rather hard; you can't really avoid writing to environ on fork() or popen(), even if you change all execv*() functions to use the execv*e() variants. So for now, instead of unsetting the variable, set it to an empty string. Thanks to Saur in IRC for spotting this and helping debug it. Signed-off-by: Seebs <seebs@seebs.net>
2017-02-24Don't try to record 0-length posix_acl_default xattrsSeebs2-3/+36
Based on a submission from Anton Gerasimov <anton@advancedtelematic.com> On some systems, with some kernel configs, "cp -a" apparently tries to set an empty ACL list, with a valid header but no contents, which causes strange and mysterious behavior later if we actually create such an entry. So filter that out, also sanity-check a couple of other things. Signed-off-by: Seebs <seebs@seebs.net>
2017-02-03Makefile.in: Stop rebuilding binaries so much.Seebs2-6/+9
Currently, the Makefile rebuilds the binary at every invokation of the command make: $ make cc -pipe -std=gnu99 -Wall -W -Wextra -fPIC -D_LARGEFILE64_SOURCE -D_ATFILE_SOURCE -m64 -DPSEUDO_PREFIX='"/opt"' -DPSEUDO_SUFFIX='""' -DPSEUDO_BINDIR='"bin"' -DPSEUDO_LIBDIR='"lib64"' -DPSEUDO_LOCALSTATEDIR='"var/pseudo"' -DPSEUDO_VERSION='"1.8.1"' -DUSE_MEMORY_DB -DPSEUDO_PASSWD_FALLBACK='""' -DPSEUDO_XATTR_SUPPORT -O2 -g -o bin/pseudo \ pseudo.o pseudo_server.o pseudo_client.o pseudo_ipc.o \ pseudo_db.o pseudo_tables.o pseudo_util.o -lsqlite3 -lpthread -ldl -lpthread cc -pipe -std=gnu99 -Wall -W -Wextra -fPIC -D_LARGEFILE64_SOURCE -D_ATFILE_SOURCE -m64 -DPSEUDO_PREFIX='"/opt"' -DPSEUDO_SUFFIX='""' -DPSEUDO_BINDIR='"bin"' -DPSEUDO_LIBDIR='"lib64"' -DPSEUDO_LOCALSTATEDIR='"var/pseudo"' -DPSEUDO_VERSION='"1.8.1"' -DUSE_MEMORY_DB -DPSEUDO_PASSWD_FALLBACK='""' -DPSEUDO_XATTR_SUPPORT -O2 -g -o bin/pseudodb pseudodb.o \ pseudo_db.o pseudo_tables.o pseudo_util.o pseudo_ipc.o -lsqlite3 -lpthread -ldl -lpthread The fault comes from the $(BIN) directory prerequesite. According to the documention of GNU make(*), directory prerequesites normally go to <order-only-prerequisites>: targets: normal-prerequisites | order-only-prerequisites > Consider an example where your targets are to be placed in a separate > directory, and that directory might not exist before make is run. In > this situation, you want the directory to be created before any > targets are placed into it but, because the timestamps on directories > change whenever a file is added, removed, or renamed, we certainly > don’t want to rebuild all the targets whenever the directory’s > timestamp changes. One way to manage this is with order-only > prerequisites: make the directory an order-only prerequisite on all > the targets. > > OBJDIR := objdir > OBJS := $(addprefix $(OBJDIR)/,foo.o bar.o baz.o) > > $(OBJDIR)/%.o : %.c > $(COMPILE.c) $(OUTPUT_OPTION) $< > > all: $(OBJS) > > $(OBJS): | $(OBJDIR) > > $(OBJDIR): > mkdir $(OBJDIR) > > Now the rule to create the objdir directory will be run, if needed, > before any ‘.o’ is built, but no ‘.o’ will be built because the > objdir directory timestamp changed. This patch fixes this behavior. No binaries are rebuilt when the command make is re-run: $ make make: Nothing to be done for 'all'. *: https://www.gnu.org/software/make/manual/html_node/Prerequisite-Types.html Signed-off-by: Gaël PORTAY <gael.portay@savoirfairelinux.com> Signed-off-by: Seebs <seebs@seebs.net>
2017-02-01pseudo 1.8.2pseudo-1.8.2PSEUDO_1_8_2Seebs2-1/+2
2017-02-01don't remove xattrs still in useSeebs2-2/+7
When deleting a specific file, delete xattrs only if it's the last file with that device/inode pair. Signed-off-by: Seebs <seebs@seebs.net>
2016-12-12From: Andrew Shadura <andrewsh@debian.org>Seebs3-0/+5
Each manual page should start with a "NAME" section, which lists the name and a brief description of the page separated by "\-". Signed-off-by: Igor Gnatenko <i.gnatenko.brain@gmail.com> Signed-off-by: Seebs <seebs@seebs.net>
2016-12-12The setcap utility supplied by libcap is used to set capabilities on aSeebs5-0/+24
file. Before setting a file's capabilities with cap_set_file() (which uses setxattr()) it calls cap_set_flag(mycaps, CAP_EFFECTIVE, 1, &capflag, CAP_SET). cap_set_flag() uses the capset syscall to raise the process' effective capability. In most cases if the process isn't running as root this will fail and setcap will exit with an error. Because setxattr is intercepted by pseudo it's unnecessary for setcap to call capset(). Override capset with a pseudo function that does nothing and always returns 0. Signed-off-by: George McCollister <george.mccollister at gmail.com> Signed-off-by: Seebs <seebs@seebs.net>
2016-12-12From: Rabin Vincent <rabinv@axis.com>Seebs3-0/+17
When tclsh forks it can create new threads in the child process, in a pthread_atfork() handler. Running this under pseudo results in a deadlock since the pseudo_lock() call in the new thread in the child process premanently believes that the mutex is already locked by another thread (which actually only existed in the parent process). The provided test cases reproduces this. Similar hangs can also been seen in other cases, such as when attempting to use vim's cscope support under pseudo. Fix it by reseting the mutex in a pthread_atfork() child function. Signed-off-by: Rabin Vincent <rabinv@axis.com> Signed-off-by: Seebs <seebs@seebs.net>
2016-12-12From: Rabin Vincent <rabinv@axis.com>Seebs2-0/+3
test-umask fails if run twice. Make it remove the created temporary files before the test. Signed-off-by: Rabin Vincent <rabinv@axis.com> Signed-off-by: Seebs <seebs@seebs.net>