Since the CPU already does almost all necessary validation steps
for us, we don't really need to attempt to do this. Doing it
ourselves doesn't really work very reliably, because we'd have to
account for other processors modifying virtual memory, and we'd
have to account for e.g. pages not being able to be allocated
due to insufficient resources.
So change the copy_to/from_user (and associated helper functions)
to use the new safe_memcpy, which will return whether it succeeded
or not. The only manual validation step needed (which the CPU
can't perform for us) is making sure the pointers provided by user
mode aren't pointing to kernel mappings.
To make it easier to read/write from/to either kernel or user mode
data add the UserOrKernelBuffer helper class, which will internally
either use copy_from/to_user or directly memcpy, or pass the data
through directly using a temporary buffer on the stack.
Last but not least we need to keep syscall params trivial as we
need to copy them from/to user mode using copy_from/to_user.
str{,n}casecmp is supposed to be *only* declared by strings.h, note the
trailing 's' in the filename.
We don't have any implementation for strlcat; using any strcat variants is
a bad idea anyway, given our implementation of AK::String.
TODO: Find a way to lint for declared-but-nowhere-defined functions.
g++ seems to generate calls to __cxa_guard_* functions when we use
non-trivial initialization of local statics.
Requiring these symbols breaks some ports since these symbols are
defined in libcstdc++ which we do not link against when building ports.
This commit turns some local statics into global statics in netdb.cpp so
libc wouldn't need these symbols.
Previously, we were including the whole of <getopt.h> in <unistd.h>.
However according to the posix <unistd.h> doesn't have to contain
everything we had in <getopt.h>.
This fixes some symbol collisions that broke the git port.
And also mark strlcpy() and strlcat() with __attribute__((warn_unused_result)).
Since our code is warning-free, this ensures we never misuse those functions.
(Or are very sure about doing it when turning off the warning for a particular
piece of code.)
In case we know exactly how many bytes we're copying (and not copying a string
while limiting its length to that of a buffer), memcpy() is a more appropriate
function to call.
Also, fix null-terminating the %c pointer.
Before, we had about these occurrence counts:
COPY: 13 without, 33 with
MOVE: 12 without, 28 with
Clearly, 'with' was the preferred way. However, this introduced double-semicolons
all over the place, and caused some warnings to trigger.
This patch *forces* the usage of a semi-colon when calling the macro,
by removing the semi-colon within the macro. (And thus also gets rid
of the double-semicolon.)
The implementation in LibC did a timestamp->day-of-week conversion
which looks like a valuable thing to have. But we only need it in
time_to_tm, where we already computed year/month/day -- so let's
consolidate on the day_of_week function in DateTime (which is
getting extracted to AK).
The JS tests pointed out that the implementation in DateTime
had an off-by-one in the month when doing the leap year check,
so this change fixes that bug.
mktime() is supposed to fill in tm_wday and tm_yday, and it
it's supposed to canonicalize out-of-range values (that is,
"Jan 31" is turned into "Feb 1").
Instead of making the straightfoward tm_to_time() implementation
more complicated, just make it call time_to_tm() once the timestamp
is computed to break it back down ot (canonical) tm entries.
An overlong group name in /etc/groups would have caused getgrent() to overflow
the global __grdb_entry. Curiously, overflow *within* __grdb_entry seems to have
no detrimental effects.
However, it was possible for a malicious sysadmin(?!) to craft an /etc/group
that overflows outside of the page allocated for __grdb_entry thus crash the
calling process. This affected at least SystemServer and su.
Now, the group name will be simply truncated. For display purposes, this is
fine. In case there is an exceptionally long group, it will not be properly
recognized. Also, a malicious /etc/groups might cause the caller of getgrent()
to become confused, but that is unavoidable.
Before, strftime unintentionally interpreted 0 as 'unlimited'. The specification
of strftime says no such thing.
Now, it properly returns 0 in that case (because the NUL byte doesn't fit).
strdup: Because the length is already known at the time of copying, there is
no need to use strcpy (which has to check every single byte, and thus tends
to be slower than memcpy).
strndup: If 'str' is not NUL-terminated, strndup used to run off into the
adjacent memory region. This can be fixed by using the proper strlen variant:
strnlen.
Year computation has to be based on seconds, not days, in case
t is < 0 but t / __seconds_per_day is 0.
Year computation also has to consider negative timestamps.
With this, days is always positive and <= the number of days in the
year, so base the tm_wday computation directly on the timestamp,
and do it first, before t is modified in the year computation.
In C, % can return a negative number if the left operand is negative,
compensate for that.
Tested via test-js. (Except for tm_wday, since we don't implement
Date.prototype.getUTCDate() yet.)
snprintf is supposed to *always* NUL-terminate its output, so it has to write one
output byte fewer.
And yes, I *did* check all existing usages; this shouldn't break anything.
timegm() is like mktime() in that it converts a struct tm to
a timestamp, but it treats the struct tm as UTC instead of as
local time.
timegm() is nonstandard, but availabe in both Linux and BSD,
and it's a useful function to have.