diff options
author | Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> | 2017-08-14 13:38:43 +0000 |
---|---|---|
committer | Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> | 2017-08-14 13:38:43 +0000 |
commit | 725b383718544da5ef1927887f9aa1e3d91ffb50 (patch) | |
tree | d87738a33ac70ee3c9885d2dfb12f69e28b13f18 /lib/gitlab | |
parent | 56054c3f9c3c78deddcd5cee7a89336efa225a38 (diff) | |
parent | a175966677edc385156eb9dab79d129ece0bb87f (diff) | |
download | gitlab-ce-725b383718544da5ef1927887f9aa1e3d91ffb50.tar.gz |
Merge branch 'fix/thread-safe-gpgme-tmp-directory' into 'master'
Fix: Thread safe GPGME tmp directory
Closes #35986
See merge request !13481
Diffstat (limited to 'lib/gitlab')
-rw-r--r-- | lib/gitlab/gpg.rb | 40 |
1 files changed, 29 insertions, 11 deletions
diff --git a/lib/gitlab/gpg.rb b/lib/gitlab/gpg.rb index e1d1724295a..45e9f9d65ae 100644 --- a/lib/gitlab/gpg.rb +++ b/lib/gitlab/gpg.rb @@ -2,6 +2,8 @@ module Gitlab module Gpg extend self + MUTEX = Mutex.new + module CurrentKeyChain extend self @@ -42,21 +44,37 @@ module Gitlab end end - def using_tmp_keychain - Dir.mktmpdir do |dir| - @original_dirs ||= [GPGME::Engine.dirinfo('homedir')] - @original_dirs.push(dir) - - GPGME::Engine.home_dir = dir - - return_value = yield + # Allows thread safe switching of temporary keychain files + # + # 1. The current thread may use nesting of temporary keychain + # 2. Another thread needs to wait for the lock to be released + def using_tmp_keychain(&block) + if MUTEX.locked? && MUTEX.owned? + optimistic_using_tmp_keychain(&block) + else + MUTEX.synchronize do + optimistic_using_tmp_keychain(&block) + end + end + end - @original_dirs.pop + # 1. Returns the custom home directory if one has been set by calling + # `GPGME::Engine.home_dir=` + # 2. Returns the default home directory otherwise + def current_home_dir + GPGME::Engine.info.first.home_dir || GPGME::Engine.dirinfo('homedir') + end - GPGME::Engine.home_dir = @original_dirs[-1] + private - return_value + def optimistic_using_tmp_keychain + previous_dir = current_home_dir + Dir.mktmpdir do |dir| + GPGME::Engine.home_dir = dir + yield end + ensure + GPGME::Engine.home_dir = previous_dir end end end |