Commit e24a9b5d authored by thomie's avatar thomie
Browse files

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
parent 01809bcd
...@@ -650,6 +650,7 @@ static void procRtsOpts (int rts_argc0, ...@@ -650,6 +650,7 @@ static void procRtsOpts (int rts_argc0,
at the start each iteration and checked at the end. */ at the start each iteration and checked at the end. */
rtsBool option_checked = rtsFalse; rtsBool option_checked = rtsFalse;
// See Note [OPTION_SAFE vs OPTION_UNSAFE].
#define OPTION_SAFE option_checked = rtsTrue; #define OPTION_SAFE option_checked = rtsTrue;
#define OPTION_UNSAFE checkUnsafe(rtsOptsEnabled); option_checked = rtsTrue; #define OPTION_UNSAFE checkUnsafe(rtsOptsEnabled); option_checked = rtsTrue;
...@@ -854,7 +855,6 @@ error = rtsTrue; ...@@ -854,7 +855,6 @@ error = rtsTrue;
THREADED_BUILD_ONLY( THREADED_BUILD_ONLY(
int nNodes; int nNodes;
int proc = (int)getNumberOfProcessors(); int proc = (int)getNumberOfProcessors();
OPTION_SAFE;
nNodes = strtol(rts_argv[arg]+5, (char **) NULL, 10); nNodes = strtol(rts_argv[arg]+5, (char **) NULL, 10);
if (nNodes > proc) { nNodes = proc; } if (nNodes > proc) { nNodes = proc; }
...@@ -1011,15 +1011,15 @@ error = rtsTrue; ...@@ -1011,15 +1011,15 @@ error = rtsTrue;
) break; ) break;
case 'h': /* serial heap profile */ case 'h': /* serial heap profile */
#if !defined(PROFILING) #if !defined(PROFILING)
OPTION_UNSAFE;
switch (rts_argv[arg][2]) { switch (rts_argv[arg][2]) {
case '\0': case '\0':
case 'T': case 'T':
OPTION_UNSAFE;
RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_CLOSURE_TYPE; RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_CLOSURE_TYPE;
break; break;
default: default:
errorBelch("invalid heap profile option: %s",rts_argv[arg]); OPTION_SAFE;
error = rtsTrue; PROFILING_BUILD_ONLY();
} }
#else #else
OPTION_SAFE; OPTION_SAFE;
...@@ -1971,3 +1971,41 @@ void freeRtsArgs(void) ...@@ -1971,3 +1971,41 @@ void freeRtsArgs(void)
freeProgArgv(); freeProgArgv();
freeRtsArgv(); 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.
*/
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment