Skip to content

Commit 3265324

Browse files
committed
Don't relocate file descriptor memory
This change fixes #496 where ASAN spotted a race condition that could happen in multithreaded programs, with more than OPEN_MAX descriptors when using ZipOS or Windows NT, which require tracking open file info and this change fixes that table so it never relocates, thus allowing us to continue to enjoy the benefits of avoiding locks while reading.
1 parent c3208eb commit 3265324

35 files changed

+297
-152
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ include test/libc/fmt/test.mk
211211
include test/libc/dns/test.mk
212212
include test/libc/time/test.mk
213213
include test/libc/stdio/test.mk
214+
include test/libc/zipos/test.mk
214215
include test/libc/release/test.mk
215216
include test/libc/test.mk
216217
include test/net/http/test.mk

examples/walk.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,12 @@
77
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
88
╚─────────────────────────────────────────────────────────────────*/
99
#endif
10-
#include "libc/calls/calls.h"
11-
#include "libc/calls/struct/stat.h"
1210
#include "libc/errno.h"
13-
#include "libc/runtime/gc.h"
1411
#include "libc/runtime/runtime.h"
1512
#include "libc/stdio/stdio.h"
1613
#include "libc/str/str.h"
1714
#include "libc/sysv/consts/exit.h"
1815
#include "libc/sysv/consts/s.h"
19-
#include "libc/x/x.h"
2016
#include "third_party/musl/ftw.h"
2117

2218
/**

libc/calls/calls.mk

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -79,14 +79,6 @@ o/$(MODE)/libc/calls/vdsofunc.greg.o: private \
7979
-ffreestanding \
8080
-fno-sanitize=address
8181

82-
# we can't use asan because:
83-
# asan guard pages haven't been allocated yet
84-
o/$(MODE)/libc/calls/directmap.o \
85-
o/$(MODE)/libc/calls/directmap-nt.o: private \
86-
OVERRIDE_COPTS += \
87-
-ffreestanding \
88-
-fno-sanitize=address
89-
9082
# we can't use asan because:
9183
# ntspawn allocates 128kb of heap memory via win32
9284
o/$(MODE)/libc/calls/ntspawn.o \
@@ -144,12 +136,6 @@ o/$(MODE)/libc/calls/ioctl-siocgifconf-nt.o: private \
144136
-ffunction-sections \
145137
-fdata-sections
146138

147-
# we want small code size because:
148-
# to keep .text.head under 4096 bytes
149-
o/$(MODE)/libc/calls/mman.greg.o: private \
150-
OVERRIDE_COPTS += \
151-
-Os
152-
153139
# we always want -Os because:
154140
# va_arg codegen is very bloated in default mode
155141
o//libc/calls/open.o \

libc/calls/extend.internal.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#ifndef COSMOPOLITAN_LIBC_CALLS_EXTEND_INTERNAL_H_
2+
#define COSMOPOLITAN_LIBC_CALLS_EXTEND_INTERNAL_H_
3+
#if !(__ASSEMBLER__ + __LINKER__ + 0)
4+
COSMOPOLITAN_C_START_
5+
6+
void *_extend(void *, size_t, void *, intptr_t);
7+
8+
COSMOPOLITAN_C_END_
9+
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
10+
#endif /* COSMOPOLITAN_LIBC_CALLS_EXTEND_INTERNAL_H_ */

libc/calls/reservefd.c

Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
╚─────────────────────────────────────────────────────────────────────────────*/
1919
#include "libc/assert.h"
2020
#include "libc/calls/calls.h"
21+
#include "libc/calls/extend.internal.h"
2122
#include "libc/calls/internal.h"
2223
#include "libc/calls/state.internal.h"
2324
#include "libc/calls/strace.internal.h"
@@ -46,33 +47,11 @@ static volatile size_t mapsize;
4647
* @asyncsignalsafe
4748
*/
4849
int __ensurefds_unlocked(int fd) {
49-
uint64_t addr;
50-
int prot, flags;
51-
size_t size, chunk;
52-
struct DirectMap dm;
50+
bool relocate;
5351
if (fd < g_fds.n) return fd;
54-
STRACE("__ensurefds(%d) extending", fd);
55-
size = mapsize;
56-
chunk = FRAMESIZE;
57-
if (IsAsan()) chunk *= 8;
58-
addr = kMemtrackFdsStart + size;
59-
prot = PROT_READ | PROT_WRITE;
60-
flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED;
61-
dm = sys_mmap((char *)addr, chunk, prot, flags, -1, 0);
62-
TrackMemoryInterval(&_mmi, addr >> 16, (addr + chunk - 1) >> 16, dm.maphandle,
63-
prot, flags, false, false, 0, chunk);
64-
if (IsAsan()) {
65-
addr = (addr >> 3) + 0x7fff8000;
66-
dm = sys_mmap((char *)addr, FRAMESIZE, prot, flags, -1, 0);
67-
TrackMemoryInterval(&_mmi, addr >> 16, addr >> 16, dm.maphandle, prot,
68-
flags, false, false, 0, FRAMESIZE);
69-
}
70-
if (!size) {
71-
g_fds.p = memcpy((char *)kMemtrackFdsStart, g_fds.__init_p,
72-
sizeof(g_fds.__init_p));
73-
}
74-
g_fds.n = (size + chunk) / sizeof(*g_fds.p);
75-
mapsize = size + chunk;
52+
g_fds.n = fd + 1;
53+
g_fds.e =
54+
_extend(g_fds.p, g_fds.n * sizeof(*g_fds.p), g_fds.e, 0x6ff000000000);
7655
return fd;
7756
}
7857

libc/calls/sig2.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
1717
│ PERFORMANCE OF THIS SOFTWARE. │
1818
╚─────────────────────────────────────────────────────────────────────────────*/
19+
#include "libc/calls/calls.h"
1920
#include "libc/calls/sig.internal.h"
2021
#include "libc/calls/state.internal.h"
2122
#include "libc/calls/strace.internal.h"

libc/calls/struct/fd.internal.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,9 @@ struct Fd {
2525
};
2626

2727
struct Fds {
28-
int f; /* lowest free slot */
29-
size_t n; /* monotonic capacity */
30-
struct Fd *p;
31-
struct Fd __init_p[OPEN_MAX];
28+
int f; /* lowest free slot */
29+
size_t n;
30+
struct Fd *p, *e;
3231
};
3332

3433
COSMOPOLITAN_C_END_

libc/integral/normalize.inc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@
6767
#endif
6868

6969
/* TODO(jart): Remove this in favor of GetStackSize() */
70-
#if defined(COSMO) && defined(MODE_DBG)
71-
#define STACKSIZE 131072 /* 128kb stack */
70+
#if defined(COSMO) && (defined(MODE_DBG) || defined(__SANITIZE_ADDRESS__))
71+
#define STACKSIZE 262144 /* 256kb stack */
7272
#elif defined(COSMO)
7373
#define STACKSIZE 65536 /* 64kb stack */
7474
#else
File renamed without changes.

0 commit comments

Comments
 (0)