Published on

如何给lua锁定so文件

前段时间在考虑一个问题,如何给lua锁定so, 也就是lua虚拟机无法引用不是我编译的so文件。

今天刚有空写一个记录,

灵感来源于很早之前,那会在看lua源码,看到luaL_checkversion函数的时候,我就在想,如果我在这个函数注入一个TOKEN,那么,每次检查的时候,如果TOKEN和我不一样,就会打开失败。

最近因为某种原因要做这个事情,重新考虑了一下这个事情,当时想的是不对的,因为是否调用luaL_checkversion,是写luaclib的人决定的,所以这里无法做到。

那么换一种方式呢,编译的时候,我用-D注入一个宏TOKEN,然后给需要的文件编入一个auth函数,那么,我就可以在lua源码里,打开lib的入口处,用lsys_sym获取函数,做token检查。

那么,就能做到只要auth校验不过,就拒绝打开luaclib

static int lookforfunc (lua_State *L, const char *path, const char *sym) {
    //...
    lua_CFunction f_auth = lsys_sym(L, reg, "auth_function");
    
    if (f_auth == NULL) {
        lua_pop(L, 1);
        lsys_unloadlib(reg);
        lua_pushstring(L, "Security Error: Missing authorization interface.");
        return ERRLIB;
    }
    const char* (*get_token)(void) = (const char* (*)(void))f_auth;
    const char* plugin_token = get_token();
    const char* host_token = TOKEN;
    if (strcmp(plugin_token, host_token) != 0) {
      lsys_unloadlib(reg);
      return ERRLIB;
    }
    //...
}

skynet里面的c服务也同理

static void *
_try_open(struct modules *m, const char * name) {
    //...
    const char* (*get_token)(void) = dlsym(dl, "auth_function");
	if (get_token == NULL || strcmp(get_token(), TOKEN) != 0) {
		dlclose(dl);
		return NULL; 
	}
    //...
}