diff options
author | Daniel Bertalan <dani@danielbertalan.dev> | 2021-08-11 10:36:08 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-08-12 21:10:44 +0200 |
commit | f95a11a7daa7c29aa0a019b9c965bfdd6f3cb69a (patch) | |
tree | bc50d9cb4f1a51e4bbddb6e18220101854774d4a | |
parent | 8b6397446e9b63c34c4275700050d35caf407e58 (diff) | |
download | serenity-f95a11a7daa7c29aa0a019b9c965bfdd6f3cb69a.zip |
LibC: Don't delete null check in `gettimeofday`
The `nonnull` attribute may delete null checks in the generated code, as
per the [GCC documentation]:
> The compiler may also perform optimizations based on the knowledge
> that nonnul parameters cannot be null. This can currently not be
> disabled other than by removing the nonnull attribute.
Disassembling the function as compiled by GCC, we can see that there is
no branch based on if `tv` is null. This means that `gettimeofday`
would produce UB if passed a null parameter, even if we wanted to
predictably return an error. Clang refuses to compile this due to a
`pointer-bool-conversion` warning.
In this commit, `settimeofday` is changed as well to match
`gettimeofday`'s null argument handling.
[GCC documentation]:
https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-nonnull-function-attribute
-rw-r--r-- | Userland/Libraries/LibC/sys/time.h | 4 | ||||
-rw-r--r-- | Userland/Libraries/LibC/time.cpp | 5 |
2 files changed, 7 insertions, 2 deletions
diff --git a/Userland/Libraries/LibC/sys/time.h b/Userland/Libraries/LibC/sys/time.h index 6d187e7ca4..7d670bfec8 100644 --- a/Userland/Libraries/LibC/sys/time.h +++ b/Userland/Libraries/LibC/sys/time.h @@ -23,8 +23,8 @@ struct timezone { }; int adjtime(const struct timeval* delta, struct timeval* old_delta); -int gettimeofday(struct timeval* __restrict__, void* __restrict__) __attribute__((nonnull(1))); -int settimeofday(struct timeval* __restrict__, void* __restrict__) __attribute__((nonnull(1))); +int gettimeofday(struct timeval* __restrict__, void* __restrict__); +int settimeofday(struct timeval* __restrict__, void* __restrict__); int utimes(const char* pathname, const struct timeval[2]); static inline void timeradd(const struct timeval* a, const struct timeval* b, struct timeval* out) diff --git a/Userland/Libraries/LibC/time.cpp b/Userland/Libraries/LibC/time.cpp index 016c966ee6..3cf77b7889 100644 --- a/Userland/Libraries/LibC/time.cpp +++ b/Userland/Libraries/LibC/time.cpp @@ -54,6 +54,11 @@ int gettimeofday(struct timeval* __restrict__ tv, void* __restrict__) int settimeofday(struct timeval* __restrict__ tv, void* __restrict__) { + if (!tv) { + errno = EFAULT; + return -1; + } + timespec ts; TIMEVAL_TO_TIMESPEC(tv, &ts); return clock_settime(CLOCK_REALTIME, &ts); |