Skip to content

Commit 126a44d

Browse files
committed
Write more tests attempting to break windows
This time I haven't succeeded in breaking anything which is a good sign.
1 parent 4769267 commit 126a44d

File tree

7 files changed

+331
-37
lines changed

7 files changed

+331
-37
lines changed

libc/calls/readwrite-nt.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
1717
│ PERFORMANCE OF THIS SOFTWARE. │
1818
╚─────────────────────────────────────────────────────────────────────────────*/
19-
#include "libc/assert.h"
2019
#include "libc/calls/createfileflags.internal.h"
2120
#include "libc/calls/internal.h"
2221
#include "libc/calls/sig.internal.h"
@@ -170,14 +169,11 @@ sys_readwrite_nt(int fd, void *data, size_t size, ssize_t offset,
170169
}
171170

172171
// the i/o operation was successfully canceled
173-
if (got_eagain) {
174-
unassert(!got_sig);
172+
if (got_eagain)
175173
return eagain();
176-
}
177174

178175
// it's now reasonable to report semaphore creation error
179176
if (other_error) {
180-
unassert(!got_sig);
181177
errno = __dos2errno(other_error);
182178
return -1;
183179
}

libc/calls/sig.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -302,10 +302,10 @@ static textwindows int __sig_killer(struct PosixThread *pt, int sig, int sic) {
302302
return 0;
303303
}
304304

305-
// we can't preempt threads that masked sig or are blocked. we aso
306-
// need to ensure we don't the target thread's stack if many signals
307-
// need to be delivered at once. we also need to make sure two threads
308-
// can't deadlock by killing each other at the same time.
305+
// we can't preempt threads that masked sigs or are blocked. we also
306+
// need to ensure we don't overflow the target thread's stack if many
307+
// signals need to be delivered at once. we also need to make sure two
308+
// threads can't deadlock by killing each other at the same time.
309309
if ((atomic_load_explicit(&pt->tib->tib_sigmask, memory_order_acquire) &
310310
(1ull << (sig - 1))) ||
311311
atomic_exchange_explicit(&pt->pt_intoff, 1, memory_order_acquire)) {

test/posix/pipe_write_eagain_test.c

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
// Copyright 2024 Justine Alexandra Roberts Tunney
2+
//
3+
// Permission to use, copy, modify, and/or distribute this software for
4+
// any purpose with or without fee is hereby granted, provided that the
5+
// above copyright notice and this permission notice appear in all copies.
6+
//
7+
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
8+
// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
9+
// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
10+
// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
11+
// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
12+
// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
13+
// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14+
// PERFORMANCE OF THIS SOFTWARE.
15+
16+
#include <errno.h>
17+
#include <poll.h>
18+
#include <pthread.h>
19+
#include <stdio.h>
20+
#include <stdlib.h>
21+
#include <unistd.h>
22+
23+
/**
24+
* @fileoverview Tests that EAGAIN won't corrupt pipe.
25+
*
26+
* This is a real bug when using CancelIoEx() on winsock writes, so we
27+
* need to make sure it doesn't happen on pipes too.
28+
*/
29+
30+
#define ITERATIONS 100000
31+
#define ASYMMETRY 3
32+
33+
int fds[2];
34+
int got_read_eagains;
35+
int got_write_eagains;
36+
37+
void *worker(void *arg) {
38+
for (int expect = 0; expect < ITERATIONS;) {
39+
int number;
40+
ssize_t rc = read(fds[0], &number, sizeof(number));
41+
if (rc == -1) {
42+
if (errno == EAGAIN) {
43+
++got_read_eagains;
44+
if (poll(&(struct pollfd){fds[0], POLLIN}, 1, -1) == -1)
45+
exit(11);
46+
continue;
47+
}
48+
perror("read");
49+
exit(8);
50+
}
51+
size_t got = rc;
52+
if (got != sizeof(int))
53+
exit(9);
54+
if (expect != number)
55+
exit(10);
56+
++expect;
57+
}
58+
return 0;
59+
}
60+
61+
int main(int argc, char *argv[]) {
62+
63+
if (pipe2(fds, O_NONBLOCK))
64+
return 1;
65+
66+
pthread_t th;
67+
if (pthread_create(&th, 0, worker, 0))
68+
return 2;
69+
70+
int number = 0;
71+
for (;;) {
72+
int chunk = 0;
73+
int numbers[ASYMMETRY];
74+
for (;;) {
75+
numbers[chunk] = number + chunk;
76+
if (++chunk == ASYMMETRY)
77+
break;
78+
if (number + chunk == ITERATIONS)
79+
break;
80+
}
81+
for (;;) {
82+
ssize_t rc = write(fds[1], numbers, chunk * sizeof(int));
83+
if (rc == -1) {
84+
if (errno == EAGAIN) {
85+
++got_write_eagains;
86+
if (poll(&(struct pollfd){fds[1], POLLOUT}, 1, -1) == -1)
87+
return 10;
88+
continue;
89+
}
90+
return 3;
91+
}
92+
if (rc % sizeof(int))
93+
return 4;
94+
chunk = rc / sizeof(int);
95+
number += chunk;
96+
break;
97+
}
98+
if (number == ITERATIONS)
99+
break;
100+
}
101+
102+
if (pthread_join(th, 0))
103+
return 5;
104+
105+
if (!got_read_eagains && !got_write_eagains)
106+
return 7;
107+
}

test/posix/sa_resethand_test.c

Lines changed: 70 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,90 @@
1-
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
2-
│ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi │
3-
╞══════════════════════════════════════════════════════════════════════════════╡
4-
│ Copyright 2023 Justine Alexandra Roberts Tunney │
5-
│ │
6-
│ Permission to use, copy, modify, and/or distribute this software for │
7-
│ any purpose with or without fee is hereby granted, provided that the │
8-
│ above copyright notice and this permission notice appear in all copies. │
9-
│ │
10-
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
11-
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
12-
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
13-
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
14-
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
15-
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
16-
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
17-
│ PERFORMANCE OF THIS SOFTWARE. │
18-
╚─────────────────────────────────────────────────────────────────────────────*/
1+
// Copyright 2024 Justine Alexandra Roberts Tunney
2+
//
3+
// Permission to use, copy, modify, and/or distribute this software for
4+
// any purpose with or without fee is hereby granted, provided that the
5+
// above copyright notice and this permission notice appear in all copies.
6+
//
7+
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
8+
// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
9+
// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
10+
// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
11+
// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
12+
// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
13+
// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14+
// PERFORMANCE OF THIS SOFTWARE.
15+
16+
#include <errno.h>
1917
#include <signal.h>
18+
#include <stdlib.h>
2019

2120
volatile int gotsig;
2221

2322
void OnSig(int sig) {
2423
gotsig = sig;
2524
}
2625

27-
int main() {
26+
void test_sa_resethand_raise(void) {
2827
struct sigaction sa;
2928
sa.sa_handler = OnSig;
3029
sa.sa_flags = SA_RESETHAND;
3130
sigemptyset(&sa.sa_mask);
3231
if (sigaction(SIGUSR1, &sa, 0))
33-
return 1;
32+
exit(1);
3433
if (sigaction(SIGUSR1, 0, &sa))
35-
return 2;
34+
exit(2);
3635
if (sa.sa_handler != OnSig)
37-
return 3;
36+
exit(3);
3837
if (raise(SIGUSR1))
39-
return 4;
38+
exit(4);
4039
if (gotsig != SIGUSR1)
41-
return 5;
40+
exit(5);
4241
if (sigaction(SIGUSR1, 0, &sa))
43-
return 6;
42+
exit(6);
43+
if (sa.sa_handler != SIG_DFL)
44+
exit(7);
45+
}
46+
47+
void test_sa_resethand_pause(void) {
48+
struct sigaction sa;
49+
sa.sa_handler = OnSig;
50+
sa.sa_flags = SA_RESETHAND;
51+
sigemptyset(&sa.sa_mask);
52+
if (sigaction(SIGALRM, &sa, 0))
53+
exit(10);
54+
ualarm(10000, 0);
55+
if (pause() != -1 || errno != EINTR)
56+
exit(11);
57+
if (gotsig != SIGALRM)
58+
exit(12);
59+
if (sigaction(SIGALRM, 0, &sa))
60+
exit(13);
4461
if (sa.sa_handler != SIG_DFL)
45-
return 7;
62+
exit(14);
63+
}
64+
65+
void test_sa_resethand_read(void) {
66+
struct sigaction sa;
67+
sa.sa_handler = OnSig;
68+
sa.sa_flags = SA_RESETHAND;
69+
sigemptyset(&sa.sa_mask);
70+
if (sigaction(SIGALRM, &sa, 0))
71+
exit(20);
72+
int fds[2];
73+
if (pipe(fds))
74+
exit(21);
75+
ualarm(10000, 0);
76+
if (read(fds[0], (char[]){0}, 1) != -1 || errno != EINTR)
77+
exit(22);
78+
if (gotsig != SIGALRM)
79+
exit(23);
80+
if (sigaction(SIGALRM, 0, &sa))
81+
exit(24);
82+
if (sa.sa_handler != SIG_DFL)
83+
exit(25);
84+
}
85+
86+
int main() {
87+
test_sa_resethand_raise();
88+
test_sa_resethand_pause();
89+
test_sa_resethand_read();
4690
}

0 commit comments

Comments
 (0)