]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-dict: dict-lua - Throw Lua error if dict key is invalid or username is missing
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Thu, 7 Oct 2021 16:59:52 +0000 (19:59 +0300)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Tue, 12 Oct 2021 11:07:27 +0000 (11:07 +0000)
This prevents assert-crashes in the C code.

src/lib-dict/dict-iter-lua.c
src/lib-dict/dict-lua.c
src/lib-dict/dict-lua.h
src/lib-dict/dict-txn-lua.c

index 1af3009be04ed7d44a4024ac4b00fc8e9def85c8..780de0316a55dc9b1359ea844a266ede07956376 100644 (file)
@@ -168,6 +168,7 @@ int lua_dict_iterate(lua_State *L)
        flags = luaL_checkinteger(L, 3);
        if (lua_gettop(L) >= 4)
                username = luaL_checkstring(L, 4);
+       lua_dict_check_key_prefix(L, path, username);
 
        struct dict_op_settings set = {
                .username = username,
index abab8c7f93326bd89d245bb9c9ae31005f057ed9..d5de534218625b7e96ee01aafb9b8479bc34a5a9 100644 (file)
@@ -58,6 +58,19 @@ static void lua_dict_lookup_callback(const struct dict_lookup_result *result,
        dlua_pcall_yieldable_resume(L, 1);
 }
 
+void lua_dict_check_key_prefix(lua_State *L, const char *key,
+                              const char *username)
+{
+       if (str_begins(key, DICT_PATH_SHARED))
+               ;
+       else if (str_begins(key, DICT_PATH_PRIVATE)) {
+               if (username == NULL || username[0] == '\0')
+                       luaL_error(L, DICT_PATH_PRIVATE" dict key prefix requires username");
+       } else {
+               luaL_error(L, "Invalid dict key prefix");
+       }
+}
+
 /*
  * Lookup a key in dict [-(2|3),+1,e]
  *
@@ -82,6 +95,7 @@ static int lua_dict_lookup(lua_State *L)
        key = luaL_checkstring(L, 2);
        if (lua_gettop(L) >= 3)
                username = luaL_checkstring(L, 3);
+       lua_dict_check_key_prefix(L, key, username);
 
        struct dict_op_settings set = {
                .username = username,
index 186f4e9974056b5d31a91535134ab81731ab0614..bf4255cc0a568be5ff32cc9f9ef3ff71959fb0d5 100644 (file)
@@ -7,6 +7,9 @@
  * 5.3 and newer.
  */
 
+void lua_dict_check_key_prefix(lua_State *L, const char *key,
+                              const char *username);
+
 void dlua_push_dict(lua_State *L, struct dict *dict);
 struct dict *dlua_check_dict(lua_State *L, int idx);
 
index a7503ba1366a9be4073902955438049884e84582..34a475dc54719b8dc22fd74787489d53106cd7a8 100644 (file)
@@ -17,6 +17,7 @@ struct lua_dict_txn {
        } state;
 
        lua_State *L;
+       const char *username;
 };
 
 static int lua_dict_transaction_rollback(lua_State *L);
@@ -161,6 +162,7 @@ static int lua_dict_set(lua_State *L)
        txn = xlua_dict_txn_getptr(L, 1, NULL);
        key = luaL_checkstring(L, 2);
        value = luaL_checkstring(L, 3);
+       lua_dict_check_key_prefix(L, key, txn->username);
 
        dict_set(txn->txn, key, value);
 
@@ -183,6 +185,7 @@ static int lua_dict_unset(lua_State *L)
 
        txn = xlua_dict_txn_getptr(L, 1, NULL);
        key = luaL_checkstring(L, 2);
+       lua_dict_check_key_prefix(L, key, txn->username);
 
        dict_unset(txn->txn, key);
 
@@ -223,6 +226,7 @@ int lua_dict_transaction_begin(lua_State *L)
        txn->txn = dict_transaction_begin(dict, &set);
        txn->state = STATE_OPEN;
        txn->L = L;
+       txn->username = p_strdup(txn->pool, username);
 
        xlua_pushdict_txn(L, txn, FALSE);