Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/tests/sys/sound/mmap.c
288955 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2026 The FreeBSD Foundation
5
*/
6
7
#include <sys/param.h>
8
#include <sys/mman.h>
9
#include <sys/soundcard.h>
10
11
#include <atf-c.h>
12
#include <errno.h>
13
#include <fcntl.h>
14
#include <string.h>
15
#include <unistd.h>
16
17
#define FMT_ERR(s) s ": %s", strerror(errno)
18
19
ATF_TC(mmap_offset_overflow);
20
ATF_TC_HEAD(mmap_offset_overflow, tc)
21
{
22
atf_tc_set_md_var(tc, "descr", "mmap offset overflow test");
23
atf_tc_set_md_var(tc, "require.kmods", "snd_dummy");
24
}
25
26
ATF_TC_BODY(mmap_offset_overflow, tc)
27
{
28
uint8_t *buf;
29
off_t off;
30
size_t len;
31
int fd;
32
33
fd = open("/dev/dsp.dummy", O_RDWR);
34
ATF_REQUIRE_MSG(fd >= 0, FMT_ERR("open"));
35
36
/* off + len will overflow and wrap back to 0. */
37
off = 0xfffffffffffff000;
38
len = 0x1000;
39
40
buf = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, off);
41
ATF_REQUIRE_MSG(buf == MAP_FAILED, FMT_ERR("mmap"));
42
43
munmap(buf, len);
44
45
close(fd);
46
}
47
48
/*
49
* Verify that a MAP_SHARED mapping of a DSP device's software buffer remains
50
* valid after the file descriptor is closed.
51
*/
52
ATF_TC(mmap_buffer_lifetime);
53
ATF_TC_HEAD(mmap_buffer_lifetime, tc)
54
{
55
atf_tc_set_md_var(tc, "descr", "mmap data survives close()");
56
atf_tc_set_md_var(tc, "require.kmods", "snd_dummy");
57
}
58
ATF_TC_BODY(mmap_buffer_lifetime, tc)
59
{
60
audio_buf_info abi;
61
uint8_t *buf;
62
size_t len;
63
int fd, arg;
64
65
fd = open("/dev/dsp.dummy", O_RDWR);
66
ATF_REQUIRE_MSG(fd >= 0, FMT_ERR("open"));
67
68
arg = (2 << 16) | 14; /* 2*16KB */
69
ATF_REQUIRE_MSG(ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &arg) == 0,
70
FMT_ERR("SNDCTL_DSP_SETFRAGMENT"));
71
ATF_REQUIRE_MSG(ioctl(fd, SNDCTL_DSP_GETOSPACE, &abi) == 0,
72
FMT_ERR("SNDCTL_DSP_GETOSPACE"));
73
74
len = abi.bytes;
75
ATF_REQUIRE_MSG(len >= PAGE_SIZE, "buffer too small: %zu", len);
76
77
buf = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
78
ATF_REQUIRE_MSG(buf != MAP_FAILED, FMT_ERR("mmap"));
79
80
for (size_t i = 0; i < len; i++) {
81
ATF_REQUIRE_MSG(buf[i] == 0,
82
"mmap data corrupted at offset %zu: want 0 got 0x%02x",
83
i, buf[i]);
84
}
85
86
memset(buf, 0xa5, len);
87
for (size_t i = 0; i < len; i++) {
88
ATF_REQUIRE_MSG(buf[i] == 0xa5,
89
"mmap data corrupted at offset %zu: want 0xa5 got 0x%02x",
90
i, buf[i]);
91
}
92
93
ATF_REQUIRE(close(fd) == 0);
94
95
/* Closing the device causes the buffer to be reset. */
96
for (size_t i = 0; i < len; i++) {
97
ATF_REQUIRE_MSG(buf[i] == 0 || buf[i] == 0xa5,
98
"mmap data corrupted at offset %zu: got 0x%02x", i, buf[i]);
99
}
100
memset(buf, 0xa5, len);
101
102
ATF_REQUIRE(munmap(buf, len) == 0);
103
}
104
105
ATF_TP_ADD_TCS(tp)
106
{
107
ATF_TP_ADD_TC(tp, mmap_offset_overflow);
108
ATF_TP_ADD_TC(tp, mmap_buffer_lifetime);
109
110
return (atf_no_error());
111
}
112
113