Serenity Operating System
1/*
2 * Copyright (c) 2022, Peter Elliott <pelliott@serenityos.org>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include <LibTest/TestCase.h>
8
9#include <mallocdefs.h>
10#include <stdlib.h>
11
12static constexpr size_t runs = 5000;
13static constexpr size_t ptrs_per_run = 20;
14
15static size_t random_alignment()
16{
17 return 1 << (rand() % 16);
18}
19
20static size_t random_size()
21{
22 int r = rand() % num_size_classes;
23 if (r == num_size_classes - 1) {
24 return rand() % (1 << 17);
25 }
26
27 return size_classes[r] + (rand() % (size_classes[r + 1] - size_classes[r]));
28}
29
30static bool is_aligned(void* ptr, size_t align)
31{
32 return (reinterpret_cast<uintptr_t>(ptr) & (align - 1)) == 0;
33}
34
35TEST_CASE(posix_memalign_fuzz)
36{
37 EXPECT_NO_CRASH("posix_memalign should not crash under regular use", [] {
38 for (size_t i = 0; i < runs; ++i) {
39 size_t align = random_alignment();
40 size_t size = random_size();
41
42 for (size_t j = 0; j < 2; ++j) {
43 void* ptrs[ptrs_per_run];
44
45 for (size_t k = 0; k < ptrs_per_run; ++k) {
46 EXPECT_EQ(posix_memalign(&(ptrs[k]), align, size), 0);
47 EXPECT(is_aligned(ptrs[k], align));
48 }
49 for (size_t k = 0; k < ptrs_per_run; ++k) {
50 free(ptrs[k]);
51 }
52 }
53 }
54
55 return Test::Crash::Failure::DidNotCrash;
56 });
57}
58
59TEST_CASE(posix_memalign_not_power2)
60{
61 char secret_ptr[0];
62 void* memptr = secret_ptr;
63 EXPECT_EQ(posix_memalign(&memptr, 7, 256), EINVAL);
64 EXPECT_EQ(memptr, secret_ptr);
65}
66
67TEST_CASE(aligned_alloc_fuzz)
68{
69 EXPECT_NO_CRASH("aligned_alloc should not crash under regular use", [] {
70 for (size_t i = 0; i < runs; ++i) {
71 size_t align = random_alignment();
72 size_t size = random_size();
73
74 for (size_t j = 0; j < 2; ++j) {
75 void* ptrs[ptrs_per_run];
76
77 for (size_t k = 0; k < ptrs_per_run; ++k) {
78 ptrs[k] = aligned_alloc(align, size);
79 EXPECT(ptrs[k]);
80 EXPECT(is_aligned(ptrs[k], align));
81 }
82 for (size_t k = 0; k < ptrs_per_run; ++k) {
83 free(ptrs[k]);
84 }
85 }
86 }
87
88 return Test::Crash::Failure::DidNotCrash;
89 });
90}
91
92TEST_CASE(aligned_alloc_not_power2)
93{
94#if defined(AK_COMPILER_CLANG)
95# pragma clang diagnostic push
96# pragma clang diagnostic ignored "-Wnon-power-of-two-alignment"
97#endif
98 EXPECT_EQ(aligned_alloc(7, 256), nullptr);
99 EXPECT_EQ(errno, EINVAL);
100#if defined(AK_COMPILER_CLANG)
101# pragma clang diagnostic pop
102#endif
103}