Skip to content

Commit 1d25881

Browse files
committed
pw_hash: Use JVM-wide mutex to prevent race conditions
Native crypt(3) uses a static buffer and is not thread-safe. On puppetserver, multiple JRuby workers share the same JVM, causing intermittent failures when concurrent pw_hash calls corrupt each other's crypt results. This fix uses synchronized block on the Crypt class for JVM-wide locking on JRuby, and a Ruby Mutex for MRI.
1 parent 50a6b6b commit 1d25881

1 file changed

Lines changed: 15 additions & 1 deletion

File tree

lib/puppet/parser/functions/pw_hash.rb

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
# Please note: This function is an implementation of a Ruby class and as such may not be entirely UTF8 compatible.
44
# To ensure compatibility please use this function with Ruby 2.4.0 or greater - https://bugs.ruby-lang.org/issues/10085.
55
#
6+
7+
# Mutex for MRI Ruby - native crypt(3) is not thread-safe
8+
PW_HASH_CRYPT_LOCK = Mutex.new unless RUBY_PLATFORM == 'java'
9+
610
Puppet::Parser::Functions.newfunction(:pw_hash, type: :rvalue, arity: 3, doc: <<-DOC
711
@summary
812
Hashes a password using the crypt function. Provides a hash usable
@@ -79,8 +83,18 @@
7983
if RUBY_PLATFORM == 'java' && !args[1].downcase.start_with?('bcrypt')
8084
# puppetserver bundles Apache Commons Codec
8185
org.apache.commons.codec.digest.Crypt.crypt(password.to_java_bytes, salt)
86+
elsif RUBY_PLATFORM == 'java'
87+
# JVM-wide lock for bcrypt on JRuby - crypt(3) uses static buffer, not thread-safe across workers
88+
org.apache.commons.codec.digest.Crypt.java_class.synchronized do
89+
if (+'test').crypt('$1$1') == '$1$1$Bp8CU9Oujr9SSEw53WV6G.'
90+
password.crypt(salt)
91+
else
92+
raise Puppet::ParseError, 'system does not support enhanced salts'
93+
end
94+
end
8295
elsif (+'test').crypt('$1$1') == '$1$1$Bp8CU9Oujr9SSEw53WV6G.'
83-
password.crypt(salt)
96+
# MRI Ruby with thread-safety mutex
97+
PW_HASH_CRYPT_LOCK.synchronize { password.crypt(salt) }
8498
else
8599
# JRuby < 1.7.17
86100
# MS Windows and other systems that don't support enhanced salts

0 commit comments

Comments
 (0)