Commit Graph

2411 Commits

Author SHA1 Message Date
c82d3bada3 fix integer overflows in time_t/struct tm conversion code
as found and reported by Brian Mastenbrook, the expressions
400*qc_cycles and years+100 in __secs_to_tm were both subject to
integer overflow for extreme values of the input t.

this patch by Szabolcs Nagy fixes the code by switching to larger
types, and matches the original intent I had in mind when writing this
code.
2015-10-08 23:30:42 +00:00
7b9f57f207 fix open_[w]memstream behavior when no writes take place
the specification for these functions requires that the buffer/size
exposed to the caller be valid after any successful call to fflush or
fclose on the stream. the implementation's approach is to update them
only at flush time, but that misses the case where fflush or fclose is
called without any writes having taken place, in which case the write
flushing callback will not be called.

to fix both the observable bug and the desired invariant, setup empty
buffers at open time and fail the open operation if no memory is
available.
2015-10-08 22:10:09 +00:00
2d51c4ad57 make nl_langinfo(CODESET) always return "ASCII" in byte-based C locale
commit 844212d94f, which did not make it
into any releases, changed nl_langinfo(CODESET) to always return
"UTF-8", even in the byte-based C locale. this was problematic because
application software was found to use the string match for "UTF-8" to
activate its own UTF-8 processing. this both undermines the byte-based
functionality of the C locale, and if mixed with with calls to the
standard multibyte functions, which happened in practice, could result
in severe mis-handling of input.

the motive for the previous change was that, to avoid widespread
compatibility problems, the string returned by nl_langinfo(CODESET)
needs to be accepted by iconv and by third-party character conversion
code. thus, the only remaining choice is "ASCII". this choice
accurately represents the intent that high bytes do not have
individual meaning in the C locale, but it does mean that iconv, when
passed nl_langinfo(CODESET) in the C locale, will produce errors in
cases where mbrtowc would have succeeded. for reference, glibc behaves
similarly in this regard, so I don't think it will be a problem.
2015-10-01 22:59:56 +00:00
fd2add5ba0 fix mips fesetround failure to write back resulting mode
patch by Anand Takale.
2015-10-01 05:10:54 +00:00
f3a53f095c eliminate protected-visibility data in libc.so with vis.h preinclude
some newer binutils versions print scary warnings about protected data
because most gcc versions fail to produce the right address
references/relocations for such data that might be subject to copy
relocations. originally vis.h explicitly assigned default visibility
to all public data symbols to avoid this issue, but commit
b8dda24fe1 removed this treatment for
stdin/out/err to work around a gcc 3.x bug, and since they don't
actually need it (because taking their addresses is not valid C).

instead, a check for the gcc 3.x bug is added to the configure check
for vis.h preinclude support; this feature will simply be disabled
when using a buggy version of gcc.
2015-09-29 02:44:05 +00:00
2a6e1f0f5a avoid attempting to lookup IP literals as hostnames
previously, __lookup_ipliteral only checked its argument against the
requested address family, so IPv4 literals passed through to
__lookup_name if the caller asked for only IPv6 results, and likewise
for IPv6 literals when the caller asked for only IPv4. this resulted
in spurious DNS lookups that reportedly even succeeded with some
nameservers.

now, __lookup_ipliteral attempts to parse its argument as both IPv4
and IPv6, and returns an error (to stop further search) rather than 0
(no results yet) if the form of the argument mismatches the requested
address family.

based on patch by Julien Ramseier.
2015-09-25 01:18:42 +00:00
06bcf9bc94 make getaddrinfo return error if both host and service name are null
this case is specified as a mandatory ("shall fail") error.

based on patch by Julien Ramseier.
2015-09-25 01:03:36 +00:00
b4d94ba40d fix localeconv field value for unavailable values
per ISO C, CHAR_MAX, not -1, is the value used to indicate that a char
field in struct lconv is unavailable.

patch by Julien Ramseier.
2015-09-24 06:40:05 +00:00
bd275378d3 avoid reading uninitialized memory in __map_file
The value of *size is not relevant in case of failure, but it's
better not to copy garbage from the stack into it.
(The compiler cannot see through the syscall, so optimization
was not affected by the unspecified value).
2015-09-24 06:33:46 +00:00
4260dfe1ec regcomp: propagate allocation failures
The error code of an allocating function was not checked in tre_add_tag.
2015-09-24 02:33:18 -04:00
b61df2294f fix signal return for sh/fdpic
the restorer function pointer provided in the kernel sigaction
structure is interpreted by the kernel as a raw code address, not a
function descriptor.

this commit moves the declarations of the __restore and __restore_rt
symbols to ksigaction.h so that arch versions of the file can override
them, and introduces a version for sh which declares them as objects
rather than functions.

an alternate solution would have been defining SA_RESTORER to 0 so
that the functions are not used, but this both requires executable
stack (since the sh kernel does not have a vdso page with permanent
restorer functions) and crashes on qemu user-level emulation.
2015-09-23 18:33:49 +00:00
6c5cad2aa5 fix dlsym RTLD_NEXT behavior for fdpic
lookup the dso an address falls in based on the loadmap and not just a
base/length. fix the main app's fake loadmap used when loaded by a
non-fdpic-aware loader so that it does not cover the whole memory
space.

function descriptor addresses are also matched for future use by
dladdr, but reverse lookups of function descriptors via dladdr have
not been implemented yet. some revisions may be needed in the future
once reclaim_gaps supports fdpic, so that function descriptors
allocated in reclaimed heap space do not get detected as belonging to
the module whose gaps they were allocated in.
2015-09-22 23:41:41 +00:00
d47d9a50f2 fix dlsym lookup of function symbols on fdpic
previously these resolved to the code address rather than the address
of the function descriptor.

the conditions for accepting or rejecting symbols are quite
inconsistent between the different points in the dynamic linker code
where such decisions are made. this commit attempts to be at least as
correct as anything already there, but does not improve consistency.
it has been tested to correctly avoid symbols that are merely
references to functions defined in other modules, at least in simple
usage, but at some point all symbol lookup logic should be reviewed
and refactored/unified.
2015-09-22 23:11:38 +00:00
c87a521033 move calls to application init functions after crt1 entry point
this change is needed to be compatible with fdpic, where some of the
main application's relocations may be performed as part of the crt1
entry point. if we call init functions before passing control, these
relocations will not yet have been performed, and the init code will
potentially make use of invalid pointers.

conceptually, no code provided by the application or third-party
libraries should run before the application entry point. the
difference is not observable to programs using the crt1 we provide,
but it could come into play if custom entry point code is used, so
it's better to be doing this right anyway.
2015-09-22 20:24:28 +00:00
78f430295c fix breakage in non-fdpic dynamic linker init/fini processing
a mistaken #ifdef instead of #if caused conversion of code addresses
to function descriptors to be performed even on non-fdpic.
2015-09-22 20:20:39 +00:00
30fdc06bba fix resolving interp string address on fdpic ldd command 2015-09-22 19:21:57 +00:00
eaf7ab6e24 add real fdpic loading of shared libraries
previously, the normal ELF library loading code was used even for
fdpic, so only the kernel-loaded dynamic linker and main app could
benefit from separate placement of segments and shared text.
2015-09-22 19:12:48 +00:00
7a9669e977 add general fdpic support in dynamic linker and arch support for sh
at this point not all functionality is complete. the dynamic linker
itself, and main app if it is also loaded by the kernel, take
advantage of fdpic and do not need constant displacement between
segments, but additional libraries loaded by the dynamic linker follow
normal ELF semantics for mapping still. this fully works, but does not
admit shared text on nommu.

in terms of actual functional correctness, dlsym's results are
presently incorrect for function symbols, RTLD_NEXT fails to identify
the caller correctly, and dladdr fails almost entirely.

with the dynamic linker entry point working, support for static pie is
automatically included, but linking the main application as ET_DYN
(pie) probably does not make sense for fdpic anyway. ET_EXEC is
equally relocatable but more efficient at representing relocations.
2015-09-22 03:54:42 +00:00
3958144ede factor symbol counting out of dladdr as its own function
the fdpic code will need to count symbols, and it may be useful
elsewhere in the future too. counting is trivial as long as sysv hash
is present, but for gnu-hash-only libraries it's complex.

the behavior of the count is changed slightly: we now include symbols
that are not accessible by the gnu hash table in the count. this may
make dladdr slightly slower. if this is a problem, dladdr can subtract
out the part that should not be accessible. unlike in the old code,
subtracting this out is easy even in the fast path where sysv hash is
available too.
2015-09-21 21:47:50 +00:00
d874064579 simplify dlstart code by using integer type for base address 2015-09-21 20:42:44 +00:00
2a54733820 refactor some more dynamic linker load address computations
these were just missed in the previous commits.
2015-09-17 19:45:45 +00:00
e6076c99dd remove some useless casts in dynamic linker 2015-09-17 19:21:55 +00:00
eb567c12cd add fdpic structs and reloc types for dynamic linking 2015-09-17 18:51:57 +00:00
a735f53e6a further refactoring of dynamic linker load address computations
these are in do_relocs. the first one was omitted in commit
301335a80b because it slightly changes
code (using dso->base rather than cached local var base) and would
have prevented easy verification. the other was an oversight.
2015-09-17 17:50:43 +00:00
301335a80b begin refactoring load address computations in dynamic linker
for ordinary ELF with fixed segment displacements, load address
computation is simply adding the base load address. but for FDPIC,
each segment has its own load address, and virtual addresses need to
be adjusted according to the segment they fall in. abstracting this
computation is the first step to making the dynamic linker ready for
FDPIC.

for this first commit, a macro is used rather than a function in order
to facilitate correctness checking. I have verified that the generated
code does not change on my i386 build.
2015-09-17 17:18:09 +00:00
6fc30c2493 remove old dlstart stage-2 symbolic lookup code; add new generic
this new generic version of the stage-2 function lookup should work
for any arch where static data is accessible via got-relative or
pc-relative addressing, using approximately the technique described in
the log message for commit 2907afb8db.

since all the mips-like archs that need got slots fo access static
data have already transitioned to the new stage chaining scheme, the
old dynamic symbol lookup code is now removed.

aarch64, arm, and sh have not yet transitioned; with this commit, they
are now using the new generic code.
2015-09-17 08:16:24 +00:00
2907afb8db introduce new symbol-lookup-free rcrt1/dlstart stage chaining
previously, the call into stage 2 was made by looking up the symbol
name "__dls2" (which was chosen short to be easy to look up) from the
dynamic symbol table. this was no problem for the dynamic linker,
since it always exports all its symbols. in the case of the static pie
entry point, however, the dynamic symbol table does not contain the
necessary symbol unless -rdynamic/-E was used when linking. this
linking requirement is a major obstacle both to practical use of
static-pie as a nommu binary format (since it greatly enlarges the
file) and to upstream toolchain support for static-pie (adding -E to
default linking specs is not reasonable).

this patch replaces the runtime symbolic lookup with a link-time
lookup via an inline asm fragment, which reloc.h is responsible for
providing. in this initial commit, the asm is provided only for i386,
and the old lookup code is left in place as a fallback for archs that
have not yet transitioned.

modifying crt_arch.h to pass the stage-2 function pointer as an
argument was considered as an alternative, but such an approach would
not be compatible with fdpic, where it's impossible to compute
function pointers without already having performed relocations. it was
also deemed desirable to keep crt_arch.h as simple/minimal as
possible.

in principle, archs with pc-relative or got-relative addressing of
static variables could instead load the stage-2 function pointer from
a static volatile object. that does not work for fdpic, and is not
safe against reordering on mips-like archs that use got slots even for
static functions, but it's a valid on i386 and many others, and could
provide a reasonable default implementation in the future.
2015-09-17 06:30:55 +00:00
6d03c4ee58 provide arch-generic fdpic self-relocation code for crt1 to use
this file is intended to be included by crt_arch.h on fdpic-based
targets and needs to be called from the entry point asm.
2015-09-12 03:10:44 +00:00
234c58467c make sh clone asm fdpic-compatible
clone calls back to a function pointer provided by the caller, which
will actually be a pointer to a function descriptor on fdpic. the
obvious solution is to have a separate version of clone for fdpic, but
I have taken a simpler approach to go around the problem. instead of
calling the pointed-to function from asm, a direct call is made to an
internal C function which then calls the pointed-to function. this
lets the C compiler generate the appropriate calling convention for an
indirect call with no need for ABI-specific assembly.
2015-09-12 02:55:28 +00:00
cb1c88d42b fix uninitialized scopeid in lookups from hosts file and ip literals 2015-09-11 06:15:06 +00:00
deb85ab44d remove unused (and invalid) C version of sigsetjmp
originally, the comment in this code was correct and it would likely
work if the compiler generated a tail call to setjmp. however, commit
583e55122e redesigned sigsetjmp and
siglongjmp such that the old C implementation (which was not intended
to be used) is not even conceptually correct. remove it in the
interest of avoiding confusion when porting to new archs.
2015-09-09 06:59:45 +00:00
58f6259dff fix breakage in nl_langinfo from previous commit 2015-09-09 06:04:42 +00:00
844212d94f make nl_langinfo(CODESET) always return "UTF-8"
this restores the original behavior prior to the addition of the
byte-based C locale and fixes what is effectively a regression in
musl's property of always providing working UTF-8 support.

commit 1507ebf837 introduced the codeset
name "UTF-8-CODE-UNITS" for the byte-based C locale to represent that
the semantic content is UTF-8 but that it is being processed as code
units (bytes) rather than whole multibyte characters. however, many
programs assume that the codeset name is usable with iconv and/or
comes from a set of standard/widely-used names known to the
application. such programs are likely to produce warnings or errors,
run with reduced functionality, or mangle character data when run
explicitly in the C locale.

the standard places basically no requirements for the string returned
by nl_langinfo(CODESET) and how it interacts with other interfaces, so
returning "UTF-8" is permissible. moreover, it seems like the right
thing to do, since the identity of the character encoding as "UTF-8"
is independent of whether it is being processed as bytes of characters
by the standard library functions.
2015-09-09 05:13:33 +00:00
426a0e2912 fix fclose of permanent (stdin/out/err) streams
this fixes a bug reported by Nuno Gonçalves. previously, calling
fclose on stdin or stdout resulted in deadlock at exit time, since
__stdio_exit attempts to lock these streams to flush/seek them, and
has no easy way of knowing that they were closed.

conceptually, leaving a FILE stream locked on fclose is valid since,
in the abstract machine, it ceases to exist. but to satisfy the
implementation-internal assumption in __stdio_exit that it can access
these streams unconditionally, we need to unlock them.

it's also necessary that fclose leaves permanent streams in a state
where __stdio_exit will not attempt any further operations on them.
fortunately, the call to fflush already yields this property.
2015-09-09 04:31:07 +00:00
aa71ec3db8 getsubopt: don't include leading = in value string
getsubopt incorrectly returns the delimiting = in the value string,
this patch fixes it by increasing the pointer position by one.

Signed-off-by: Steven Barth <cyrus@openwrt.org>
2015-08-21 01:29:10 -04:00
c13f2af1fe match historical behavior for tm_gmtoff member of struct tm
tm_gmtoff is a nonstandard field, but on historical systems which have
this field, it stores the offset of the local time zone from GMT or
UTC. this is the opposite of the POSIX extern long timezone object and
the offsets used in POSIX-form TZ strings, which represent the offset
from local time to UTC. previously we were storing these negated
offsets in tm_gmtoff too.

programs which only used this field indirectly via strftime were not
affected since strftime performed the negation for presentation.
however, some programs and libraries accesse tm_gmtoff directly and
were obtaining negated time zone offsets.
2015-08-14 00:47:46 +00:00
062bb737de fix failure of tempnam to null-terminate result
tempnam uses an uninitialized buffer which is filled using memcpy and
__randname. It is therefore necessary to explicitly null-terminate it.

based on patch by Felix Janda.
2015-08-09 22:51:09 +00:00
c3761622e8 mitigate blow-up of heap size under malloc/free contention
during calls to free, any free chunks adjacent to the chunk being
freed are momentarily held in allocated state for the purpose of
merging, possibly leaving little or no available free memory for other
threads to allocate. under this condition, other threads will attempt
to expand the heap rather than waiting to use memory that will soon be
available. the race window where this happens is normally very small,
but became huge when free chooses to use madvise to release unused
physical memory, causing unbounded heap size growth.

this patch drastically shrinks the race window for unwanted heap
expansion by performing madvise with the bin lock held and marking the
bin non-empty in the binmask before making the expensive madvise
syscall. testing by Timo Teräs has shown this approach to be a
suitable mitigation.

more invasive changes to the synchronization between malloc and free
would be needed to completely eliminate the problem. it's not clear
whether such changes would improve or worsen typical-case performance,
or whether this would be a worthwhile direction to take malloc
development.
2015-08-07 19:19:49 +00:00
fe7582f4f9 fix undefined left-shift of negative values in utf-8 state table 2015-07-25 03:15:45 +00:00
57243b3021 fix atexit when it is called from an atexit handler
The old code accepted atexit handlers after exit, but did not run them
reliably. C11 seems to explicitly allow atexit to fail (and report
such failure) in this case, but this situation can easily come up in
C++ if a destructor has a local static object with a destructor so it
should be handled.

Note that the memory usage can grow linearly with the overall number
of registered atexit handlers instead of with the worst case list
length. (This only matters if atexit handlers keep registering atexit
handlers which should not happen in practice).

Commit message/rationale based on text by Szabolcs Nagy.
2015-07-24 21:22:43 +00:00
0f9c2666ac handle loss of syslog socket connection
when traditional syslogd implementations are restarted, the old server
socket ceases to exist and a new unix socket with the same pathname is
created. when this happens, the default destination address associated
with the client socket via connect is no longer valid, and attempts to
send produce errors. this happens despite the socket being datagram
type, and is in contrast to the behavior that would be seen with an IP
datagram (UDP) socket.

in order to avoid a situation where the application is unable to send
further syslog messages without calling closelog, this patch makes
syslog attempt to reconnect the socket when send returns an error
indicating a lost connection.

additionally, initial failure to connect the socket no longer results
in the socket being closed. this ensures that an application which
calls openlog to reserve the socket file descriptor will not run into
a situation where transient connection failure (e.g. due to syslogd
restart) prevents fd reservation. however, applications which may be
unable to connect the socket later (e.g. due to chroot, restricted
permissions, seccomp, etc.) will still fail to log if the syslog
socket cannot be connected at openlog time or if it has to be
reconnected later.
2015-07-09 18:47:48 +00:00
11894f6d3a fix incorrect void return type for syncfs function
being nonstandard, the closest thing to a specification for this
function is its man page, which documents it as returning int. it can
fail with EBADF if the file descriptor passed is invalid.
2015-07-09 17:07:35 +00:00
e8cbe0bad4 fix negated return value of ns_skiprr, breakage in related functions
due to a reversed pointer difference computation, ns_skiprr always
returned a negative value, which functions using it would interpret as
an error.

patch by Yu Lu.
2015-07-08 02:46:45 +00:00
2a780aa305 treat empty TZ environment variable as GMT rather than default
this improves compatibility with the behavior of other systems and
with some applications which set an empty TZ var to disable use of
local time by mktime, etc.
2015-07-06 22:13:11 +00:00
8f08a58c63 dynlink.c: pass gnu-hash table pointer to gnu_lookup
The callers need to check the value of the pointer anyway, so make
them pass the pointer to gnu_lookup instead of reloading it there.

Reorder gnu_lookup arguments so that always-used ones are listed
first. GCC can choose a calling convention with arguments in registers
(e.g. up to 3 arguments in eax, ecx, edx on x86), but cannot reorder
the arguments for static functions.
2015-06-28 02:30:12 +00:00
5b4286e12c dynlink.c: slim down gnu_lookup
Do not reference dso->syms and dso->strings until point of use.
Check 'h1 == (h2|1)', the simplest condition, before the others.
2015-06-28 01:51:15 +00:00
84389c6456 dynlink.c: use bloom filter in gnu hash lookup
Introduce gnu_lookup_filtered and use it to speed up symbol lookups in
find_sym (do_dlsym is left as is, based on an expectation that
frequently dlsym queries will use a dlopen handle rather than
RTLD_NEXT or RTLD_DEFAULT, and will not need to look at more than one
DSO).
2015-06-28 01:49:53 +00:00
66d45787c8 dynlink.c: use a faster expression in gnu_hash
With -Os, GCC uses a multiply rather than a shift and addition for 'h*33'.
Use a more efficient expression explicitely.
2015-06-27 21:48:19 -04:00
6ba5517a46 fix local-dynamic model TLS on mips and powerpc
the TLS ABI spec for mips, powerpc, and some other (presently
unsupported) RISC archs has the return value of __tls_get_addr offset
by +0x8000 and the result of DTPOFF relocations offset by -0x8000. I
had previously assumed this part of the ABI was actually just an
implementation detail, since the adjustments cancel out. however, when
the local dynamic model is used for accessing TLS that's known to be
in the same DSO, either of the following may happen:

1. the -0x8000 offset may already be applied to the argument structure
passed to __tls_get_addr at ld time, without any opportunity for
runtime relocations.

2. __tls_get_addr may be used with a zero offset argument to obtain a
base address for the module's TLS, to which the caller then applies
immediate offsets for individual objects accessed using the local
dynamic model. since the immediate offsets have the -0x8000 adjustment
applied to them, the base address they use needs to include the
+0x8000 offset.

it would be possible, but more complex, to store the pointers in the
dtv[] array with the +0x8000 offset pre-applied, to avoid the runtime
cost of adding 0x8000 on each call to __tls_get_addr. this change
could be made later if measurements show that it would help.
2015-06-25 22:22:00 +00:00
ce337daa00 make dynamic linker work around MAP_FAILED mmap failure on nommu kernels
previously, loading of additional libraries beyond libc/ldso did not
work on nommu kernels, nor did loading programs via invocation of the
dynamic linker as a command.
2015-06-23 04:05:31 +00:00