Skip to content

Commit

Permalink
fix(core) random seeding fix (Kong#1824)
Browse files Browse the repository at this point in the history
* fix(core) random seeding fix, do not rely on first call being in `init_worker`

* added safety measure to not re-run the patches

* remove double invocation of patches

* updated log messages to be consistent
  • Loading branch information
Tieske authored Nov 16, 2016
1 parent 04f9faa commit bbb62cd
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 14 deletions.
4 changes: 0 additions & 4 deletions bin/kong
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
#!/usr/bin/env resty

require("kong.core.globalpatches")({
cli = true
})

package.path = "?/init.lua;"..package.path

require("kong.cmd.init")(arg)
35 changes: 25 additions & 10 deletions kong/core/globalpatches.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
local ran_before

return function(options)

if ran_before then
ngx.log(ngx.WARN, debug.traceback("attempt to re-run the globalpatches", 2))
return
end
ngx.log(ngx.DEBUG, "installing the globalpatches")
ran_before = true



options = options or {}
local meta = require "kong.meta"

Expand Down Expand Up @@ -163,7 +174,7 @@ return function(options)
-- as with the semaphore patch
-- only used for running tests
local randomseed = math.randomseed
local seed
local seeds = {}

--- Seeds the random generator, use with care.
-- Once - properly - seeded, this method is replaced with a stub
Expand All @@ -176,6 +187,7 @@ return function(options)
-- using a combination of both time and the worker's pid.
-- luacheck: globals math
_G.math.randomseed = function()
local seed = seeds[ngx.worker.pid()]
if not seed then
-- If we're in runtime nginx, we have multiple workers so we _only_
-- accept seeding when in the 'init_worker' phase.
Expand All @@ -184,16 +196,18 @@ return function(options)
-- if we'd do that in the 'init' phase, the Lua VM is not forked
-- yet and all workers would end-up using the same seed.
if not options.cli and ngx.get_phase() ~= "init_worker" then
ngx.log(ngx.ERR, debug.traceback("math.randomseed() must be called in init_worker"))
ngx.log(ngx.WARN, debug.traceback("math.randomseed() must be "..
"called in init_worker context", 2))
end

seed = ngx.time() + ngx.worker.pid()
ngx.log(ngx.DEBUG, "random seed: ", seed, " for worker nb ", ngx.worker.id(),
" (pid: ", ngx.worker.pid(), ")")
randomseed(seed)
seeds[ngx.worker.pid()] = seed
else
ngx.log(ngx.DEBUG, "attempt to seed random number generator, but ",
"already seeded with ", seed)
ngx.log(ngx.DEBUG, debug.traceback("attempt to seed random number "..
"generator, but already seeded with: "..tostring(seed), 2))
end

return seed
Expand All @@ -204,14 +218,15 @@ return function(options)
-- this version of the randomseeding patch is required for
-- production, but doesn't work in tests, due to the ffi dependency
local util = require "kong.tools.utils"
local seed
local seeds = {}
local randomseed = math.randomseed

_G.math.randomseed = function()
local seed = seeds[ngx.worker.pid()]
if not seed then
if not options.cli and ngx.get_phase() ~= "init_worker" then
ngx.log(ngx.WARN, "math.randomseed() must be called in init_worker ",
"context\n", debug.traceback('', 2)) -- nil [message] arg doesn't work with level
ngx.log(ngx.WARN, debug.traceback("math.randomseed() must be "..
"called in init_worker context", 2))
end

local bytes, err = util.get_rand_bytes(8)
Expand Down Expand Up @@ -253,10 +268,10 @@ return function(options)
end

randomseed(seed)
seeds[ngx.worker.pid()] = seed
else
ngx.log(ngx.DEBUG, "attempt to seed random number generator, but ",
"already seeded with: ", seed, "\n",
debug.traceback('', 2)) -- nil [message] arg doesn't work with level
ngx.log(ngx.DEBUG, debug.traceback("attempt to seed random number "..
"generator, but already seeded with: "..tostring(seed), 2))
end

return seed
Expand Down

0 comments on commit bbb62cd

Please sign in to comment.