Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 55 additions & 13 deletions security/lua/kvcache.c
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,30 @@ void kvcache_dict_init(struct kvcache_dict *dict)
dict->capacity = CACHE_CAPACITY;
}

static void lua_lsm_shdict_free_rcu(struct rcu_head *head)
{
struct lua_lsm_module_shdict *shdict;

shdict = container_of(head, struct lua_lsm_module_shdict, rcu);
kvcache_dict_free(&shdict->dict);
kfree(shdict);
}

void lua_lsm_shdict_get(struct lua_lsm_module_shdict *shdict)
{
if (shdict)
refcount_acquire(&shdict->refcount);
}

void lua_lsm_shdict_put(struct lua_lsm_module_shdict *shdict)
{
if (!shdict)
return;

if (refcount_release(&shdict->refcount) == 0)
call_rcu(&shdict->rcu, lua_lsm_shdict_free_rcu);
}

/******************************** object cache *******************************/

const int _module_sentinel;
Expand Down Expand Up @@ -595,28 +619,37 @@ int lua_object_newindex(lua_State *L, struct kvcache_dict *dict)

static int shdict_set(lua_State *L)
{
struct kvcache_dict *shdict = toshdict(L, 1);
struct lua_lsm_module_shdict *shdict = toshdict(L, 1);

return kvcache_set(L, shdict, NULL);
if (READ_ONCE(shdict->dead))
return kvcache_result(L, -ESRCH);

return kvcache_set(L, &shdict->dict, NULL);
}

static int shdict_get(lua_State *L)
{
struct kvcache_dict *shdict = toshdict(L, 1);
struct lua_lsm_module_shdict *shdict = toshdict(L, 1);

if (READ_ONCE(shdict->dead))
return kvcache_result(L, -ESRCH);

return kvcache_get(L, shdict, NULL);
return kvcache_get(L, &shdict->dict, NULL);
}

static int shdict_incr(lua_State *L)
{
struct kvcache_dict *shdict = toshdict(L, 1);
struct lua_lsm_module_shdict *shdict = toshdict(L, 1);

if (READ_ONCE(shdict->dead))
return kvcache_result(L, -ESRCH);

return kvcache_incr(L, shdict, NULL);
return kvcache_incr(L, &shdict->dict, NULL);
}

static int shdict_index(lua_State *L)
{
struct kvcache_dict *shdict = toshdict(L, 1);
struct lua_lsm_module_shdict *shdict = toshdict(L, 1);

/* metatable[key] */
if (lua_getmetatable(L, 1) == 0) {
Expand All @@ -628,24 +661,33 @@ static int shdict_index(lua_State *L)
if (!lua_isnoneornil(L, -1))
return 1;

return kvcache_get(L, shdict, NULL);
if (READ_ONCE(shdict->dead))
return kvcache_result(L, -ESRCH);

return kvcache_get(L, &shdict->dict, NULL);
}

static int shdict_tostring(lua_State *L)
{
struct kvcache_dict *shdict = toshdict(L, 1);
struct lua_lsm_module_shdict *shdict = toshdict(L, 1);
unsigned long flags;

read_lock_irqsave(&shdict->lock, flags);
if (READ_ONCE(shdict->dead)) {
lua_pushliteral(L, "shdict (dead)");
return 1;
}

read_lock_irqsave(&shdict->dict.lock, flags);
lua_pushfstring(L, "shdict (%d / %d)",
atomic_read(&shdict->count), shdict->capacity);
read_unlock_irqrestore(&shdict->lock, flags);
atomic_read(&shdict->dict.count),
shdict->dict.capacity);
read_unlock_irqrestore(&shdict->dict.lock, flags);
return 1;
}

static int shdict_gc(lua_State *L)
{
__log_info_ratelimited("shdict already freed by unregister\n");
lua_lsm_shdict_put(toshdict(L, 1));
return 0;
}

Expand Down
9 changes: 7 additions & 2 deletions security/lua/kvcache.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#define CACHE_CAPACITY 1024

struct lua_lsm_module;
struct lua_lsm_module_shdict;

struct kvcache_node {
const char *key;
Expand Down Expand Up @@ -67,11 +68,15 @@ int lua_object_newindex(lua_State *L, struct kvcache_dict *dict);
#define METH_SHARED_DICT "meth_shared_dict"

#define newshdict(L) \
((struct kvcache_dict **)newcptr((L), METH_SHARED_DICT))
((struct lua_lsm_module_shdict **) \
newcptr((L), METH_SHARED_DICT))
#define toshdictp(L, idx) \
((struct kvcache_dict **)luaL_checkudata((L), (idx), METH_SHARED_DICT))
((struct lua_lsm_module_shdict **) \
luaL_checkudata((L), (idx), METH_SHARED_DICT))
#define toshdict(L, idx) (*toshdictp(L, idx))

void lua_lsm_shdict_get(struct lua_lsm_module_shdict *shdict);
void lua_lsm_shdict_put(struct lua_lsm_module_shdict *shdict);
int shdict_init(lua_State *L);

#endif /* ! _SECURITY_LUA_LSM_KVCACHE_H */
Loading