From d307a1482a4bb5a704b848bdf077aa08d380d9e9 Mon Sep 17 00:00:00 2001 From: Euan Kemp Date: Tue, 20 Feb 2018 23:20:30 -0800 Subject: [PATCH] Correct c-struct 'null' checks In luajit, a null pointer is distinct from nil, and thus "truthy". That is to say, `if not c_ffi_struct` will never evaluate to true, even if the struct is null. However, a null ffi struct does compare equal to nil, so the new comparison corrects this issue. This fixes numerous bugs in this library, including multiple cases of uninitialized data being passed into functions leading to null pointer dereferences, buffer overflows, and more. --- lib/resty/evp.lua | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/resty/evp.lua b/lib/resty/evp.lua index 12165ef..59ff18b 100644 --- a/lib/resty/evp.lua +++ b/lib/resty/evp.lua @@ -137,7 +137,7 @@ function RSASigner.new(self, pem_private_key) ffi.gc(rsa, _C.RSA_free) local evp_pkey = _C.EVP_PKEY_new() - if not evp_pkey then + if evp_pkey == nil then return _err() end ffi.gc(evp_pkey, _C.EVP_PKEY_free) @@ -158,13 +158,13 @@ function RSASigner.sign(self, message, digest_name) local len = ffi.new("size_t[1]", 1024) local ctx = _C.EVP_MD_CTX_create() - if not ctx then + if ctx == nil then return _err() end ffi.gc(ctx, _C.EVP_MD_CTX_destroy) local md = _C.EVP_get_digestbyname(digest_name) - if not md then + if md == nil then return _err() end @@ -209,12 +209,12 @@ end -- @returns bool, error_string function RSAVerifier.verify(self, message, sig, digest_name) local md = _C.EVP_get_digestbyname(digest_name) - if not md then + if md == nil then return _err(false) end local ctx = _C.EVP_MD_CTX_create() - if not ctx then + if ctx == nil then return _err(false) end ffi.gc(ctx, _C.EVP_MD_CTX_destroy) @@ -265,7 +265,7 @@ function Cert.new(self, payload) end x509 = _C.d2i_X509_bio(bio, nil) end - if not x509 then + if x509 == nil then return _err() end ffi.gc(x509, _C.X509_free) @@ -299,7 +299,7 @@ end -- @returns fingerprint_string function Cert.get_fingerprint(self, digest_name) local md = _C.EVP_get_digestbyname(digest_name) - if not md then + if md == nil then return _err() end local buf = ffi.new("unsigned char[?]", 32) @@ -317,7 +317,7 @@ end -- @returns An OpenSSL EVP PKEY object representing the public key function Cert.get_public_key(self) local evp_pkey = _C.X509_get_pubkey(self.x509) - if not evp_pkey then + if evp_pkey == nil then return _err() end @@ -329,7 +329,7 @@ end -- @return bool, error_string function Cert.verify_trust(self, trusted_cert_file) local store = _C.X509_STORE_new() - if not store then + if store == nil then return _err(false) end ffi.gc(store, _C.X509_STORE_free) @@ -338,7 +338,7 @@ function Cert.verify_trust(self, trusted_cert_file) end local ctx = _C.X509_STORE_CTX_new() - if not store then + if store == nil then return _err(false) end ffi.gc(ctx, _C.X509_STORE_CTX_free) @@ -386,7 +386,7 @@ function PublicKey.new(self, payload) end pkey = _C.d2i_PUBKEY_bio(bio, nil) end - if not pkey then + if pkey == nil then return _err() end ffi.gc(pkey, _C.EVP_PKEY_free)