Jump to content
Main menu
Main menu
move to sidebar
hide
Navigation
Haskell
Wiki community
Recent changes
Random page
HaskellWiki
Search
Search
Create account
Log in
Personal tools
Create account
Log in
Pages for logged out editors
learn more
Contributions
Talk
Editing
Safely running untrusted Haskell code
(section)
Page
Discussion
English
Read
Edit
View history
Tools
Tools
move to sidebar
hide
Actions
Read
Edit
View history
General
What links here
Related changes
Special pages
Page information
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
=== The implementation === :''Note: This section refers to the old Lambdabot evaluator; as of 2009, lambdabot calls out to [http://hackage.haskell.org/package/mueval mueval], which while it uses many of the same techniques, is structured differently.'' The evaluator is essentially a function, <hask>eval :: String -> IO String</hask>, which takes a random Haskell string, verifies it, compiles it, and evaluates the result, returning a <code>String</code> representing the result, back over the network. This function is implemented as two separate processes: * [http://www.cse.unsw.edu.au/~dons/code/lambdabot/Plugin/Eval.hs Driver/simple verifier] * [http://www.cse.unsw.edu.au/~dons/code/lambdabot/scripts/RunPlugs.hs Evaluator binary] The driver reads a <code>String</code> from the network, and then subjects it to a simple test: # The expression is parsed as a Haskell 98 expression, hopefully preventing code injection (''is this true? and can any string that can parse as a valid Haskell expression become something more sinister when put in a particular context?'') # If the string parses as a Haskell 98 expression, the <code>runplugs</code> process is then forked to evaluate the string, and the following checks are put in place: ::{| | * Only a trusted module set is imported, avoiding <code>unsafePerformIO</code>, <code>unsafeIOtoST</code> and such like. * Module imports are disallowed * Time and space limitations on the <code>runplugs</code> process are set by the OS <code>rlimit</code> facility * The expression type checked, enforcing lack of memory errors * Because the user code is not at the beginning of the file, malicious <code>{-# LANGUAGE #-}</code> and <code>{-# OPTIONS #-}</code> flags are ignored * Only <code>-fextended-default-rules</code> are allowed as language extensions over Haskell 98. * The resulting object file is dynamically linked only into the throw-away <code>runplugs</code> instance * Even if all went well, the first 2048 characters of the output string are returned to the caller (no infinite output DoS) |} A few other niceties are provided: * The expression is bound to a random identifier (harmless to guess), in order to allow nice line error messages with line pragmas. * The expression is wrapped in <code>show</code>. * A catch-all instance of <code>Show</code> in terms of <code>Typable</code> is provided, to display non-displayable objects in a more useful way (e.g. <code>putStrLn</code> β <code>[Char] -> IO ()</code>) * It is compiled to native code with <code>-fasm</code> for speed (compilation time is negligible compared to IRC lag) * The value is evaluated inside an exception handler; if an exception is thrown, the first 1024 characters of the exception string are returned.
Summary:
Please note that all contributions to HaskellWiki are considered to be released under simple permissive license (see
HaskellWiki:Copyrights
for details). If you don't want your writing to be edited mercilessly and redistributed at will, then don't submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource.
DO NOT SUBMIT COPYRIGHTED WORK WITHOUT PERMISSION!
Cancel
Editing help
(opens in new window)
Toggle limited content width