[libc-commits] [libc] [libc] implement secure random buffer filling with vDSO (PR #109870)
Schrodinger ZHU Yifan via libc-commits
libc-commits at lists.llvm.org
Wed Oct 2 15:23:19 PDT 2024
================
@@ -0,0 +1,363 @@
+//===- Linux implementation of secure random buffer generation --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#include "src/__support/OSUtil/linux/cprng.h"
+#include "src/__support/CPP/atomic.h"
+#include "src/__support/CPP/mutex.h"
+#include "src/__support/CPP/new.h"
+#include "src/__support/OSUtil/linux/syscall.h"
+#include "src/__support/OSUtil/linux/vdso.h"
+#include "src/__support/block.h"
+#include "src/__support/libc_assert.h"
+#include "src/__support/threads/callonce.h"
+#include "src/__support/threads/linux/raw_mutex.h"
+#include "src/sched/sched_getaffinity.h"
+#include "src/sched/sched_getcpucount.h"
+#include "src/sys/mman/mmap.h"
+#include "src/sys/mman/munmap.h"
+#include "src/unistd/sysconf.h"
+
+extern "C" int __cxa_thread_atexit_impl(void (*)(void *), void *, void *);
+extern "C" int __cxa_atexit(void (*)(void *), void *, void *);
+extern "C" [[gnu::weak, gnu::visibility("hidden")]] void *__dso_handle =
+ nullptr;
+
+namespace LIBC_NAMESPACE_DECL {
+namespace cprng {
+namespace {
+
+using namespace vdso;
+// A block of random state together with enough space to hold all its freelist.
+// ┌───────────┬────────────┐
+// │ │ │
+// │ │ Pages ├──────────────┐
+// │ │ │ ▼
+// │ Prev ├────────────┤ ┌──────────────────┐
+// │ │ │ │ │
+// │ │ State0 ├───►│ Opaque Area │
+// │ │ │ │ │
+// │ ├────────────┤ ├──────────────────┤
+// ├───────────┤ │ │ │
+// │ │ State1 ├───►│ Opaque Area │
+// │ │ │ │ │
+// │ ├────────────┤ ├──────────────────┤
+// │ Next │ │ │ │
+// │ │ State2 ├───►│ Opaque Area │
+// │ │ │ │ │
+// │ ├────────────┤ ├──────────────────┤
+// │ │ ...... │ │ .............. │
+// └───────────┴────────────┘ └──────────────────┘
+// State blocks are doubly linked so that we can iterate bidrectionally as a
+// freelist. We'will use a sentinel to simplify the implementation.
+struct StateBlock {
+ StateBlock *prev;
+ StateBlock *next;
+ void *appendix[0];
+ void *&pages() { return appendix[0]; }
+ void *&freelist(size_t index) { return appendix[index + 1]; }
+};
----------------
SchrodingerZhu wrote:
We need a separate freelist here. We need the freelist size always to be capable of holding all blocks inside an allocation, which is a dynamically sized here.
https://github.com/llvm/llvm-project/pull/109870
More information about the libc-commits
mailing list