HADOOP-11056. OsSecureRandom.setConf() might leak file descriptors. Contributed by Yongjun Zhang.
Project: http://git-wip-us.apache.org/repos/asf/hadoop/repo Commit: http://git-wip-us.apache.org/repos/asf/hadoop/commit/8f1a6685 Tree: http://git-wip-us.apache.org/repos/asf/hadoop/tree/8f1a6685 Diff: http://git-wip-us.apache.org/repos/asf/hadoop/diff/8f1a6685 Branch: refs/heads/MR-2841 Commit: 8f1a668575d35bee11f4cd8173335be5352ec620 Parents: f4caedf Author: Colin Patrick Mccabe <cmcc...@cloudera.com> Authored: Wed Sep 3 19:35:39 2014 -0700 Committer: Colin Patrick Mccabe <cmcc...@cloudera.com> Committed: Wed Sep 3 19:35:39 2014 -0700 ---------------------------------------------------------------------- hadoop-common-project/hadoop-common/CHANGES.txt | 3 +++ .../hadoop/crypto/random/OsSecureRandom.java | 21 +++++++++++++++++--- .../crypto/random/TestOsSecureRandom.java | 15 ++++++++++++++ 3 files changed, 36 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/hadoop/blob/8f1a6685/hadoop-common-project/hadoop-common/CHANGES.txt ---------------------------------------------------------------------- diff --git a/hadoop-common-project/hadoop-common/CHANGES.txt b/hadoop-common-project/hadoop-common/CHANGES.txt index 0b9cfdc..e8d0f52 100644 --- a/hadoop-common-project/hadoop-common/CHANGES.txt +++ b/hadoop-common-project/hadoop-common/CHANGES.txt @@ -684,6 +684,9 @@ Release 2.6.0 - UNRELEASED HADOOP-8815. RandomDatum needs to override hashCode(). (Brandon Li via suresh) + HADOOP-11056. OsSecureRandom.setConf() might leak file descriptors (yzhang + via cmccabe) + BREAKDOWN OF HDFS-6134 AND HADOOP-10150 SUBTASKS AND RELATED JIRAS HADOOP-10734. Implement high-performance secure random number sources. http://git-wip-us.apache.org/repos/asf/hadoop/blob/8f1a6685/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/random/OsSecureRandom.java ---------------------------------------------------------------------- diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/random/OsSecureRandom.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/random/OsSecureRandom.java index c6cb0a8..fee4186 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/random/OsSecureRandom.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/random/OsSecureRandom.java @@ -23,6 +23,8 @@ import java.io.FileInputStream; import java.io.IOException; import java.util.Random; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.apache.hadoop.classification.InterfaceAudience; import org.apache.hadoop.conf.Configurable; import org.apache.hadoop.conf.Configuration; @@ -37,6 +39,8 @@ import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY */ @InterfaceAudience.Private public class OsSecureRandom extends Random implements Closeable, Configurable { + public static final Log LOG = LogFactory.getLog(OsSecureRandom.class); + private static final long serialVersionUID = 6391500337172057900L; private transient Configuration conf; @@ -72,12 +76,20 @@ public class OsSecureRandom extends Random implements Closeable, Configurable { HADOOP_SECURITY_SECURE_RANDOM_DEVICE_FILE_PATH_KEY, HADOOP_SECURITY_SECURE_RANDOM_DEVICE_FILE_PATH_DEFAULT); File randomDevFile = new File(randomDevPath); + try { + close(); this.stream = new FileInputStream(randomDevFile); - fillReservoir(0); } catch (IOException e) { throw new RuntimeException(e); } + + try { + fillReservoir(0); + } catch (RuntimeException e) { + close(); + throw e; + } } @Override @@ -109,7 +121,10 @@ public class OsSecureRandom extends Random implements Closeable, Configurable { } @Override - synchronized public void close() throws IOException { - stream.close(); + synchronized public void close() { + if (stream != null) { + IOUtils.cleanup(LOG, stream); + stream = null; + } } } http://git-wip-us.apache.org/repos/asf/hadoop/blob/8f1a6685/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/crypto/random/TestOsSecureRandom.java ---------------------------------------------------------------------- diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/crypto/random/TestOsSecureRandom.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/crypto/random/TestOsSecureRandom.java index 8fc5c70..50a0031 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/crypto/random/TestOsSecureRandom.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/crypto/random/TestOsSecureRandom.java @@ -22,6 +22,7 @@ import java.util.Arrays; import org.apache.commons.lang.SystemUtils; import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.util.Shell.ShellCommandExecutor; import org.junit.Assume; import org.junit.Test; @@ -136,4 +137,18 @@ public class TestOsSecureRandom { } random.close(); } + + @Test(timeout=120000) + public void testOsSecureRandomSetConf() throws IOException { + Assume.assumeTrue(SystemUtils.IS_OS_LINUX); + OsSecureRandom random = new OsSecureRandom(); + for(int n = 0; n < 10; ++n) { + random.setConf(new Configuration()); + String[] scmd = new String[] {"/bin/sh", "-c", "lsof | wc -l"}; + ShellCommandExecutor sce = new ShellCommandExecutor(scmd); + sce.execute(); + System.out.println("==lsof result " + n + ":"); + System.out.println(sce.getOutput()); + } + } }