forked from luainkernel/lunatik
-
Notifications
You must be signed in to change notification settings - Fork 0
/
lunatik_aux.c
96 lines (75 loc) · 2.26 KB
/
lunatik_aux.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/*
* SPDX-FileCopyrightText: (c) 2023-2024 Ring Zero Desenvolvimento de Software LTDA
* SPDX-License-Identifier: MIT OR GPL-2.0-only
*/
#include <linux/slab.h>
#include <linux/fs.h>
#include <lua.h>
#include <lauxlib.h>
#include <lunatik.h>
typedef struct lunatik_file {
struct file *file;
char *buffer;
loff_t pos;
} lunatik_file;
static const char *lunatik_loader(lua_State *L, void *ud, size_t *size)
{
lunatik_file *lf = (lunatik_file *)ud;
ssize_t ret = kernel_read(lf->file, lf->buffer, PAGE_SIZE, &(lf->pos));
if (unlikely(ret < 0))
luaL_error(L, "kernel_read failure %I", (lua_Integer)ret);
*size = (size_t)ret;
return lf->buffer;
}
int lunatik_loadfile(lua_State *L, const char *filename, const char *mode)
{
lunatik_file lf = {NULL, NULL, 0};
int status = LUA_ERRFILE;
int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */
if (unlikely(lunatik_cannotsleep(L, lunatik_isready(L)))) {
lua_pushfstring(L, "cannot load file on non-sleepable runtime");
goto error;
}
if (unlikely(filename == NULL) || IS_ERR(lf.file = filp_open(filename, O_RDONLY, 0600))) {
lua_pushfstring(L, "cannot open %s", filename);
goto error;
}
lf.buffer = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (lf.buffer == NULL) {
lua_pushfstring(L, "cannot allocate buffer for %s", filename);
goto close;
}
lua_pushfstring(L, "@%s", filename);
status = lua_load(L, lunatik_loader, &lf, lua_tostring(L, -1), mode);
lua_remove(L, fnameindex);
kfree(lf.buffer);
close:
filp_close(lf.file, NULL);
error:
return status;
}
EXPORT_SYMBOL(lunatik_loadfile);
#ifdef MODULE /* see https://lwn.net/Articles/813350/ */
#include <linux/kprobes.h>
static unsigned long (*__lunatik_lookup)(const char *) = NULL;
void *lunatik_lookup(const char *symbol)
{
#ifdef CONFIG_KPROBES
if (__lunatik_lookup == NULL) {
struct kprobe kp = {.symbol_name = "kallsyms_lookup_name"};
if (register_kprobe(&kp) != 0)
return NULL;
__lunatik_lookup = (unsigned long (*)(const char *))kp.addr;
unregister_kprobe(&kp);
BUG_ON(__lunatik_lookup == NULL);
}
return (void *)__lunatik_lookup(symbol);
#else /* CONFIG_KPROBES */
return NULL;
#endif /* CONFIG_KPROBES */
}
EXPORT_SYMBOL(lunatik_lookup);
#endif /* MODULE */
/* used by lib/luarcu.c */
#include <lua/lstring.h>
EXPORT_SYMBOL(luaS_hash);