diff --git a/security/lua/kvcache.c b/security/lua/kvcache.c index 37768761b669..c0e5756ce45c 100644 --- a/security/lua/kvcache.c +++ b/security/lua/kvcache.c @@ -62,7 +62,7 @@ static int kvcache_node_cmp(struct kvcache_node *n1, struct kvcache_node *n2) RB_GENERATE_STATIC(kvcache, kvcache_node, node, kvcache_node_cmp); -static void __kvcache_dict_init(struct kvcache_dict *dict) +static void kvcache_dict_init(struct kvcache_dict *dict) { rwlock_init(&dict->lock); RB_INIT(&dict->root); @@ -111,7 +111,7 @@ static int kvcache_dict_init_once(struct kvcache_dict *dict) */ if (atomic_try_cmpxchg(&dict->state, &state, KVCACHE_DICT_INITING)) { - __kvcache_dict_init(dict); + kvcache_dict_init(dict); atomic_set_release(&dict->state, KVCACHE_DICT_READY); goto out_bh; } @@ -549,13 +549,6 @@ void kvcache_dict_free(struct kvcache_dict *dict) WARN_ON(atomic_read(&dict->count) != 0); } -void kvcache_dict_init(struct kvcache_dict *dict) -{ - atomic_set(&dict->state, KVCACHE_DICT_INITING); - __kvcache_dict_init(dict); - atomic_set_release(&dict->state, KVCACHE_DICT_READY); -} - /******************************** object cache *******************************/ const int _module_sentinel; @@ -592,8 +585,10 @@ int lua_object_get(lua_State *L, struct kvcache_dict *dict) { struct lua_lsm_module *module; - if (!dict) - return 0; + if (!dict) { + lua_pushnil(L); + return 1; + } module = module_from_object_fenv(L, 1); if (!module) @@ -605,6 +600,9 @@ int lua_object_incr(lua_State *L, struct kvcache_dict *dict) { struct lua_lsm_module *module; + if (IS_ERR(dict)) + return kvcache_result(L, PTR_ERR(dict)); + if (!dict) return kvcache_result(L, -ESRCH); @@ -660,6 +658,9 @@ int lua_object_newindex(lua_State *L, struct kvcache_dict *dict) { struct lua_lsm_module *module; + if (IS_ERR(dict)) + return kvcache_result(L, PTR_ERR(dict)); + if (!dict) return kvcache_result(L, -ESRCH); @@ -715,6 +716,11 @@ static int shdict_tostring(lua_State *L) struct kvcache_dict *shdict = toshdict(L, 1); unsigned long flags; + if (!kvcache_dict_ready(shdict)) { + lua_pushfstring(L, "shdict (%d / %d)", 0, CACHE_CAPACITY); + return 1; + } + read_lock_irqsave(&shdict->lock, flags); lua_pushfstring(L, "shdict (%d / %d)", atomic_read(&shdict->count), shdict->capacity); diff --git a/security/lua/kvcache.h b/security/lua/kvcache.h index ee9a1d9ce840..43c1eaf3f0bd 100644 --- a/security/lua/kvcache.h +++ b/security/lua/kvcache.h @@ -58,7 +58,6 @@ void kvcache_stats_show(struct seq_file *m); int kvcache_module_nodes_gc(struct lua_lsm_module *module); void kvcache_dict_free(struct kvcache_dict *dict); -void kvcache_dict_init(struct kvcache_dict *dict); /******************************** object cache *******************************/ diff --git a/security/lua/lsm.c b/security/lua/lsm.c index 9f978b2da6b8..7d271bd9bb96 100644 --- a/security/lua/lsm.c +++ b/security/lua/lsm.c @@ -428,35 +428,13 @@ static void lvm_vm_reset(struct lvm_state *lvm) lua_gc(L, LUA_GCCOLLECT, 0); } -static void lvm_mark_dirty(lua_State *L) -{ - void *ud; - - lua_getallocf(L, &ud); - ((struct lvm_state *)ud)->dirty = true; -} - -static bool lvm_task_teardown(const struct lua_lsm_task *llt) -{ - /* Pairs with smp_store_release() in task_blob_free(). */ - return smp_load_acquire(&llt->lvm_teardown); -} - -bool lvm_current_task_teardown(void) -{ - return in_task() && lvm_task_teardown(lua_lsm_task(current)); -} - static struct lvm_state * lvm_get_task_state(const struct task_struct *task, bool create) { struct lua_lsm_task *llt = lua_lsm_task(task); struct lvm_state *lvm, *old; - if (unlikely(lvm_task_teardown(llt))) - return NULL; - - /* Pairs with cmpxchg() publishing a lazy task VM state. */ + /* Pairs with xchg() in lua_lsm_task_blob_free(). */ lvm = smp_load_acquire(&llt->lvm); if (likely(lvm || !create)) return lvm; @@ -465,20 +443,12 @@ lvm_get_task_state(const struct task_struct *task, bool create) if (!lvm) return NULL; - if (unlikely(lvm_task_teardown(llt))) { - kfree(lvm); - return NULL; - } - old = cmpxchg(&llt->lvm, NULL, lvm); if (old) { kfree(lvm); lvm = old; } - if (unlikely(lvm_task_teardown(llt))) - return NULL; - return lvm; } @@ -490,12 +460,16 @@ lvm_get_from_task(const struct task_struct *task, bool require_idle) lua_State *L; int n; + if (IS_ERR(lvm)) + return ERR_CAST(lvm); if (!lvm) - return NULL; + return ERR_PTR(-ENOMEM); n = refcount_acquire(&lvm->refcount); - if (unlikely(lvm_task_teardown(llt))) - goto err_put; + if (IS_ERR(READ_ONCE(llt->lvm))) { + refcount_release(&lvm->refcount); + return ERR_PTR(-ESRCH); + } if (require_idle && n != 1) { refcount_release(&lvm->refcount); return NULL; @@ -521,7 +495,7 @@ lvm_get_from_task(const struct task_struct *task, bool require_idle) memset(&build_owner, 0, sizeof(build_owner)); built = lvm_build_lua_state(&build_owner); if (!built) - goto err_put; + goto err_nomem; owner = &build_owner; } lua_setallocf(built, lvm_alloc, lvm); @@ -541,9 +515,9 @@ lvm_get_from_task(const struct task_struct *task, bool require_idle) } return L; -err_put: +err_nomem: refcount_release(&lvm->refcount); - return NULL; + return ERR_PTR(-ENOMEM); } static void lvm_put_to_task(const struct task_struct *task, lua_State *L) @@ -609,13 +583,12 @@ static int lua_shared_index(lua_State *L) unsigned long flags; size_t l = strlen(name); - shdict = kmalloc(struct_size(shdict, name, l + 1), + shdict = kzalloc(struct_size(shdict, name, l + 1), lua_lsm_gfp()); if (!shdict) { __log_err("No memory\n"); return 0; } - kvcache_dict_init(&shdict->dict); memcpy(shdict->name, name, l); shdict->name[l] = '\0'; @@ -734,6 +707,14 @@ static int module_load(lua_State *L, struct lua_lsm_module *module) return 0; } +static void lvm_mark_dirty(lua_State *L) +{ + void *ud; + + lua_getallocf(L, &ud); + ((struct lvm_state *)ud)->dirty = true; +} + static int lua_modules_index(lua_State *L) { const char *key = luaL_checkstring(L, 2); @@ -1197,7 +1178,6 @@ static int lvm_remove_module(lua_State *L, struct lua_lsm_module *module) static int task_remove_module(struct task_struct *task, void *arg) { - struct lua_lsm_task *llt = lua_lsm_task(task); struct lua_lsm_module *module = arg; struct lvm_state *lvm; lua_State *L; @@ -1207,13 +1187,16 @@ static int task_remove_module(struct task_struct *task, void *arg) return -EBUSY; /* Unregister must not lazily create a VM for untouched tasks. */ - /* Pairs with cmpxchg() in lvm_get_task_state(). */ - lvm = smp_load_acquire(&llt->lvm); - if (!lvm || !smp_load_acquire(&lvm->L)) + lvm = lvm_get_task_state(task, false); + if (IS_ERR_OR_NULL(lvm)) + return -ENOENT; + + /* Pairs with smp_store_release() publishing a constructed Lua VM. */ + if (!smp_load_acquire(&lvm->L)) return -ENOENT; L = lvm_get_from_task(task, true); - if (!L) + if (IS_ERR_OR_NULL(L)) return -EAGAIN; err = lvm_remove_module(L, module); @@ -1435,48 +1418,129 @@ int modules_show(struct seq_file *m, void *v) return 0; } -/*********************************** main ***********************************/ +/******************************** task blob *********************************/ -int task_blob_init(struct task_struct *task) +struct kvcache_dict *lua_lsm_task_dict(const struct task_struct *task, + bool create) { struct lua_lsm_task *llt = lua_lsm_task(task); + struct kvcache_dict *dict, *old; - WRITE_ONCE(llt->lvm_teardown, false); - kvcache_dict_init(&llt->dict); - return 0; + if (IS_ERR(READ_ONCE(llt->lvm))) + return NULL; + + /* Pairs with cmpxchg() publishing a lazily allocated dictionary. */ + dict = smp_load_acquire(&llt->dict); + if (likely(dict || !create)) + return dict; + + dict = kzalloc(sizeof(*dict), lua_lsm_gfp()); + if (!dict) + return ERR_PTR(-ENOMEM); + + if (IS_ERR(READ_ONCE(llt->lvm))) { + kfree(dict); + return NULL; + } + + old = cmpxchg(&llt->dict, NULL, dict); + if (old) { + kfree(dict); + dict = old; + } + + /* Close a publication race with lua_lsm_task_blob_free(). */ + if (IS_ERR(READ_ONCE(llt->lvm))) { + if (cmpxchg(&llt->dict, dict, NULL) == dict) + kfree(dict); + return NULL; + } + + return dict; } -void task_blob_free(struct task_struct *task) +void lua_lsm_task_blob_free(struct task_struct *task) { struct lua_lsm_task *llt = lua_lsm_task(task); struct lvm_state *lvm; + struct kvcache_dict *dict; + lua_State *L; + + if (likely(!lua_lsm_task_blob_has_state(task))) + return; /* * Lua GC can run finalizers which re-enter LSM hooks. Keep the task VM - * published until reset completes, but make lvm_get() skip this task so - * re-entrant hooks cannot allocate or reuse a VM during teardown. + * private after publishing the teardown state so re-entrant hooks + * cannot allocate or reuse task state during teardown. */ - smp_store_release(&llt->lvm_teardown, true); - /* Pairs with cmpxchg() in lvm_get_task_state(). */ - lvm = smp_load_acquire(&llt->lvm); - if (lvm && READ_ONCE(lvm->L) && lvm->dirty) { - lua_modules_free(task, lvm->L); - lvm_vm_reset(lvm); - lvm->dirty = false; - } + lvm = xchg(&llt->lvm, ERR_PTR(-ESRCH)); + if (!IS_ERR_OR_NULL(lvm)) { + L = READ_ONCE(lvm->L); + if (L && lvm->dirty) { + lua_modules_free(task, L); + lvm_vm_reset(lvm); + lvm->dirty = false; + } - lvm = xchg(&llt->lvm, NULL); - if (lvm) { - if (!READ_ONCE(lvm->L)) { + if (!L) { kfree(lvm); } else { refcount_init(&lvm->refcount, 0); lvm_pool_put(lvm); } } - kvcache_dict_free(&llt->dict); + + dict = xchg(&llt->dict, NULL); + if (dict) { + kvcache_dict_free(dict); + kfree(dict); + } } +/******************************* object blob ********************************/ + +struct kvcache_dict *lua_lsm_object_dict(struct lua_lsm_object *llo, bool create) +{ + struct kvcache_dict *dict, *old; + + if (!llo) + return NULL; + + /* Pairs with cmpxchg() publishing a lazily allocated dictionary. */ + dict = smp_load_acquire(&llo->dict); + if (likely(dict || !create)) + return dict; + + dict = kzalloc(sizeof(*dict), lua_lsm_gfp()); + if (!dict) + return ERR_PTR(-ENOMEM); + + old = cmpxchg(&llo->dict, NULL, dict); + if (old) { + kfree(dict); + dict = old; + } + + return dict; +} + +void lua_lsm_object_dict_free(struct lua_lsm_object *llo) +{ + struct kvcache_dict *dict; + + if (!llo) + return; + + dict = xchg(&llo->dict, NULL); + if (dict) { + kvcache_dict_free(dict); + kfree(dict); + } +} + +/*********************************** main ***********************************/ + /* * TODO: Currently, the key, perf_event, tun_dev, and ib objects do not * have corresponding free LSM callback functions, which prevents object @@ -1532,10 +1596,6 @@ static int __init lua_lsm_init(void) lua_lsm_hook_stats_init_cpu(cpu); #endif - err = task_blob_init(current); - if (err) - return err; - for_each_possible_cpu(cpu) { lvm = kzalloc(sizeof(struct lvm_state), GFP_KERNEL); if (!lvm) diff --git a/security/lua/lsm.h b/security/lua/lsm.h index 597b0ecd2b20..0b8a15056501 100644 --- a/security/lua/lsm.h +++ b/security/lua/lsm.h @@ -8,28 +8,32 @@ #ifndef _SECURITY_LUA_LSM_LSM_H #define _SECURITY_LUA_LSM_LSM_H -#include -#include +#include #include -#include -#include +#include +#include #include -#include +#include +#include #include +#include +#include #include -#include -#include +#include + #include "bitmap.h" #include "kvcache.h" +#define LUA_LSM_VERSION 1 + +/* LSM hook dispatch */ + DECLARE_STATIC_KEY_FALSE(lua_lsm_modules_active); DECLARE_STATIC_KEY_FALSE(lua_lsm_inactive_cleanup_armed); /* Flag indicating whether initialization completed */ extern int lua_lsm_initialized __initdata; -#define LUA_LSM_VERSION 1 - struct lua_lsm_hook_stat { const char *name; atomic_t nhooks; @@ -66,11 +70,7 @@ static inline bool lua_lsm_hook_supported(unsigned int nr) } } -struct lua_lsm_module_shdict { - struct list_head list; - struct kvcache_dict dict; - char name[]; -}; +/* Policy modules */ enum lua_lsm_module_state { LMS_STATE_LIVE, @@ -79,6 +79,12 @@ enum lua_lsm_module_state { LMS_STATE_ZOMBIE, }; +struct lua_lsm_module_shdict { + struct list_head list; + struct kvcache_dict dict; + char name[]; +}; + struct lua_lsm_module { const char *name; const char *author; @@ -108,26 +114,10 @@ struct lua_lsm_module { extern struct list_head lsm_modules; extern struct srcu_struct modules_ss; -#define TABLINE \ - "---------------------------------------------" \ - "---------------------------------------------" - -lua_State *lvm_get(void); -void lvm_put(lua_State *L); -bool lvm_current_task_teardown(void); - int lua_lsm_module_register(const char *code, size_t len); int lua_lsm_module_unregister(const char *name); -int modules_show(struct seq_file *m, void *v); - -#ifdef CONFIG_SECURITY_LUA_LSM_STATS -void lua_lsm_hook_stats_record(unsigned int nr, u64 delta); -void lvm_stats_show(struct seq_file *m); -int lsm_funcs_show(struct seq_file *m, void *v); -#endif - -extern struct lsm_blob_sizes lua_lsm_blob_sizes; +/* Lua VMs */ struct lvm_state { lua_State *L; @@ -141,10 +131,20 @@ struct lvm_state { #endif }; +lua_State *lvm_get(void); +void lvm_put(lua_State *L); + +/* LSM blobs */ + +extern struct lsm_blob_sizes lua_lsm_blob_sizes; + struct lua_lsm_task { struct lvm_state *lvm; - bool lvm_teardown; - struct kvcache_dict dict; + struct kvcache_dict *dict; +}; + +struct lua_lsm_object { + struct kvcache_dict *dict; }; static inline struct lua_lsm_task *lua_lsm_task(const struct task_struct *task) @@ -152,11 +152,16 @@ static inline struct lua_lsm_task *lua_lsm_task(const struct task_struct *task) return task->security + lua_lsm_blob_sizes.lbs_task; } -/* common object */ +static inline bool lua_lsm_task_blob_has_state(const struct task_struct *task) +{ + struct lua_lsm_task *llt = lua_lsm_task(task); + + return READ_ONCE(llt->lvm) || READ_ONCE(llt->dict); +} -struct lua_lsm_object { - struct kvcache_dict dict; -}; +struct kvcache_dict *lua_lsm_task_dict(const struct task_struct *task, + bool create); +void lua_lsm_task_blob_free(struct task_struct *task); static inline struct lua_lsm_object *lua_lsm_cred(const struct cred *cred) { @@ -237,10 +242,25 @@ static inline struct lua_lsm_object *lua_lsm_bdev(const struct block_device *bde return bdev->bd_security + lua_lsm_blob_sizes.lbs_bdev; } -int task_blob_init(struct task_struct *task); -void task_blob_free(struct task_struct *task); +struct kvcache_dict *lua_lsm_object_dict(struct lua_lsm_object *llo, + bool create); +void lua_lsm_object_dict_free(struct lua_lsm_object *llo); -/* lua C module */ +/* Observability */ + +#define TABLINE \ + "---------------------------------------------" \ + "---------------------------------------------" + +int modules_show(struct seq_file *m, void *v); + +#ifdef CONFIG_SECURITY_LUA_LSM_STATS +void lua_lsm_hook_stats_record(unsigned int nr, u64 delta); +void lvm_stats_show(struct seq_file *m); +int lsm_funcs_show(struct seq_file *m, void *v); +#endif + +/* Lua C modules */ int luaopen_kernel(lua_State *L); int luaopen_fs(lua_State *L); @@ -249,7 +269,8 @@ int luaopen_errno(lua_State *L); int luaopen_capability(lua_State *L); int luaopen_signal(lua_State *L); -/* securityfs interface */ +/* Securityfs interface */ + int lua_lsm_securityfs_init(void); #endif /* ! _SECURITY_LUA_LSM_LSM_H */ diff --git a/security/lua/lsm_defs.c b/security/lua/lsm_defs.c index 51e2d22ae4f3..8e7cdd2f2234 100644 --- a/security/lua/lsm_defs.c +++ b/security/lua/lsm_defs.c @@ -348,12 +348,6 @@ LUA_LSM_INT_DEFINE2(fs_context_parse_param, struct fs_context *, fc, */ LUA_LSM_PREPARE_DEFINE1(sb_alloc_security, struct super_block *, sb) { - struct lua_lsm_object *llo = lua_lsm_superblock(sb); - - if (!llo) - return -EINVAL; - - kvcache_dict_init(&llo->dict); return 0; } @@ -380,12 +374,7 @@ LUA_LSM_VOID_DEFINE1(sb_delete, struct super_block *, sb) */ LUA_LSM_POSTPONE_DEFINE1(sb_free_security, struct super_block *, sb) { - struct lua_lsm_object *llo = lua_lsm_superblock(sb); - - if (!llo) - return; - - kvcache_dict_free(&llo->dict); + lua_lsm_object_dict_free(lua_lsm_superblock(sb)); } /** @@ -727,12 +716,6 @@ LUA_LSM_INT_DEFINE3(path_notify, const struct path *, path, */ LUA_LSM_PREPARE_DEFINE1(inode_alloc_security, struct inode *, inode) { - struct lua_lsm_object *llo = lua_lsm_inode(inode); - - if (!llo) - return -EINVAL; - - kvcache_dict_init(&llo->dict); return 0; } @@ -759,8 +742,7 @@ LUA_LSM_VOID_DEFINE1(inode_free_security, struct inode *, inode) */ LUA_LSM_POSTPONE_DEFINE1(inode_free_security_rcu, void *, inode_security) { - struct lua_lsm_object *llo = lua_lsm_inode_rcu(inode_security); - kvcache_dict_free(&llo->dict); + lua_lsm_object_dict_free(lua_lsm_inode_rcu(inode_security)); } /** @@ -1530,12 +1512,6 @@ LUA_LSM_INT_DEFINE2(file_permission, struct file *, file, int, mask) */ LUA_LSM_PREPARE_DEFINE1(file_alloc_security, struct file *, file) { - struct lua_lsm_object *llo = lua_lsm_file(file); - - if (!llo) - return -EINVAL; - - kvcache_dict_init(&llo->dict); return 0; } @@ -1562,12 +1538,7 @@ LUA_LSM_VOID_DEFINE1(file_release, struct file *, file) */ LUA_LSM_POSTPONE_DEFINE1(file_free_security, struct file *, file) { - struct lua_lsm_object *llo = lua_lsm_file(file); - - if (!llo) - return; - - kvcache_dict_free(&llo->dict); + lua_lsm_object_dict_free(lua_lsm_file(file)); } /** @@ -1735,7 +1706,7 @@ LUA_LSM_INT_DEFINE1(file_truncate, struct file *, file) */ LUA_LSM_PREPARE_DEFINE2(task_alloc, struct task_struct *, task, u64, clone_flags) { - return task_blob_init(task); + return 0; } /** @@ -1753,7 +1724,7 @@ LUA_LSM_INT_DEFINE2(task_alloc, struct task_struct *, task, u64, clone_flags) */ LUA_LSM_POSTPONE_DEFINE1(task_free, struct task_struct *, task) { - task_blob_free(task); + lua_lsm_task_blob_free(task); } /** @@ -1770,12 +1741,6 @@ LUA_LSM_VOID_DEFINE1(task_free, struct task_struct *, task) */ LUA_LSM_PREPARE_DEFINE2(cred_alloc_blank, struct cred *, cred, gfp_t, gfp) { - struct lua_lsm_object *llo = lua_lsm_cred(cred); - - if (!llo) - return -EINVAL; - - kvcache_dict_init(&llo->dict); return 0; } @@ -1794,12 +1759,7 @@ LUA_LSM_INT_DEFINE2(cred_alloc_blank, struct cred *, cred, gfp_t, gfp) */ LUA_LSM_POSTPONE_DEFINE1(cred_free, struct cred *, cred) { - struct lua_lsm_object *llo = lua_lsm_cred(cred); - - if (!llo) - return; - - kvcache_dict_free(&llo->dict); + lua_lsm_object_dict_free(lua_lsm_cred(cred)); } /** @@ -1817,12 +1777,6 @@ LUA_LSM_VOID_DEFINE1(cred_free, struct cred *, cred) LUA_LSM_PREPARE_DEFINE3(cred_prepare, struct cred *, new, const struct cred *, old, gfp_t, gfp) { - struct lua_lsm_object *llo = lua_lsm_cred(new); - - if (!llo) - return -EINVAL; - - kvcache_dict_init(&llo->dict); return 0; } @@ -2205,12 +2159,6 @@ LUA_LSM_VOID_DEFINE2(ipc_getlsmprop, struct kern_ipc_perm *, ipcp, */ LUA_LSM_PREPARE_DEFINE1(msg_msg_alloc_security, struct msg_msg *, msg) { - struct lua_lsm_object *llo = lua_lsm_msgmsg(msg); - - if (!llo) - return -EINVAL; - - kvcache_dict_init(&llo->dict); return 0; } @@ -2228,12 +2176,7 @@ LUA_LSM_INT_DEFINE1(msg_msg_alloc_security, struct msg_msg *, msg) */ LUA_LSM_POSTPONE_DEFINE1(msg_msg_free_security, struct msg_msg *, msg) { - struct lua_lsm_object *llo = lua_lsm_msgmsg(msg); - - if (!llo) - return; - - kvcache_dict_free(&llo->dict); + lua_lsm_object_dict_free(lua_lsm_msgmsg(msg)); } /** @@ -2250,12 +2193,6 @@ LUA_LSM_VOID_DEFINE1(msg_msg_free_security, struct msg_msg *, msg) */ LUA_LSM_PREPARE_DEFINE1(msg_queue_alloc_security, struct kern_ipc_perm *, perm) { - struct lua_lsm_object *llo = lua_lsm_ipc(perm); - - if (!llo) - return -EINVAL; - - kvcache_dict_init(&llo->dict); return 0; } @@ -2273,12 +2210,7 @@ LUA_LSM_INT_DEFINE1(msg_queue_alloc_security, struct kern_ipc_perm *, perm) */ LUA_LSM_POSTPONE_DEFINE1(msg_queue_free_security, struct kern_ipc_perm *, perm) { - struct lua_lsm_object *llo = lua_lsm_ipc(perm); - - if (!llo) - return; - - kvcache_dict_free(&llo->dict); + lua_lsm_object_dict_free(lua_lsm_ipc(perm)); } /** @@ -2343,12 +2275,6 @@ LUA_LSM_INT_DEFINE5(msg_queue_msgrcv, struct kern_ipc_perm *, perm, */ LUA_LSM_PREPARE_DEFINE1(shm_alloc_security, struct kern_ipc_perm *, perm) { - struct lua_lsm_object *llo = lua_lsm_ipc(perm); - - if (!llo) - return -EINVAL; - - kvcache_dict_init(&llo->dict); return 0; } @@ -2366,12 +2292,7 @@ LUA_LSM_INT_DEFINE1(shm_alloc_security, struct kern_ipc_perm *, perm) */ LUA_LSM_POSTPONE_DEFINE1(shm_free_security, struct kern_ipc_perm *, perm) { - struct lua_lsm_object *llo = lua_lsm_ipc(perm); - - if (!llo) - return; - - kvcache_dict_free(&llo->dict); + lua_lsm_object_dict_free(lua_lsm_ipc(perm)); } /** @@ -2420,12 +2341,6 @@ LUA_LSM_INT_DEFINE3(shm_shmat, struct kern_ipc_perm *, perm, */ LUA_LSM_PREPARE_DEFINE1(sem_alloc_security, struct kern_ipc_perm *, perm) { - struct lua_lsm_object *llo = lua_lsm_ipc(perm); - - if (!llo) - return -EINVAL; - - kvcache_dict_init(&llo->dict); return 0; } @@ -2443,12 +2358,7 @@ LUA_LSM_INT_DEFINE1(sem_alloc_security, struct kern_ipc_perm *, perm) */ LUA_LSM_POSTPONE_DEFINE1(sem_free_security, struct kern_ipc_perm *, perm) { - struct lua_lsm_object *llo = lua_lsm_ipc(perm); - - if (!llo) - return; - - kvcache_dict_free(&llo->dict); + lua_lsm_object_dict_free(lua_lsm_ipc(perm)); } /** @@ -2924,8 +2834,6 @@ LUA_LSM_INT_DEFINE3(socket_getpeersec_dgram, struct socket *, sock, LUA_LSM_PREPARE_DEFINE3(sk_alloc_security, struct sock *, sk, int, family, gfp_t, priority) { - struct lua_lsm_object *llo = lua_lsm_sock(sk); - kvcache_dict_init(&llo->dict); return 0; } @@ -2946,8 +2854,7 @@ LUA_LSM_INT_DEFINE3(sk_alloc_security, struct sock *, sk, */ LUA_LSM_POSTPONE_DEFINE1(sk_free_security, struct sock *, sk) { - struct lua_lsm_object *llo = lua_lsm_sock(sk); - kvcache_dict_free(&llo->dict); + lua_lsm_object_dict_free(lua_lsm_sock(sk)); } /** @@ -3652,8 +3559,6 @@ LUA_LSM_VOID_DEFINE0(initramfs_populated) */ LUA_LSM_PREPARE_DEFINE1(bdev_alloc_security, struct block_device *, bdev) { - struct lua_lsm_object *llo = lua_lsm_bdev(bdev); - kvcache_dict_init(&llo->dict); return 0; } @@ -3671,8 +3576,7 @@ LUA_LSM_INT_DEFINE1(bdev_alloc_security, struct block_device *, bdev) */ LUA_LSM_POSTPONE_DEFINE1(bdev_free_security, struct block_device *, bdev) { - struct lua_lsm_object *llo = lua_lsm_bdev(bdev); - kvcache_dict_free(&llo->dict); + lua_lsm_object_dict_free(lua_lsm_bdev(bdev)); } /** diff --git a/security/lua/lsm_defs.h b/security/lua/lsm_defs.h index c6b2149ca122..afd7377c0e75 100644 --- a/security/lua/lsm_defs.h +++ b/security/lua/lsm_defs.h @@ -251,10 +251,10 @@ static inline bool lua_lsm_hook_has_inactive_cleanup(unsigned int nr) if (!lua_lsm_hook_active(__LL_NR_ ## NAME)) \ goto out; \ L = lvm_get(); \ - if (!L) { \ - if (lvm_current_task_teardown()) \ + if (IS_ERR(L)) { \ + if (PTR_ERR(L) == -ESRCH) \ goto out; \ - return -ENOMEM; \ + return PTR_ERR(L); \ } \ lua_pushcfunction(L, lua_traceback); \ lua_pushthread(L); \ diff --git a/security/lua/lua_object.h b/security/lua/lua_object.h index 84b332f8361e..24eb9ebbb755 100644 --- a/security/lua/lua_object.h +++ b/security/lua/lua_object.h @@ -49,12 +49,19 @@ return (ctype *)checkudata(L, idx, metaname); \ } -#define LUA_OBJECT_KVCACHE_FUNC(name, ctype, blob, method, fname) \ +#define LUA_OBJECT_KVCACHE_FUNC_object(name, ctype, method, fname, create) \ static int rawmeth_ ## name ## _ ## method(lua_State *L) \ { \ ctype p = toraw ## name(L, 1); \ - struct lua_lsm_ ## blob *ll = lua_lsm_ ## name(p); \ - return lua_object_ ## fname(L, ll ? &ll->dict : NULL); \ + struct lua_lsm_object *ll = lua_lsm_ ## name(p); \ + return lua_object_ ## fname(L, lua_lsm_object_dict(ll, create)); \ + } + +#define LUA_OBJECT_KVCACHE_FUNC_task(name, ctype, method, fname, create) \ + static int rawmeth_ ## name ## _ ## method(lua_State *L) \ + { \ + ctype p = toraw ## name(L, 1); \ + return lua_object_ ## fname(L, lua_lsm_task_dict(p, create)); \ } #define LUA_OBJECT_FUNCS_DEFINE(name, ctype, has_kvcache) \ @@ -75,10 +82,10 @@ LUA_OBJECT_META_DEFINE(name, ctype, d, METHOD_NAME(name)) \ LUA_OBJECT_META_DEFINE(raw ## name, ctype, d, METHOD_NAME_RAW(name)) \ LUA_OBJECT_META_DEFINE(gc ## name, ctype, d, METHOD_NAME_GC(name)) \ - LUA_OBJECT_KVCACHE_FUNC(name, ctype, blob, kvcache_get, get) \ - LUA_OBJECT_KVCACHE_FUNC(name, ctype, blob, kvcache_incr, incr) \ - LUA_OBJECT_KVCACHE_FUNC(name, ctype, blob, index, index) \ - LUA_OBJECT_KVCACHE_FUNC(name, ctype, blob, newindex, newindex) \ + LUA_OBJECT_KVCACHE_FUNC_ ## blob(name, ctype, kvcache_get, get, false) \ + LUA_OBJECT_KVCACHE_FUNC_ ## blob(name, ctype, kvcache_incr, incr, true) \ + LUA_OBJECT_KVCACHE_FUNC_ ## blob(name, ctype, index, index, false) \ + LUA_OBJECT_KVCACHE_FUNC_ ## blob(name, ctype, newindex, newindex, true) \ LUA_OBJECT_FUNCS_DEFINE(name, ctype, 1) \ static inline void create_ ## name ## _meta(lua_State *L, \ const luaL_Reg *funcs, const luaL_Reg *gc) \