[PATCH] openposix: timer_*/speculative: Handle SIGSEGV on invalid timer ID
Avinesh Kumar via ltp <[email protected]>
| Newsgroups | gmane.linux.ltp |
|---|---|
| Message-ID | <[email protected]> |
From: Avinesh Kumar <avinesh.kumar-IBi9RG/[email protected]> timer_delete/speculative/5-1, timer_getoverrun/speculative/6-1, timer_gettime/speculative/6-1 and timer_settime/speculative/12-1 all pass a bogus value as an invalid timer_t timerid. On i586, glibc dereferences timer_t as a pointer into internal state, and the bogus pointer causes a SIGSEGV instead of the tests' expected EINVAL: timer_delete_sp[22499]: segfault at 7f4982f0 ip b7e07824 sp bfa4c140 error 4 in libc.so.6[a4824,b7d87000+191000] POSIX defines no required behavior for an invalid timer ID (EINVAL is only a recommendation), so a SIGSEGV is just as valid an outcome. Signed-off-by: Avinesh Kumar <avinesh.kumar-IBi9RG/[email protected]> --- .../interfaces/timer_delete/speculative/5-1.c | 19 ++++++++++++++++++ .../timer_getoverrun/speculative/6-1.c | 19 ++++++++++++++++++ .../timer_gettime/speculative/6-1.c | 20 +++++++++++++++++++ .../timer_settime/speculative/12-1.c | 20 +++++++++++++++++++ 4 files changed, 78 insertions(+) diff --git a/testcases/open_posix_testsuite/conformance/interfaces/timer_delete/speculative/5-1.c b/testcases/open_posix_testsuite/conformance/interfaces/timer_delete/speculative/5-1.c index 912cf5800e6f..fb46c3e7dabb 100644 --- a/testcases/open_posix_testsuite/conformance/interfaces/timer_delete/speculative/5-1.c +++ b/testcases/open_posix_testsuite/conformance/interfaces/timer_delete/speculative/5-1.c @@ -12,17 +12,36 @@ #include <time.h> #include <stdio.h> +#include <stdlib.h> #include <errno.h> +#include <signal.h> #include "posixtest.h" #define BOGUSTIMERID 99999 +/* + * when timerid argument does not correspond to a timer ID returned by + * timer_create(), POSIX recommends EINVAL, but SIGSEGV is also + * valid outcome. + */ +static void sigsegv_handler(int signum PTS_ATTRIBUTE_UNUSED) +{ + printf("Got SIGSEGV when calling timer_delete() with an invalid timer ID\n"); + printf("Test PASSED\n"); + exit(PTS_PASS); +} + int test_main(int argc PTS_ATTRIBUTE_UNUSED, char **argv PTS_ATTRIBUTE_UNUSED) { timer_t tid; int tval = BOGUSTIMERID; + struct sigaction sa = { .sa_handler = sigsegv_handler }; + tid = (timer_t) & tval; + sigfillset(&sa.sa_mask); + sigaction(SIGSEGV, &sa, NULL); + if (timer_delete(tid) == -1) { if (errno == EINVAL) { printf diff --git a/testcases/open_posix_testsuite/conformance/interfaces/timer_getoverrun/speculative/6-1.c b/testcases/open_posix_testsuite/conformance/interfaces/timer_getoverrun/speculative/6-1.c index 6e18560e5084..429b08379e9c 100644 --- a/testcases/open_posix_testsuite/conformance/interfaces/timer_getoverrun/speculative/6-1.c +++ b/testcases/open_posix_testsuite/conformance/interfaces/timer_getoverrun/speculative/6-1.c @@ -12,17 +12,36 @@ #include <time.h> #include <stdio.h> +#include <stdlib.h> #include <errno.h> +#include <signal.h> #include "posixtest.h" #define BOGUSTID 9999 +/* + * when timerid argument does not correspond to a timer ID returned by + * timer_create(), POSIX recommends EINVAL, but SIGSEGV is also + * valid outcome. + */ +static void sigsegv_handler(int signum PTS_ATTRIBUTE_UNUSED) +{ + printf("Got SIGSEGV when calling timer_getoverrun() with an invalid timer ID\n"); + printf("Test PASSED\n"); + exit(PTS_PASS); +} + int test_main(int argc PTS_ATTRIBUTE_UNUSED, char **argv PTS_ATTRIBUTE_UNUSED) { timer_t tid; int tval = BOGUSTID; + struct sigaction sa = { .sa_handler = sigsegv_handler }; + tid = (timer_t) & tval; + sigfillset(&sa.sa_mask); + sigaction(SIGSEGV, &sa, NULL); + if (timer_getoverrun(tid) == -1) { if (EINVAL == errno) { printf("fcn returned -1 and errno=EINVAL\n"); diff --git a/testcases/open_posix_testsuite/conformance/interfaces/timer_gettime/speculative/6-1.c b/testcases/open_posix_testsuite/conformance/interfaces/timer_gettime/speculative/6-1.c index d09c2f70901d..c124497153a9 100644 --- a/testcases/open_posix_testsuite/conformance/interfaces/timer_gettime/speculative/6-1.c +++ b/testcases/open_posix_testsuite/conformance/interfaces/timer_gettime/speculative/6-1.c @@ -12,17 +12,37 @@ #include <time.h> #include <stdio.h> +#include <stdlib.h> #include <errno.h> +#include <signal.h> #include "posixtest.h" #define BOGUSTID 9999 +/* + * when timerid argument does not correspond to a timer ID returned by + * timer_create(), POSIX recommends EINVAL, but SIGSEGV is also + * valid outcome. + */ +static void sigsegv_handler(int signum PTS_ATTRIBUTE_UNUSED) +{ + printf("Got SIGSEGV when calling timer_gettime() with an invalid timer ID\n"); + printf("Test PASSED\n"); + exit(PTS_PASS); +} + int test_main(int argc PTS_ATTRIBUTE_UNUSED, char **argv PTS_ATTRIBUTE_UNUSED) { timer_t tid; struct itimerspec its; int tval = BOGUSTID; + struct sigaction sa = { .sa_handler = sigsegv_handler }; + tid = (timer_t) & tval; + + sigfillset(&sa.sa_mask); + sigaction(SIGSEGV, &sa, NULL); + if (timer_gettime(tid, &its) == -1) { if (EINVAL == errno) { printf("fcn returned -1 and errno==EINVAL\n"); diff --git a/testcases/open_posix_testsuite/conformance/interfaces/timer_settime/speculative/12-1.c b/testcases/open_posix_testsuite/conformance/interfaces/timer_settime/speculative/12-1.c index 5d4e1dda30ba..056f75448ea8 100644 --- a/testcases/open_posix_testsuite/conformance/interfaces/timer_settime/speculative/12-1.c +++ b/testcases/open_posix_testsuite/conformance/interfaces/timer_settime/speculative/12-1.c @@ -11,17 +11,37 @@ #include <time.h> #include <stdio.h> +#include <stdlib.h> #include <errno.h> +#include <signal.h> #include "posixtest.h" #define BOGUSTID 9999 +/* + * when timerid argument does not correspond to a timer ID returned by + * timer_create(), POSIX recommends EINVAL, but SIGSEGV is also + * valid outcome. + */ +static void sigsegv_handler(int signum PTS_ATTRIBUTE_UNUSED) +{ + printf("Got SIGSEGV when calling timer_settime() with an invalid timer ID\n"); + printf("Test PASSED\n"); + exit(PTS_PASS); +} + int test_main(int argc PTS_ATTRIBUTE_UNUSED, char **argv PTS_ATTRIBUTE_UNUSED) { timer_t tid; struct itimerspec its; int tval = BOGUSTID; + struct sigaction sa = { .sa_handler = sigsegv_handler }; + tid = (timer_t) & tval; + + sigfillset(&sa.sa_mask); + sigaction(SIGSEGV, &sa, NULL); + its.it_interval.tv_sec = 0; its.it_interval.tv_nsec = 0; its.it_value.tv_sec = 0; -- 2.55.0 -- Mailing list info: https://lists.linux.it/listinfo/ltp