Files
Alastair Houghton cc0fb6e4da [Backtracing] Avoid TOCTOU races during backtracing on Linux.
On Linux, if one thread generates a backtrace while another is busy
unmapping a file, the memory map can change after the backtracer's code
has read it, which then means that the backtracer can crash attempting
to access memory while it is trying to enumerate loaded images.

Fix by changing the way we read memory on Linux so that by default,
we do so in a failable manner.

Fixes #92089

rdar://186982100
2026-09-17 10:50:35 +01:00

55 lines
1.6 KiB
C++

//===--- SafeReadMemory.h - Safe memory reading (POSIX) ---------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2026 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// Safely read from the current process's memory.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_SAFEREADMEMORY_H_
#define SWIFT_SAFEREADMEMORY_H_
#ifdef __linux__
#include <setjmp.h>
#include <signal.h>
#include <string.h>
struct _swift_read_memory_context {
bool reading;
struct sigaction sa_old_segv;
struct sigaction sa_old_bus;
sigjmp_buf fault_buf;
};
typedef struct _swift_read_memory_context *swift_read_memory_context_t;
/* Retrieve the context for the current thread */
extern "C" swift_read_memory_context_t _swift_begin_reading_memory(void);
static inline bool _swift_read_memory(swift_read_memory_context_t ctx,
const void *from,
void *to,
size_t length) {
if (!sigsetjmp(ctx->fault_buf, 1)) {
memcpy(to, from, length);
return true;
}
return false;
}
/* Release the context */
extern "C" void _swift_end_reading_memory(swift_read_memory_context_t ctx);
#endif // __linux__
#endif // SWIFT_SAFEREADMEMORY_H_