• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <gtest/gtest.h>
17 #include <fcntl.h>
18 #include <cinttypes>
19 #include <climits>
20 #include <cstdio>
21 #include <cstdlib>
22 #include <unistd.h>
23 #include <iomanip>
24 #include <iostream>
25 #include <string>
26 #include <vector>
27 #include <sys/mman.h>
28 #include <sys/utsname.h>
29 #include <string>
30 #include <regex>
31 #include "securec.h"
32 
33 #define PAGE_SIZE 4096
34 
35 
36 using namespace testing::ext;
37 using namespace std;
38 
39 class MadviseApiTest : public testing::Test {
40 public:
41     static void SetUpTestCase();
42     static void TearDownTestCase();
43     void SetUp();
44     void TearDown();
45 private:
46 };
SetUp()47 void MadviseApiTest::SetUp()
48 {
49 }
TearDown()50 void MadviseApiTest::TearDown()
51 {
52 }
SetUpTestCase()53 void MadviseApiTest::SetUpTestCase()
54 {
55 }
TearDownTestCase()56 void MadviseApiTest::TearDownTestCase()
57 {
58 }
59 
CreateFile()60 static void CreateFile()
61 {
62     FILE *file;
63     int ret = -1;
64     char *buffer =  static_cast<char *>(malloc(PAGE_SIZE));
65     if (buffer != nullptr) {
66         ret = memset_s(buffer, PAGE_SIZE, 'a', PAGE_SIZE);
67         ASSERT_TRUE(ret == 0);
68         file = fopen("output_file.txt", "wb");
69         if (fwrite(buffer, 1, PAGE_SIZE, file) != PAGE_SIZE) {
70             std::cout << "Error fwrite file.\n" << std::endl;
71             ASSERT_TRUE(ret != 0);
72         }
73         fclose(file);
74     }
75     free(buffer);
76 }
77 
78 /*
79  * @tc.number SUB_KERNEL_MEM_MADVISE_0100
80  * @tc.name   MadviseMadvCold001
81  * @tc.desc   MADV_COLD with MAP_PRIVATE
82 */
83 HWTEST_F(MadviseApiTest, MadviseMadvCold001, Function | MediumTest | Level1)
84 {
85     void *addr = mmap(nullptr, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
86     ASSERT_TRUE(addr != MAP_FAILED);
87     int err = madvise(addr, PAGE_SIZE, MADV_COLD);
88     ASSERT_TRUE(err == 0);
89     int ret = munmap(addr, PAGE_SIZE);
90     ASSERT_TRUE(ret == 0);
91     addr = nullptr;
92 }
93 
94 /*
95  * @tc.number SUB_KERNEL_MEM_MADVISE_0200
96  * @tc.name   MadviseMadvCold002
97  * @tc.desc   MADV_COLD with MAP_SHARED
98 */
99 HWTEST_F(MadviseApiTest, MadviseMadvCold002, Function | MediumTest | Level1)
100 {
101     CreateFile();
102     int fd = open("output_file.txt", O_RDWR);
103     ASSERT_TRUE(fd > 0);
104     void *addr = mmap(nullptr, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED | MAP_FILE, fd, 0);
105     ASSERT_TRUE(addr != MAP_FAILED);
106     int ret = madvise(addr, PAGE_SIZE, MADV_COLD);
107     ASSERT_TRUE(ret == 0);
108     ret = munmap(addr, PAGE_SIZE);
109     ASSERT_TRUE(ret == 0);
110     addr = nullptr;
111     close(fd);
112     ret = unlink("output_file.txt");
113     ASSERT_TRUE(ret == 0);
114     addr = nullptr;
115 }
116 
117 /*
118  * @tc.number SUB_KERNEL_MEM_MADVISE_0300
119  * @tc.name   MadviseMadvCold003
120  * @tc.desc   MADV_COLD with mlock MAP_PRIVATE FILE
121 */
122 HWTEST_F(MadviseApiTest, MadviseMadvCold003, Function | MediumTest | Level1)
123 {
124     CreateFile();
125     int fd = open("output_file.txt", O_RDWR);
126     ASSERT_TRUE(fd > 0);
127     void *addr = mmap(nullptr, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED | MAP_FILE, fd, 0);
128     ASSERT_TRUE(addr != MAP_FAILED);
129     int ret = mlock(addr, PAGE_SIZE);
130     ASSERT_TRUE(ret == 0);
131     ret = madvise(addr, PAGE_SIZE, MADV_COLD);
132     ASSERT_TRUE(ret == -1);
133     ret = munmap(addr, PAGE_SIZE);
134     ASSERT_TRUE(ret == 0);
135     addr = nullptr;
136     close(fd);
137     ret = unlink("output_file.txt");
138     ASSERT_TRUE(ret == 0);
139     addr = nullptr;
140 }
141 
142 /*
143  * @tc.number SUB_KERNEL_MEM_MADVISE_0400
144  * @tc.name   MadviseMadvCold004
145  * @tc.desc   MADV_COLD with mlock MAP_PRIVATE anon
146 */
147 HWTEST_F(MadviseApiTest, MadviseMadvCold004, Function | MediumTest | Level1)
148 {
149     void *addr = mmap(nullptr, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
150     ASSERT_TRUE(addr != MAP_FAILED);
151     int ret = mlock(addr, PAGE_SIZE);
152     ASSERT_TRUE(ret == 0);
153     ret = madvise(addr, PAGE_SIZE, MADV_COLD);
154     ASSERT_TRUE(ret == -1);
155     ret = munmap(addr, PAGE_SIZE);
156     ASSERT_TRUE(ret == 0);
157     addr = nullptr;
158 }
159 
160 /*
161  * @tc.number SUB_KERNEL_MEM_MADVISE_0500
162  * @tc.name MadviseMadvPageOut001
163  * @tc.desc MADV_PAGEOUT with  MAP_PRIVATE anon
164 */
165 HWTEST_F(MadviseApiTest, MadviseMadvPageOut001, Function | MediumTest | Level1)
166 {
167     int ret = -1;
168     void *addr = mmap(nullptr, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
169     ASSERT_TRUE(addr != MAP_FAILED);
170     ret = memset_s(addr, PAGE_SIZE, 'a', PAGE_SIZE);
171     ASSERT_TRUE(ret == 0);
172     ret = madvise(addr, PAGE_SIZE, MADV_PAGEOUT);
173     ASSERT_TRUE(ret == 0);
174     ret = munmap(addr, PAGE_SIZE);
175     ASSERT_TRUE(ret == 0);
176     addr = nullptr;
177 }
178 
179 /*
180  * @tc.number SUB_KERNEL_MEM_MADVISE_0600
181  * @tc.name MadviseMadvPageOut002
182  * @tc.desc MADV_PAGEOUT with  MAP_SHARED FILE
183 */
184 HWTEST_F(MadviseApiTest, MadviseMadvPageOut002, Function | MediumTest | Level1)
185 {
186     CreateFile();
187     int fd = open("output_file.txt", O_RDWR);
188     ASSERT_TRUE(fd > 0);
189     void *addr = mmap(nullptr, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED | MAP_FILE, fd, 0);
190     ASSERT_TRUE(addr != MAP_FAILED);
191     int ret = memset_s(addr, PAGE_SIZE, 'a', PAGE_SIZE);
192     ASSERT_TRUE(ret == 0);
193     ret = madvise(addr, PAGE_SIZE, MADV_PAGEOUT);
194     ASSERT_TRUE(ret == 0);
195     ret = munmap(addr, PAGE_SIZE);
196     ASSERT_TRUE(ret == 0);
197     close(fd);
198     ret = unlink("output_file.txt");
199     ASSERT_TRUE(ret == 0);
200     addr = nullptr;
201 }
202 
203 /*
204  * @tc.number SUB_KERNEL_MEM_MADVISE_0700
205  * @tc.name   MadviseMadvPageOut003
206  * @tc.desc   MADV_PAGEOUT with mlock MAP_SHARED FILE
207 */
208 HWTEST_F(MadviseApiTest, MadviseMadvPageOut003, Function | MediumTest | Level1)
209 {
210     CreateFile();
211     int fd = open("output_file.txt", O_RDWR);
212     ASSERT_TRUE(fd > 0);
213     void *addr = mmap(nullptr, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED | MAP_FILE, fd, 0);
214     ASSERT_TRUE(addr != MAP_FAILED);
215     int ret = memset_s(addr, PAGE_SIZE, 'a', PAGE_SIZE);
216     ASSERT_TRUE(ret == 0);
217     ret = mlock(addr, PAGE_SIZE);
218     ASSERT_TRUE(ret == 0);
219     ret = madvise(addr, PAGE_SIZE, MADV_PAGEOUT);
220     ASSERT_TRUE(ret == -1);
221     ret = munmap(addr, PAGE_SIZE);
222     ASSERT_TRUE(ret == 0);
223     close(fd);
224     ret = unlink("output_file.txt");
225     ASSERT_TRUE(ret == 0);
226     addr = nullptr;
227 }
228 
229 /*
230  * @tc.number SUB_KERNEL_MEM_MADVISE_0800
231  * @tc.name   MadviseMadvPageOut004
232  * @tc.desc   MADV_PAGEOUT with mlock MAP_PRIVATE anon
233 */
234 HWTEST_F(MadviseApiTest, MadviseMadvPageOut004, Function | MediumTest | Level1)
235 {
236     int ret = -2;
237     void *addr = mmap(nullptr, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
238     ASSERT_TRUE(addr != MAP_FAILED);
239     ret = memset_s(addr, PAGE_SIZE, 'a', PAGE_SIZE);
240     ASSERT_TRUE(ret == 0);
241     ret = mlock(addr, PAGE_SIZE);
242     ASSERT_TRUE(ret == 0);
243     ret = madvise(addr, PAGE_SIZE, MADV_PAGEOUT);
244     ASSERT_TRUE(ret == -1);
245     ret = munmap(addr, PAGE_SIZE);
246     ASSERT_TRUE(ret == 0);
247     addr = nullptr;
248 }
249 
250 /*
251  * @tc.number SUB_KERNEL_MEM_MADVISE_0900
252  * @tc.name   MadviseMadvWipeOnFork001
253  * @tc.desc   MADV_WIPEONFORK with  MAP_PRIVATE anon
254 */
255 HWTEST_F(MadviseApiTest, MadviseMadvWipeOnFork001, Function | MediumTest | Level1)
256 {
257     int status = 0;
258     char *addr = static_cast<char*>(mmap(nullptr, PAGE_SIZE, PROT_READ | PROT_WRITE,
259          MAP_ANONYMOUS | MAP_PRIVATE, -1, 0));
260     ASSERT_TRUE(addr != MAP_FAILED);
261     *addr = 'A';
262     int err = madvise(addr, PAGE_SIZE, MADV_WIPEONFORK);
263     ASSERT_TRUE(err == 0);
264     pid_t pid = fork();
265     ASSERT_TRUE(pid >= 0);
266     if (pid == 0)
267     {
268         ASSERT_TRUE(*addr == 0);
269         exit(0);
270     } else {
271         ASSERT_TRUE(*addr == 'A');
272         waitpid(0, &status, 0);
273     }
274     int ret = munmap(addr, PAGE_SIZE);
275     ASSERT_TRUE(ret == 0);
276     addr = nullptr;
277 }
278 
279 /*
280  * @tc.number  SUB_KERNEL_MEM_MADVISE_1000
281  * @tc.name    MadviseMadvWipeOnFork002
282  * @tc.desc    MADV_WIPEONFORK with  MAP_SHARED
283 */
284 HWTEST_F(MadviseApiTest, MadviseMadvWipeOnFork002, Function | MediumTest | Level1)
285 {
286     void *addr = mmap(nullptr, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1, 0);
287     ASSERT_TRUE(addr != MAP_FAILED);
288     int err = madvise(addr, PAGE_SIZE, MADV_WIPEONFORK);
289     ASSERT_TRUE(err == -1);
290     int ret = munmap(addr, PAGE_SIZE);
291     ASSERT_TRUE(ret == 0);
292     addr = nullptr;
293 }
294 
295 /*
296  * @tc.number SUB_KERNEL_MEM_MADVISE_1100
297  * @tc.name   MadviseMadvWipeOnFork003
298  * @tc.desc   MADV_KEEPONFORK after MADV_WIPEONFORK
299 */
300 HWTEST_F(MadviseApiTest, MadviseMadvWipeOnFork003, Function | MediumTest | Level1)
301 {
302     int status = 0;
303     char *addr = static_cast<char*>(mmap(nullptr, PAGE_SIZE, PROT_READ | PROT_WRITE,
304          MAP_ANONYMOUS | MAP_PRIVATE, -1, 0));
305     ASSERT_TRUE(addr != MAP_FAILED);
306     *addr = 'A';
307     int err = madvise(addr, PAGE_SIZE, MADV_WIPEONFORK);
308     ASSERT_TRUE(err == 0);
309     err = madvise(addr, PAGE_SIZE, MADV_KEEPONFORK);
310     ASSERT_TRUE(err == 0);
311     pid_t pid = fork();
312     ASSERT_TRUE(pid >= 0);
313     if (pid == 0)
314     {
315         ASSERT_TRUE(*addr == 'A');
316         exit(0);
317     } else {
318         ASSERT_TRUE(*addr == 'A');
319         waitpid(0, &status, 0);
320     }
321     int ret = munmap(addr, PAGE_SIZE);
322     ASSERT_TRUE(ret == 0);
323     addr = nullptr;
324 }
325 
326 /*
327  * @tc.number SUB_KERNEL_MEM_MADVISE_1200
328  * @tc.name   MadviseMadvWipeOnFork004
329  * @tc.desc   next vregion is no MADV_WIPEONFORK
330 */
331 HWTEST_F(MadviseApiTest, MadviseMadvWipeOnFork004, Function | MediumTest | Level1)
332 {
333     int status = 0;
334     char *addr = static_cast<char*>(mmap(nullptr, PAGE_SIZE, PROT_READ | PROT_WRITE,
335          MAP_ANONYMOUS | MAP_PRIVATE, -1, 0));
336     ASSERT_TRUE(addr != MAP_FAILED);
337     char *nextAddr = static_cast<char*>(mmap(addr, PAGE_SIZE, PROT_READ | PROT_WRITE,
338          MAP_ANONYMOUS | MAP_PRIVATE, -1, PAGE_SIZE));
339     ASSERT_TRUE(nextAddr != MAP_FAILED);
340     *addr = 'A';
341     *nextAddr = 'B';
342     int err = madvise(addr, PAGE_SIZE, MADV_WIPEONFORK);
343     ASSERT_TRUE(err == 0);
344     pid_t pid = fork();
345     ASSERT_TRUE(pid >= 0);
346     if (pid == 0)
347     {
348         ASSERT_TRUE(*addr == 0);
349         ASSERT_TRUE(*nextAddr == 'B');
350         exit(0);
351     } else {
352         ASSERT_TRUE(*addr == 'A');
353         ASSERT_TRUE(*nextAddr == 'B');
354         waitpid(0, &status, 0);
355     }
356     int ret = munmap(addr, PAGE_SIZE);
357     ASSERT_TRUE(ret == 0);
358     ret = munmap(nextAddr, PAGE_SIZE);
359     ASSERT_TRUE(ret == 0);
360     addr = nullptr;
361     nextAddr = nullptr;
362 }
363 
364 /*
365  * @tc.number SUB_KERNEL_MEM_MADVISE_1300
366  * @tc.name   MadviseMadvWipeOnFork005
367  * @tc.desc   next vregion is MADV_WIPEONFORK
368 */
369 HWTEST_F(MadviseApiTest, MadviseMadvWipeOnFork005, Function | MediumTest | Level1)
370 {
371     int status = 0;
372     char *addr = static_cast<char*>(mmap(nullptr, PAGE_SIZE, PROT_READ | PROT_WRITE,
373          MAP_ANONYMOUS | MAP_PRIVATE, -1, 0));
374     ASSERT_TRUE(addr != MAP_FAILED);
375     char *nextAddr = static_cast<char*>(mmap(addr, PAGE_SIZE, PROT_READ | PROT_WRITE,
376          MAP_ANONYMOUS | MAP_PRIVATE, -1, PAGE_SIZE));
377     ASSERT_TRUE(nextAddr != MAP_FAILED);
378     *addr = 'A';
379     *nextAddr = 'B';
380     int err = madvise(addr, PAGE_SIZE, MADV_WIPEONFORK);
381     ASSERT_TRUE(err == 0);
382     err = madvise(nextAddr, PAGE_SIZE, MADV_WIPEONFORK);
383     ASSERT_TRUE(err == 0);
384     pid_t pid = fork();
385     ASSERT_TRUE(pid >= 0);
386     if (pid == 0)
387     {
388         ASSERT_TRUE(*addr == 0);
389         ASSERT_TRUE(*nextAddr == 0);
390         exit(0);
391     } else {
392         ASSERT_TRUE(*addr == 'A');
393         ASSERT_TRUE(*nextAddr == 'B');
394         waitpid(0, &status, 0);
395     }
396     int ret = munmap(addr, PAGE_SIZE);
397     ASSERT_TRUE(ret == 0);
398     ret = munmap(nextAddr, PAGE_SIZE);
399     ASSERT_TRUE(ret == 0);
400     addr = nullptr;
401     nextAddr = nullptr;
402 }
403 
404 /*
405  * @tc.number SUB_KERNEL_MEM_MADVISE_1400
406  * @tc.name   MadviseMadvWipeOnFork006
407  * @tc.desc   next vregion is MADV_KEEPONFORK
408 */
409 HWTEST_F(MadviseApiTest, MadviseMadvWipeOnFork006, Function | MediumTest | Level1)
410 {
411     int status = 0;
412     char *addr = static_cast<char*>(mmap(nullptr, PAGE_SIZE, PROT_READ | PROT_WRITE,
413          MAP_ANONYMOUS | MAP_PRIVATE, -1, 0));
414     ASSERT_TRUE(addr != MAP_FAILED);
415     char *nextAddr = static_cast<char*>(mmap(addr, PAGE_SIZE, PROT_READ | PROT_WRITE,
416          MAP_ANONYMOUS | MAP_PRIVATE, -1, PAGE_SIZE));
417     ASSERT_TRUE(nextAddr != MAP_FAILED);
418     *addr = 'A';
419     *nextAddr = 'B';
420     int err = madvise(addr, PAGE_SIZE, MADV_WIPEONFORK);
421     ASSERT_TRUE(err == 0);
422     err = madvise(nextAddr, PAGE_SIZE, MADV_WIPEONFORK);
423     ASSERT_TRUE(err == 0);
424     err = madvise(addr, PAGE_SIZE, MADV_KEEPONFORK);
425     ASSERT_TRUE(err == 0);
426     err = madvise(nextAddr, PAGE_SIZE, MADV_KEEPONFORK);
427     ASSERT_TRUE(err == 0);
428     pid_t pid = fork();
429     ASSERT_TRUE(pid >= 0);
430     if (pid == 0)
431     {
432         ASSERT_TRUE(*addr == 'A');
433         ASSERT_TRUE(*nextAddr == 'B');
434         exit(0);
435     } else {
436         ASSERT_TRUE(*addr == 'A');
437         ASSERT_TRUE(*nextAddr == 'B');
438         waitpid(0, &status, 0);
439     }
440     int ret = munmap(addr, PAGE_SIZE);
441     ASSERT_TRUE(ret == 0);
442     ret = munmap(nextAddr, PAGE_SIZE);
443     ASSERT_TRUE(ret == 0);
444     addr = nullptr;
445     nextAddr = nullptr;
446 }