Age | Commit message (Collapse) | Author | Lines |
|
the workaround/fallback code for supporting O_PATH file descriptors
when the kernel lacks support for performing these operations on them
caused EBADF to get replaced by ENOENT (due to missing entry in
/proc/self/fd). this is unlikely to affect real-world code (calls that
might yield EBADF are generally unsafe, especially in library code)
but it was breaking some test cases.
the fix I've applied is something of a tradeoff: it adds one syscall
to these operations on kernels where the workaround is needed. the
alternative would be to catch ENOENT from the /proc lookup and
translate it to EBADF, but I want to avoid doing that in the interest
of not touching/depending on /proc at all in these functions as long
as the kernel correctly supports the operations. this is following the
general principle of isolating hacks to code paths that are taken on
broken systems, and keeping the code for correct systems completely
hack-free.
|
|
|
|
on newer kernels, fchdir and fstat work anyway. this same fix should
be applied to any other syscalls that are similarly affected.
with this change, the current definitions of O_SEARCH and O_EXEC as
O_PATH are mostly conforming to POSIX requirements. the main remaining
issue is that O_NOFOLLOW has different semantics.
|
|
I intend to add more Linux workarounds that depend on using these
pathnames, and some of them will be in "syscall" functions that, from
an anti-bloat standpoint, should not depend on the whole snprintf
framework.
|
|
previously, the AT_SYMLINK_NOFOLLOW flag was ignored, giving
dangerously incorrect behavior -- the target of the symlink had its
modes changed to the modes (usually 0777) intended for the symlink).
this issue was amplified by the fact that musl provides lchmod, as a
wrapper for fchmodat, which some archival programs take as a sign that
symlink modes are supported and thus attempt to use.
emulating AT_SYMLINK_NOFOLLOW was a difficult problem, and I
originally believed it could not be solved, at least not without
depending on kernels newer than 3.5.x or so where O_PATH works halfway
well. however, it turns out that accessing O_PATH file descriptors via
their pseudo-symlink entries in /proc/self/fd works much better than
trying to use the fd directly, and works even on older kernels.
moreover, the kernel has permanently pegged these references to the
inode obtained by the O_PATH open, so there should not be race
conditions with the file being moved, deleted, replaced, etc.
|
|
the main aim of this patch is to ensure that if not all fields are
filled in, they contain zeros, so as not to confuse applications.
reportedly some older kernels, including commonly used openvz kernels,
lack the f_flags field, resulting in applications reading random junk
as the mount flags; the common symptom seems to be wrongly considering
the filesystem to be mounted read-only and refusing to operate. glibc
has some amazingly ugly fallback code to get the mount flags for old
kernels, but having them really is not that important anyway; what
matters most is not presenting incorrect flags to the application.
I have also aimed to fill in some fields of statvfs that were
previously missing, and added code to explicitly zero the reserved
space at the end of the structure, which will make things easier in
the future if this space someday needs to be used.
|
|
support for these was recently added to sysmacros.h. note that the
syscall argument is a long, despite dev_t being 64-bit, so on 32-bit
archs the high bits will be lost. it appears the high bits are just
glibc silliness and not part of the kernel api, anyway, but it's nice
that we have them there for future expansion if needed.
|
|
this function is obsolete, however it's available as a syscall
and as such qemu userspace emulation tries to forward it to the
host kernel.
|
|
to deal with the fact that the public headers may be used with pre-c99
compilers, __restrict is used in place of restrict, and defined
appropriately for any supported compiler. we also avoid the form
[restrict] since older versions of gcc rejected it due to a bug in the
original c99 standard, and instead use the form *restrict.
|
|
|
|
|
|
at the same time, make struct statfs match the traditional definition
and make it more useful, especially the fsid_t stuff.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|