diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs
index c180476efb8..844814fbfdd 100644
--- a/src/libstd/io/stdio.rs
+++ b/src/libstd/io/stdio.rs
@@ -41,6 +41,7 @@ use option::Option;
 use option::Option::{Some, None};
 use ops::{Deref, DerefMut, FnOnce};
 use result::Result::{Ok, Err};
+use rt;
 use rustrt;
 use rustrt::local::Local;
 use rustrt::task::Task;
@@ -224,6 +225,12 @@ pub fn stdin() -> StdinReader {
                 inner: Arc::new(Mutex::new(stdin))
             };
             STDIN = mem::transmute(box stdin);
+
+            // Make sure to free it at exit
+            rt::at_exit(|| {
+                mem::transmute::<_, Box<StdinReader>>(STDIN);
+                STDIN = 0 as *const _;
+            });
         });
 
         (*STDIN).clone()
diff --git a/src/test/run-pass-valgrind/cleanup-stdin.rs b/src/test/run-pass-valgrind/cleanup-stdin.rs
new file mode 100644
index 00000000000..21160553f79
--- /dev/null
+++ b/src/test/run-pass-valgrind/cleanup-stdin.rs
@@ -0,0 +1,13 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    let _ = std::io::stdin();
+}