• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 "napi/native_api.h"
17 #include <cerrno>
18 #include <cstdio>
19 #include <cstring>
20 #include <fcntl.h>
21 #include <ifaddrs.h>
22 #include <js_native_api.h>
23 #include <js_native_api_types.h>
24 #include <malloc.h>
25 #include <net/if.h>
26 #include <node_api.h>
27 #include <sys/inotify.h>
28 #include <sys/mman.h>
29 #include <sys/stat.h>
30 #include <unistd.h>
31 #include <utmp.h>
32 #include <uv.h>
33 
34 #define PARAM_1 1
35 #define PARAM_2 2
36 #define PARAM_UNNORMAL (-1)
37 #define RETURN_0 0
38 #define FAILD (-1)
39 #define ERRON_0 0
40 #define SIZE_10 10
41 #define SIZE_32 32
42 #define SIZE_0x0 0x0
43 #define SIZE_4096 4096
44 #define SIZE_100 100
45 #define SIZE_4096 4096
46 #define SIZE_0L 0L
47 #define SIZE_8 8
48 #define SIZE_8192 8192
49 #define NO_ERR 0
50 #define SUCCESS 1
51 #define FAIL (-1)
52 #define PARAM_0 0
53 #define TEN 10
54 #define STATERROR (-100)
55 #define OPENERROR (-99)
56 #define MMAPERROR (-98)
57 #define TEST_SIZE 4096
58 #define TEST_M_SIZE 1024
59 #define TEST_M_NEW_SIZE 2048
60 #define TEST_MS_SIZE 1024
61 #define TEST_MODE 0666
62 #define TEST_FLAG 0777
63 #include <sys/mman.h>
64 
MemfdCreate(napi_env env,napi_callback_info info)65 static napi_value MemfdCreate(napi_env env, napi_callback_info info)
66 {
67     char tmpfile[] = "/data/storage/el2/base/files/memfd_create_0100.txt";
68     int retVal = PARAM_0;
69     int fd = memfd_create(tmpfile, PARAM_0);
70     if (fd != PARAM_UNNORMAL) {
71         size_t cnt = write(fd, tmpfile, strlen(tmpfile));
72         if (cnt == strlen(tmpfile)) {
73             retVal = PARAM_0;
74         } else {
75             retVal = FAIL;
76         }
77         close(fd);
78     }
79     napi_value result = nullptr;
80     napi_create_int32(env, retVal, &result);
81     return result;
82 }
Mincore(napi_env env,napi_callback_info info)83 static napi_value Mincore(napi_env env, napi_callback_info info)
84 {
85     struct stat st;
86     int retVal = PARAM_0;
87     napi_value result = nullptr;
88     char tmpfile[] = "/data/storage/el2/base/files/memfd_create_0100.txt";
89     int fd = open(tmpfile, O_CREAT | O_RDWR);
90     if (fd == PARAM_UNNORMAL) {
91         perror("open failed");
92         napi_create_int32(env, OPENERROR, &result);
93         return result;
94     }
95     void *start = mmap(nullptr, st.st_size, PROT_READ, MAP_PRIVATE, fd, PARAM_0);
96     close(fd);
97     if (!start) {
98         napi_create_int32(env, MMAPERROR, &result);
99         return result;
100     }
101     unsigned char vec[TEST_SIZE];
102     memset(vec, SIZE_0x0, sizeof(vec));
103     retVal = mincore(start, TEST_SIZE, vec);
104     munmap(start, st.st_size);
105     remove(tmpfile);
106     napi_create_int32(env, retVal, &result);
107     return result;
108 }
109 
110 #define PAGE_SIZE 256
Mmap(napi_env env,napi_callback_info info)111 static napi_value Mmap(napi_env env, napi_callback_info info)
112 {
113     char ptr[] = "/data/storage/el2/base/files/mmap0100.txt";
114     int retVal = PARAM_0;
115     int fd;
116     void *start;
117     FILE *fptr = fopen(ptr, "w+");
118     struct stat statbuff;
119     fwrite(ptr, sizeof(char), strlen(ptr), fptr);
120     fseek(fptr, SIZE_0L, SEEK_SET);
121     stat(ptr, &statbuff);
122     fclose(fptr);
123     fd = open(ptr, O_RDWR | O_CREAT, TEST_FLAG);
124     start = mmap(nullptr, statbuff.st_size, PROT_READ, MAP_PRIVATE, fd, PARAM_0);
125     if (start == MAP_FAILED) {
126         retVal = FAIL;
127     } else {
128         retVal = PARAM_0;
129     }
130     munmap(start, statbuff.st_size);
131     close(fd);
132     remove(ptr);
133     fptr = nullptr;
134     napi_value result = nullptr;
135     napi_create_int32(env, retVal, &result);
136     return result;
137 }
138 
MProtect(napi_env env,napi_callback_info info)139 static napi_value MProtect(napi_env env, napi_callback_info info)
140 {
141     int retVal = FAIL;
142     size_t align = getpagesize();
143     void *buffer = memalign(align, SIZE_8 * align);
144     int ret = mprotect(buffer, getpagesize(), PROT_READ);
145     retVal = ret;
146     napi_value result = nullptr;
147     napi_create_int32(env, retVal, &result);
148     return result;
149 }
MreMap(napi_env env,napi_callback_info info)150 static napi_value MreMap(napi_env env, napi_callback_info info)
151 {
152     int retVal = FAIL;
153     char tmpfile[] = "/data/storage/el2/base/files/memfd_create_0100.txt";
154     int fd = open(tmpfile, O_CREAT | O_RDWR);
155     void *map = mmap(nullptr, TEST_M_SIZE, PROT_READ, MAP_SHARED, fd, PARAM_0);
156     void *map_new = mremap(map, TEST_M_SIZE, TEST_M_NEW_SIZE, MREMAP_MAYMOVE);
157 
158     munmap(map_new, TEST_M_NEW_SIZE);
159     close(fd);
160     if (!map_new) {
161         retVal = PARAM_1;
162     } else {
163         retVal = PARAM_0;
164     }
165     napi_value result = nullptr;
166     napi_create_int32(env, retVal, &result);
167     return result;
168 }
MSync(napi_env env,napi_callback_info info)169 static napi_value MSync(napi_env env, napi_callback_info info)
170 {
171     int retVal = FAIL;
172     char tmpfile[] = "/data/storage/el2/base/files/memfd_creat0100.txt";
173     int fd = open(tmpfile, O_CREAT | O_RDWR);
174     void *map = mmap(nullptr, TEST_MS_SIZE, PROT_READ, MAP_SHARED, fd, PARAM_0);
175     int ret = msync(map, TEST_MS_SIZE, MS_ASYNC);
176     munmap(map, TEST_MS_SIZE);
177     close(fd);
178     retVal = ret;
179     napi_value result = nullptr;
180     napi_create_int32(env, retVal, &result);
181     return result;
182 }
183 
MUnLock(napi_env env,napi_callback_info info)184 static napi_value MUnLock(napi_env env, napi_callback_info info)
185 {
186     int retVal = FAIL;
187     char *memory = static_cast<char *>(malloc(TEST_SIZE));
188     memset(memory, SIZE_0x0, TEST_SIZE);
189     int ret = mlock(memory, TEST_SIZE);
190     ret = munlock(memory, TEST_SIZE);
191     free(memory);
192     memory = nullptr;
193     retVal = ret;
194     napi_value result = nullptr;
195     napi_create_int32(env, retVal, &result);
196     return result;
197 }
198 
MUnLockAll(napi_env env,napi_callback_info info)199 static napi_value MUnLockAll(napi_env env, napi_callback_info info)
200 {
201     int ret = FAIL;
202     char *memory = static_cast<char *>(malloc(TEST_SIZE));
203     memset(memory, '\0', TEST_SIZE);
204     mlockall(MCL_CURRENT);
205     ret = munlockall();
206     free(memory);
207     memory = nullptr;
208     napi_value result = nullptr;
209     napi_create_int32(env, ret, &result);
210     return result;
211 }
212 
MAdvise(napi_env env,napi_callback_info info)213 static napi_value MAdvise(napi_env env, napi_callback_info info)
214 {
215     size_t length = SIZE_4096;
216     char path[] = "/data/storage/el2/base/files/memfd_creat0100.txt";
217     if (access(path, F_OK) == PARAM_0) {
218         remove(path);
219     }
220     int fd = open(path, O_RDWR | O_CREAT, TEST_MODE);
221     void *ptr = mmap(nullptr, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, PARAM_0);
222     int ret = madvise(ptr, length, MADV_NORMAL);
223     munmap(ptr, length);
224     close(fd);
225     if (access(path, F_OK) == PARAM_0) {
226         remove(path);
227     }
228     napi_value result = nullptr;
229     napi_create_int32(env, ret, &result);
230     return result;
231 }
232 
MLock(napi_env env,napi_callback_info info)233 static napi_value MLock(napi_env env, napi_callback_info info)
234 {
235     errno = ERRON_0;
236     size_t argc = PARAM_1;
237     napi_value args[1] = {nullptr};
238     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
239     int change;
240     size_t lenV = SIZE_32;
241     char *mem = static_cast<char *>(malloc(sizeof(char) * lenV));
242     int ret;
243     napi_get_value_int32(env, args[0], &change);
244     if (change == PARAM_0) {
245         ret = mlock(mem, lenV);
246         munlock(mem, lenV);
247     } else {
248         ret = mlock(nullptr, lenV);
249     }
250 
251     free(mem);
252 
253     napi_value result;
254     napi_create_int32(env, ret, &result);
255     return result;
256 }
257 
MLock2(napi_env env,napi_callback_info info)258 static napi_value MLock2(napi_env env, napi_callback_info info)
259 {
260     errno = ERRON_0;
261     size_t argc = PARAM_1;
262     napi_value args[1] = {nullptr};
263     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
264     int change;
265     size_t lenV = SIZE_32;
266     char *mem = static_cast<char *>(malloc(sizeof(char) * lenV));
267     int ret;
268     napi_get_value_int32(env, args[0], &change);
269     if (change == PARAM_0) {
270         ret = mlock2(mem, lenV, PARAM_0);
271         munlock(mem, lenV);
272     } else {
273         ret = mlock(nullptr, lenV);
274     }
275     free(mem);
276 
277     napi_value result;
278     napi_create_int32(env, ret, &result);
279     return result;
280 }
281 
MLockAll(napi_env env,napi_callback_info info)282 static napi_value MLockAll(napi_env env, napi_callback_info info)
283 {
284     errno = ERRON_0;
285     int ret;
286     ret = mlockall(MCL_FUTURE);
287     munlockall();
288     napi_value result;
289     napi_create_int32(env, ret, &result);
290     return result;
291 }
292 
Mmap64(napi_env env,napi_callback_info info)293 static napi_value Mmap64(napi_env env, napi_callback_info info)
294 {
295     int fd = open("/data/storage/el2/base/files/Fzl.txt", O_CREAT | O_RDWR);
296     void *pMap = (unsigned char *)mmap64(PARAM_0, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, PARAM_0);
297     napi_value result;
298     if (pMap == MAP_FAILED) {
299         napi_create_int32(env, PARAM_UNNORMAL, &result);
300     } else {
301         napi_create_int32(env, PARAM_0, &result);
302     }
303     close(fd);
304     return result;
305 }
Munmap(napi_env env,napi_callback_info info)306 static napi_value Munmap(napi_env env, napi_callback_info info)
307 {
308     size_t argc = PARAM_1;
309     napi_value args[1] = {nullptr};
310     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
311     double value;
312     napi_get_value_double(env, args[0], &value);
313     int fd = open("/data/storage/el2/base/files/test.txt", O_CREAT);
314     void *p = mmap(PARAM_0, value, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, fd, PARAM_0);
315     napi_value result = nullptr;
316     napi_create_double(env, munmap(p, value), &result);
317     close(fd);
318     return result;
319 }
RemapFilePages(napi_env env,napi_callback_info info)320 static napi_value RemapFilePages(napi_env env, napi_callback_info info)
321 {
322     char path[] = "/data/storage/el2/base/files/testRemapFilePages.txt";
323     char text[] = "test remap_file_pages";
324     int len = strlen(text);
325     size_t argc = PARAM_1;
326     napi_value args[1] = {nullptr};
327     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
328     int param;
329     napi_get_value_int32(env, args[0], &param);
330 
331     int ret;
332     int fd = open(path, O_CREAT | O_RDWR);
333     write(fd, text, len);
334     lseek(fd, PARAM_0, SEEK_SET);
335     char *start = static_cast<char *>(mmap(nullptr, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, PARAM_0));
336     if (param == PARAM_0) {
337         ret = remap_file_pages(start, TEST_SIZE, PARAM_0, PARAM_1, MAP_SHARED);
338     } else {
339         ret = remap_file_pages(start, len, PARAM_0, PARAM_1, MAP_SHARED);
340     }
341     munmap(start, len);
342     close(fd);
343     remove(path);
344 
345     napi_value result = nullptr;
346     napi_create_int32(env, ret, &result);
347     return result;
348 }
349 
350 EXTERN_C_START
Init(napi_env env,napi_value exports)351 static napi_value Init(napi_env env, napi_value exports)
352 {
353     napi_property_descriptor desc[] = {
354         {"remapFilePages", nullptr, RemapFilePages, nullptr, nullptr, nullptr, napi_default, nullptr},
355         {"memfdCreate", nullptr, MemfdCreate, nullptr, nullptr, nullptr, napi_default, nullptr},
356         {"mincore", nullptr, Mincore, nullptr, nullptr, nullptr, napi_default, nullptr},
357         {"mmap", nullptr, Mmap, nullptr, nullptr, nullptr, napi_default, nullptr},
358         {"mProtect", nullptr, MProtect, nullptr, nullptr, nullptr, napi_default, nullptr},
359         {"mreMap", nullptr, MreMap, nullptr, nullptr, nullptr, napi_default, nullptr},
360         {"mSync", nullptr, MSync, nullptr, nullptr, nullptr, napi_default, nullptr},
361         {"mUnLock", nullptr, MUnLock, nullptr, nullptr, nullptr, napi_default, nullptr},
362         {"mUnLockAll", nullptr, MUnLockAll, nullptr, nullptr, nullptr, napi_default, nullptr},
363         {"mAdvise", nullptr, MAdvise, nullptr, nullptr, nullptr, napi_default, nullptr},
364         {"mLock", nullptr, MLock, nullptr, nullptr, nullptr, napi_default, nullptr},
365         {"mLock2", nullptr, MLock2, nullptr, nullptr, nullptr, napi_default, nullptr},
366         {"mLockAll", nullptr, MLockAll, nullptr, nullptr, nullptr, napi_default, nullptr},
367         {"munmap", nullptr, Munmap, nullptr, nullptr, nullptr, napi_default, nullptr},
368         {"mmap64", nullptr, Mmap64, nullptr, nullptr, nullptr, napi_default, nullptr},
369     };
370     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
371     return exports;
372 }
373 
374 EXTERN_C_END
375 
376 static napi_module demoModule = {
377     .nm_version = 1,
378     .nm_flags = 0,
379     .nm_filename = nullptr,
380     .nm_register_func = Init,
381     .nm_modname = "mman",
382     .nm_priv = ((void *)0),
383     .reserved = {0},
384 };
385 
RegisterEntryModule(void)386 extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&demoModule); }
387