Skip to content

Commit

Permalink
new clojure RT every 10 minutes, this is way too much code, but at
Browse files Browse the repository at this point in the history
least it seems to work
  • Loading branch information
hiredman committed Sep 28, 2011
1 parent eb83e01 commit 9641a9a
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 31 deletions.
46 changes: 33 additions & 13 deletions src/hiredman/clojurebot/sb.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,39 @@
(:use (hiredman.clojurebot core)
(hiredman sandbox)))

(defonce cl
(memoize
(fn [clojure-jar]
(doto (if clojure-jar
(let [bootcp clojure-jar
cp (.split bootcp ":")
cp (for [c cp] (java.net.URL. (format "file://%s" c)))
cp (into-array java.net.URL cp)]
(java.net.URLClassLoader. cp nil))
(.getClassLoader clojure.lang.RT))
;; make sure RT is loaded and inited before we try and use it
;; in the sandbox
(evil "(+ 1 2)")))))
(let [cl-cache (atom {})]
(defn cl [clojure-jar]
(if-let [[ctime cl] (get @cl-cache clojure-jar)]
(if (> (- (System/currentTimeMillis)
(* 10 60 1000))
ctime)
(do
(println "new classloader")
(swap! cl-cache dissoc clojure-jar)
(recur clojure-jar))
cl)
(doto (if clojure-jar
(java.security.AccessController/doPrivileged
(reify
java.security.PrivilegedAction
(run [_]
(let [bootcp clojure-jar
cp (.split bootcp ":")
cp (for [c cp] (java.net.URL. (format "file://%s" c)))
cp (into-array java.net.URL cp)]
(java.net.URLClassLoader. cp nil)))))
(.getClassLoader clojure.lang.RT))
;; make sure RT is loaded and inited before we try and use it
;; in the sandbox
((fn [cl]
(java.security.AccessController/doPrivileged
(reify
java.security.PrivilegedAction
(run [_]
(evil cl "(+ 1 2)"))))))
((fn [cl]
(swap! cl-cache assoc clojure-jar
[(System/currentTimeMillis) cl])))))))

(defn naughty-forms? [strang]
(let [nf #{"catch" "finally" "clojure.asm" "hiredman.clojurebot"
Expand Down
83 changes: 65 additions & 18 deletions src/hiredman/sandbox.clj
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,44 @@

(def *default-timeout* 10) ; in seconds

(def *secure?* false)

(defmacro defering-security-manager [sm]
(let [sm-name (gensym 'sm)
methods (for [[method-name methods]
(group-by #(.getName %)
(.getDeclaredMethods SecurityManager))
:when (.startsWith method-name "check")
:let [methods (filter
#(java.lang.reflect.Modifier/isPublic
(.getModifiers %))
methods)]]
`(~(symbol method-name)
~@(for [[argc [method]] (group-by
#(count (.getParameterTypes %))
methods)
:let [args (vec (map-indexed
(comp symbol str)
(take argc (repeat "arg"))))]]
`(~args
(println ~method-name *secure?*)
(when *secure?*
(. ~sm-name ~(symbol method-name) ~@args))))))]
`(let [~sm-name ~sm]
(proxy [SecurityManager] []
~@methods))))

(defn enable-security-manager []
(System/setSecurityManager (SecurityManager.)))
(println "enable-security-manager")
(System/setSecurityManager
(let [sm (SecurityManager.)]
(defering-security-manager sm))))

;;;;;;;; Chousuke
(defn thunk-timeout [thunk seconds]
(let [task (FutureTask. thunk)
(let [task (FutureTask.
#(binding [*secure?* true]
(thunk)))
thr (Thread. task)]
(try
(.start thr)
Expand Down Expand Up @@ -151,16 +183,21 @@
(let [old-cl (.getContextClassLoader (Thread/currentThread))]
(try
(.setContextClassLoader (Thread/currentThread) cl)
(let [rt (.loadClass cl "clojure.lang.RT")
(let [secure *secure?*
rt (.loadClass cl "clojure.lang.RT")
compiler (.loadClass cl "clojure.lang.Compiler")
var- (fn [s]
(call-method
rt :var [String String] nil (namespace s) (name s)))
class (fn [x] (.loadClass cl (name x)))
deref (fn [x] (call-method (.getClass x) :deref [] x))
invoke (fn [x & args] (call-method (.getClass x) :invoke []))
read-string (fn [s] (call-method rt :readString [String] nil s))
eval (fn [f] (call-method compiler :eval [Object] nil f))]
read-string (fn [s]
(binding [*secure?* secure]
(call-method rt :readString [String] nil s)))
eval (fn [f]
(binding [*secure?* secure]
(call-method compiler :eval [Object] nil f)))]
(thunk-timeout
(fn []
(sandbox #(eval (read-string (format "(pr-str %s)" form-str)))
Expand Down Expand Up @@ -188,18 +225,18 @@
(let [f# (read-string ~_string)
good?# (if (and (coll? f#)
(not (empty? f#)))
(when (not
(some '~*bad-forms*
(tree-seq coll?
(fn [i#]
(let [a# (macroexpand
i#)]
(if (coll? a#)
(seq a#)
(list a#))))
f#)))
f#)
true)
(when (not
(some '~*bad-forms*
(tree-seq coll?
(fn [i#]
(let [a# (macroexpand
i#)]
(if (coll? a#)
(seq a#)
(list a#))))
f#)))
f#)
true)
r# (pr-str (try
(when-not good?#
(throw (Exception. "SANBOX DENIED")))
Expand All @@ -209,5 +246,15 @@
[(.toString (doto o# .close))
(.toString (doto e# .close))
r#]))))
thunk (fn [] (evil class-loader f))]
thunk (fn []
(binding [*secure?* true]
(evil class-loader f)))]
(thunk)))

(->> SecurityManager .getDeclaredMethods
(map bean)
(filter
#(java.lang.reflect.Modifier/isPublic (:modifiers %)))
(filter #(.startsWith (:name %) "check")))


0 comments on commit 9641a9a

Please sign in to comment.