summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Miedema <thomasmiedema@gmail.com>2016-01-25 20:07:31 +0100
committerThomas Miedema <thomasmiedema@gmail.com>2016-01-26 16:07:08 +0100
commite24a9b5de00bc2669a52a1f9905bd40e7be0d857 (patch)
tree1285faaa5b1c495ab85aae7b9294c19a67081160
parent01809bcd4c9066244d705360f0d9a3a2176385f4 (diff)
downloadhaskell-e24a9b5de00bc2669a52a1f9905bd40e7be0d857.tar.gz
Nicer error on +RTS -hc without -rtsopts or -prof
Before: * without -rtsopts: Most RTS options are disabled. Link with -rtsopts to enable them. * with -rtsopts: invalid heap profile option: -hc After: * the flag -hc requires the program to be built with -prof Copy `Note [OPTION_SAFE vs OPTION_UNSAFE]` from commit 8c7ad0bd. Reviewed by: bgamari Differential Revision: https://phabricator.haskell.org/D1845
-rw-r--r--rts/RtsFlags.c46
1 files changed, 42 insertions, 4 deletions
diff --git a/rts/RtsFlags.c b/rts/RtsFlags.c
index 56f4420142..46d14090f0 100644
--- a/rts/RtsFlags.c
+++ b/rts/RtsFlags.c
@@ -650,6 +650,7 @@ static void procRtsOpts (int rts_argc0,
at the start each iteration and checked at the end. */
rtsBool option_checked = rtsFalse;
+// See Note [OPTION_SAFE vs OPTION_UNSAFE].
#define OPTION_SAFE option_checked = rtsTrue;
#define OPTION_UNSAFE checkUnsafe(rtsOptsEnabled); option_checked = rtsTrue;
@@ -854,7 +855,6 @@ error = rtsTrue;
THREADED_BUILD_ONLY(
int nNodes;
int proc = (int)getNumberOfProcessors();
- OPTION_SAFE;
nNodes = strtol(rts_argv[arg]+5, (char **) NULL, 10);
if (nNodes > proc) { nNodes = proc; }
@@ -1011,15 +1011,15 @@ error = rtsTrue;
) break;
case 'h': /* serial heap profile */
#if !defined(PROFILING)
- OPTION_UNSAFE;
switch (rts_argv[arg][2]) {
case '\0':
case 'T':
+ OPTION_UNSAFE;
RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_CLOSURE_TYPE;
break;
default:
- errorBelch("invalid heap profile option: %s",rts_argv[arg]);
- error = rtsTrue;
+ OPTION_SAFE;
+ PROFILING_BUILD_ONLY();
}
#else
OPTION_SAFE;
@@ -1971,3 +1971,41 @@ void freeRtsArgs(void)
freeProgArgv();
freeRtsArgv();
}
+
+
+/*
+Note [OPTION_SAFE vs OPTION_UNSAFE]
+
+Ticket #3910 originally pointed out that the RTS options are a potential
+security problem. For example the -t -s or -S flags can be used to
+overwrite files. This would be bad in the context of CGI scripts or
+setuid binaries. So we introduced a system where +RTS processing is more
+or less disabled unless you pass the -rtsopts flag at link time.
+
+This scheme is safe enough but it also really annoyes users. They have
+to use -rtsopts in many circumstances: with -threaded to use -N, with
+-eventlog to use -l, with -prof to use any of the profiling flags. Many
+users just set -rtsopts globally or in project .cabal files. Apart from
+annoying users it reduces security because it means that deployed
+binaries will have all RTS options enabled rather than just profiling
+ones.
+
+So now, we relax the set of RTS options that are available in the
+default -rtsopts=some case. For "deployment" ways like vanilla and
+-threaded we remain quite conservative. Only --info -? --help are
+allowed for vanilla. For -threaded, -N and -N<x> are allowed with a
+check that x <= num cpus.
+
+For "developer" ways like -debug, -eventlog, -prof, we allow all the
+options that are special to that way. Some of these allow writing files,
+but the file written is not directly under the control of the attacker.
+For the setuid case (where the attacker would have control over binary
+name, current dir, local symlinks etc) we check if the process is
+running setuid/setgid and refuse all RTS option processing. Users would
+need to use -rtsopts=all in this case.
+
+We are making the assumption that developers will not deploy binaries
+built in the -debug, -eventlog, -prof ways. And even if they do, the
+damage should be limited to DOS, information disclosure and writing
+files like <progname>.eventlog, not arbitrary files.
+*/