Skip to content

Commit 8c366c2

Browse files
committed
fix(param) save converted value to prevent potential use-after-free
1 parent a0711de commit 8c366c2

File tree

2 files changed

+27
-10
lines changed

2 files changed

+27
-10
lines changed

lib/resty/openssl/kdf.lua

+1-1
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ function _M:derive(outlen, options, options_count)
337337
end
338338

339339
if self.buf_size and outlen then
340-
return nil, string.format("kdf:derive: this KDF has fixed output size %d, "..
340+
return nil, string.format("kdf:derive: this KDF has fixed output size %d, "..
341341
"it can't be set manually", self.buf_size)
342342
end
343343

lib/resty/openssl/param.lua

+26-9
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,23 @@ local OSSL_PARAM_OCTET_PTR = 7
2020

2121
local alter_type_key = {}
2222
local buf_param_key = {}
23+
local buf_anchor_key = {}
2324

2425
local function construct(buf_t, length, types_map, types_size)
2526
if not length then
2627
length = nkeys(buf_t)
2728
end
2829

30+
2931
local params = ffi_new("OSSL_PARAM[?]", length + 1)
3032

3133
local i = 0
32-
local buf_param
34+
local buf_param, buf_anchored
3335
for key, value in pairs(buf_t) do
36+
if key == buf_anchor_key then
37+
goto continue
38+
end
39+
3440
local typ = types_map[key]
3541
if not typ then
3642
return nil, "param:construct: unknown key \"" .. key .. "\""
@@ -69,28 +75,38 @@ local function construct(buf_t, length, types_map, types_size)
6975
ffi_new("unsigned int[1]")
7076
param = C.OSSL_PARAM_construct_uint(key, buf)
7177
elseif typ == OSSL_PARAM_UTF8_STRING then
72-
buf = value and ffi_cast("char *", value) or buf
78+
buf = value ~= nil and ffi_cast("char *", value) or buf
7379
param = C.OSSL_PARAM_construct_utf8_string(key, buf, value and #value or size)
7480
elseif typ == OSSL_PARAM_OCTET_STRING then
75-
buf = value and ffi_cast("char *", value) or buf
81+
buf = value ~= nil and ffi_cast("char *", value) or buf
7682
param = C.OSSL_PARAM_construct_octet_string(key, ffi_cast("void*", buf),
7783
value and #value or size)
78-
elseif typ == OSSL_PARAM_UTF8_PTR then
84+
elseif typ == OSSL_PARAM_UTF8_PTR then -- out only
7985
buf = ffi_new("char*[1]")
8086
param = C.OSSL_PARAM_construct_utf8_ptr(key, buf, 0)
81-
elseif typ == OSSL_PARAM_OCTET_PTR then
87+
elseif typ == OSSL_PARAM_OCTET_PTR then -- out only
8288
buf = ffi_new("char*[1]")
8389
param = C.OSSL_PARAM_construct_octet_ptr(key, ffi_cast("void**", buf), 0)
8490
else
8591
error("type " .. typ .. " is not yet implemented")
8692
end
87-
if not value then -- out
93+
94+
if value == nil then -- out
8895
buf_t[key] = buf
96+
else -- in
97+
-- save value as OSSL_PARAM_construct_* doesn't copy the value
98+
buf_anchored = buf_anchored or {}
99+
buf_anchored[key] = buf
89100
end
101+
90102
params[i] = param
91103
i = i + 1
104+
105+
::continue::
92106
end
93107

108+
buf_t[buf_anchor_key] = buf_anchored
109+
94110
buf_t[buf_param_key] = buf_param
95111
params[length] = C.OSSL_PARAM_construct_end()
96112

@@ -112,7 +128,8 @@ local function parse(buf_t, length, types_map, types_size)
112128
if C.OSSL_PARAM_get_BN(param, bn_t) ~= 1 then
113129
return nil, format_error("param:parse: OSSL_PARAM_get_BN")
114130
end
115-
buf_t[key] = bn_lib.dup(bn_t[0])
131+
buf_t[key] = assert(bn_lib.dup(bn_t[0]))
132+
C.BN_free(bn_t[0])
116133
elseif typ == OSSL_PARAM_INTEGER or
117134
typ == OSSL_PARAM_UNSIGNED_INTEGER then
118135
buf_t[key] = tonumber(buf[0])
@@ -228,7 +245,7 @@ local function get_params_func(typ, field)
228245
local cf_set = C[typ .. "_set_params"]
229246
local set = function(self, params)
230247
if not param_maps_set[self[field]] then
231-
local ok, err = self:settable_params()
248+
local ok, err = self:settable_params(true) -- only query raw schema to save memory
232249
if not ok then
233250
return false, typ_lower .. ":set_params: " .. err
234251
end
@@ -270,7 +287,7 @@ local function get_params_func(typ, field)
270287
local get_buffer, get_size_map = {}, {}
271288
local get = function(self, key, want_size, want_type)
272289
if not param_maps_get[self[field]] then
273-
local ok, err = self:gettable_params()
290+
local ok, err = self:gettable_params(true) -- only query raw schema to save memory
274291
if not ok then
275292
return false, typ_lower .. ":set_params: " .. err
276293
end

0 commit comments

Comments
 (0)