Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions libc/config/linux/aarch64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.unistd.fsync
libc.src.unistd.ftruncate
libc.src.unistd.getcwd
libc.src.unistd.getentropy
libc.src.unistd.geteuid
libc.src.unistd.getpid
libc.src.unistd.getppid
Expand Down
1 change: 1 addition & 0 deletions libc/config/linux/x86_64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.unistd.fsync
libc.src.unistd.ftruncate
libc.src.unistd.getcwd
libc.src.unistd.getentropy
libc.src.unistd.geteuid
libc.src.unistd.getpid
libc.src.unistd.getppid
Expand Down
3 changes: 3 additions & 0 deletions libc/config/windows/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ set(TARGET_LIBC_ENTRYPOINTS
# time.h entrypoints
libc.src.time.time
libc.src.time.clock_getres

# unistd.h entrypoints
libc.src.unistd.getentropy
)

set(TARGET_LIBM_ENTRYPOINTS
Expand Down
1 change: 1 addition & 0 deletions libc/config/windows/headers.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ set(TARGET_PUBLIC_HEADERS
libc.include.errno
libc.include.fenv
libc.include.math
libc.include.unistd
)
7 changes: 7 additions & 0 deletions libc/include/sys/random.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,10 @@ functions:
- type: void *
- type: size_t
- type: unsigned int
- name: getentropy
standards:
- GNUExtensions
return_type: int
arguments:
- type: void *
- type: size_t
7 changes: 7 additions & 0 deletions libc/include/unistd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,13 @@ functions:
arguments:
- type: char *
- type: size_t
- name: getentropy
standards:
- GNUExtensions
return_type: int
arguments:
- type: void *
- type: size_t
- name: geteuid
standards:
- POSIX
Expand Down
2 changes: 1 addition & 1 deletion libc/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ add_subdirectory(string)
add_subdirectory(strings)
add_subdirectory(wchar)
add_subdirectory(time)
add_subdirectory(unistd)

if(${LIBC_TARGET_OS} STREQUAL "linux")
add_subdirectory(dirent)
Expand All @@ -23,7 +24,6 @@ if(${LIBC_TARGET_OS} STREQUAL "linux")
add_subdirectory(sched)
add_subdirectory(sys)
add_subdirectory(termios)
add_subdirectory(unistd)
endif()

if(NOT LLVM_LIBC_FULL_BUILD)
Expand Down
7 changes: 7 additions & 0 deletions libc/src/unistd/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -350,3 +350,10 @@ add_entrypoint_object(
DEPENDS
libc.src.__support.threads.identifier
)

add_entrypoint_object(
getentropy
ALIAS
DEPENDS
.${LIBC_TARGET_OS}.getentropy
)
19 changes: 19 additions & 0 deletions libc/src/unistd/getentropy.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//===-- Implementation header for getentropy ------------------------------===//
//
// 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 "hdr/types/size_t.h"
#include "src/__support/common.h"

#ifndef LLVM_LIBC_SRC_UNISTD_GETENTROPY_H
#define LLVM_LIBC_SRC_UNISTD_GETENTROPY_H

namespace LIBC_NAMESPACE_DECL {
int getentropy(void *buffer, size_t length);
}

#endif // LLVM_LIBC_SRC_UNISTD_GETENTROPY_H
15 changes: 15 additions & 0 deletions libc/src/unistd/linux/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -570,3 +570,18 @@ add_entrypoint_object(
libc.src.__support.OSUtil.osutil
libc.src.errno.errno
)

add_entrypoint_object(
getentropy
SRCS
getentropy.cpp
HDRS
../getentropy.h
DEPENDS
libc.hdr.types.size_t
libc.hdr.types.ssize_t
libc.hdr.errno_macros
libc.include.sys_syscall
libc.src.__support.OSUtil.osutil
libc.src.errno.errno
)
51 changes: 51 additions & 0 deletions libc/src/unistd/linux/getentropy.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//===-- Linux implementation of getentropy --------------------------------===//
//
// 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/unistd/getentropy.h"
#include "hdr/errno_macros.h"
#include "src/__support/OSUtil/syscall.h"
#include "src/__support/common.h"
#include "src/errno/libc_errno.h"

#include <sys/syscall.h> // For syscall numbers.

namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(int, getentropy, (void *buffer, size_t length)) {
// check the length limit
if (length > 256) {
libc_errno = EIO;
return -1;
}

char *cursor = static_cast<char *>(buffer);
while (length != 0) {
// 0 flag means urandom and blocking, which meets the assumption of
// getentropy
auto ret = syscall_impl<long>(SYS_getrandom, cursor, length, 0);

// on success, advance the buffer pointer
if (ret >= 0) {
length -= static_cast<size_t>(ret);
cursor += ret;
continue;
}

auto error = -static_cast<int>(ret);

// on EINTR, try again
if (error == EINTR)
continue;

// on ENOSYS, forward errno and exit;
// otherwise, set EIO and exit
libc_errno = (error == ENOSYS) ? ENOSYS : EIO;
return -1;
}
return 0;
}
} // namespace LIBC_NAMESPACE_DECL
11 changes: 11 additions & 0 deletions libc/src/unistd/windows/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
add_entrypoint_object(
getentropy
SRCS
getentropy.cpp
HDRS
../getentropy.h
DEPENDS
libc.hdr.types.size_t
libc.hdr.errno_macros
libc.src.errno.errno
)
42 changes: 42 additions & 0 deletions libc/src/unistd/windows/getentropy.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//===-- Windows implementation of getentropy ------------------------------===//
//
// 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/unistd/getentropy.h"
#include "hdr/errno_macros.h"
#include "src/__support/common.h"
#include "src/errno/libc_errno.h"

#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <bcrypt.h>
#include <ntstatus.h>
#pragma comment(lib, "bcrypt.lib")

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(int, getentropy, (void *buffer, size_t length)) {
__try {
// check the length limit
if (length > 256)
__leave;

NTSTATUS result = ::BCryptGenRandom(nullptr, static_cast<PUCHAR>(buffer),
static_cast<ULONG>(length),
BCRYPT_USE_SYSTEM_PREFERRED_RNG);

if (result == STATUS_SUCCESS)
return 0;

} __except (EXCEPTION_EXECUTE_HANDLER) {
// no need to handle exceptions specially
}

libc_errno = EIO;
return -1;
}
} // namespace LIBC_NAMESPACE_DECL
2 changes: 1 addition & 1 deletion libc/test/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ add_subdirectory(string)
add_subdirectory(strings)
add_subdirectory(wchar)
add_subdirectory(time)
add_subdirectory(unistd)

# Depends on utilities in stdlib
add_subdirectory(inttypes)
Expand All @@ -70,7 +71,6 @@ if(${LIBC_TARGET_OS} STREQUAL "linux")
add_subdirectory(sched)
add_subdirectory(sys)
add_subdirectory(termios)
add_subdirectory(unistd)
endif()

if(NOT LLVM_LIBC_FULL_BUILD)
Expand Down
12 changes: 12 additions & 0 deletions libc/test/src/unistd/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,18 @@ add_libc_test(
libc.src.stdio.fflush
)

add_libc_test(
getentropy_test
SUITE
libc_unistd_unittests
SRCS
getentropy_test.cpp
DEPENDS
libc.src.unistd.getentropy
libc.src.errno.errno
libc.test.UnitTest.ErrnoSetterMatcher
)

if(LLVM_LIBC_FULL_BUILD)
add_libc_test(
_exit_test
Expand Down
28 changes: 28 additions & 0 deletions libc/test/src/unistd/getentropy_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//===-- Unittests for getentropy ------------------------------------------===//
//
// 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 "hdr/errno_macros.h"
#include "src/unistd/getentropy.h"
#include "test/UnitTest/ErrnoSetterMatcher.h"
#include "test/UnitTest/Test.h"

using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;

TEST(LlvmLibcUnistdGetEntropyTest, LengthTooLong) {
char buf[1024];
ASSERT_THAT(LIBC_NAMESPACE::getentropy(buf, 257), Fails(EIO));
}

TEST(LlvmLibcUnistdGetEntropyTest, SmokeTest) {
char buf[256];
ASSERT_THAT(LIBC_NAMESPACE::getentropy(buf, 256), Succeeds());
}

TEST(LlvmLibcUnistdGetEntropyTest, OtherError) {
ASSERT_THAT(LIBC_NAMESPACE::getentropy(nullptr, 1), Fails(EIO));
}
Loading