Commit ad6bf9c0 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Varnishd needs to run the systems C-compiler to compile the VCL code.

For security reasons, we run the C-compiler in a sandbox process
which by default uses the same (non-)privileges as the other sandboxes
(VCL compiler, test-loader process and the worker process).

On some systems access to the C-compiler is limited, also for reasons
of security, and varnishd will fail to compile VCL code, unless all
the sandboxes are given access to the C-compiler.

Add a new parameter "group_cc" which adds a single gid to the grouplist
of the sandbox which executes the cc_command, for the benefit of such
systems.

Do some slightly related polishing of the docs/help-texts in this area
while here anyway.

Fixes #1521
parent aa01242a
......@@ -63,6 +63,10 @@ struct params {
char *group;
gid_t gid;
/* Extra group for compiler access */
char *group_cc;
gid_t gid_cc;
/* TTL used for lack of anything better */
double default_ttl;
......
......@@ -90,6 +90,10 @@ static const char PROTECTED_TEXT[] =
"\n\n"
"NB: This parameter is protected and can not be changed.";
static const char ONLY_ROOT_TEXT[] =
"\n\n"
"NB: This parameter only works of varnishd is run as root.";
/*--------------------------------------------------------------------*/
......@@ -265,6 +269,8 @@ mcf_param_show(struct cli *cli, const char * const *av, void *priv)
mcf_wrap(cli, WIZARD_TEXT);
if (pp->flags & PROTECTED)
mcf_wrap(cli, PROTECTED_TEXT);
if (pp->flags & ONLY_ROOT)
mcf_wrap(cli, ONLY_ROOT_TEXT);
VCLI_Out(cli, "\n\n");
}
}
......@@ -556,6 +562,10 @@ MCF_DumpRstParam(void)
printf("%swizard", q);
q = ", ";
}
if (pp->flags & ONLY_ROOT) {
printf("%sonly_root", q);
q = ", ";
}
printf("\n");
}
printf("\n");
......
......@@ -47,6 +47,7 @@ struct parspec {
#define WIZARD (1<<4)
#define PROTECTED (1<<5)
#define OBJ_STICKY (1<<6)
#define ONLY_ROOT (1<<7)
const char *def;
const char *units;
};
......@@ -56,6 +57,7 @@ tweak_t tweak_bytes;
tweak_t tweak_bytes_u;
tweak_t tweak_double;
tweak_t tweak_group;
tweak_t tweak_group_cc;
tweak_t tweak_listen_address;
tweak_t tweak_poolparam;
tweak_t tweak_string;
......
......@@ -53,11 +53,19 @@
struct parspec mgt_parspec[] = {
{ "user", tweak_user, NULL, NULL, NULL,
"The unprivileged user to run as.",
MUST_RESTART,
MUST_RESTART | ONLY_ROOT,
"" },
{ "group", tweak_group, NULL, NULL, NULL,
"The unprivileged group to run as.",
MUST_RESTART,
MUST_RESTART | ONLY_ROOT,
"" },
{ "group_cc", tweak_group_cc, NULL, NULL, NULL,
"On some systems the C-compiler is restricted so not"
" everybody can run it. This parameter makes it possible"
" to add an extra group to the sandbox process which runs the"
" cc_command, in order to gain access to such a restricted"
" c-compiler.",
ONLY_ROOT,
"" },
{ "default_ttl", tweak_timeout, &mgt_param.default_ttl,
"0", NULL,
......
......@@ -433,6 +433,38 @@ tweak_group(struct vsb *vsb, const struct parspec *par, const char *arg)
return (0);
}
/*--------------------------------------------------------------------
* XXX: see comment for tweak_user, same thing here.
*/
int
tweak_group_cc(struct vsb *vsb, const struct parspec *par, const char *arg)
{
struct group *gr;
(void)par;
if (arg != NULL) {
if (*arg != '\0') {
gr = getgrnam(arg);
if (gr == NULL) {
VSB_printf(vsb, "Unknown group");
return(-1);
}
REPLACE(mgt_param.group_cc, gr->gr_name);
mgt_param.gid_cc = gr->gr_gid;
} else {
REPLACE(mgt_param.group_cc, "");
mgt_param.gid_cc = 0;
}
} else if (strlen(mgt_param.group_cc) > 0) {
VSB_printf(vsb, "%s (%d)",
mgt_param.group_cc, (int)mgt_param.gid_cc);
} else {
VSB_printf(vsb, "<not set>");
}
return (0);
}
/*--------------------------------------------------------------------*/
static void
......
......@@ -51,6 +51,7 @@
#include <grp.h>
#include <stdio.h>
#include <syslog.h>
#include <string.h>
#include <unistd.h>
#include "mgt/mgt.h"
......@@ -62,14 +63,27 @@
static void __match_proto__(mgt_sandbox_f)
mgt_sandbox_unix(enum sandbox_e who)
{
(void)who;
if (geteuid() == 0) {
XXXAZ(setgid(mgt_param.gid));
XXXAZ(initgroups(mgt_param.user, mgt_param.gid));
XXXAZ(setuid(mgt_param.uid));
} else {
#define NGID 10
gid_t gid_list[NGID];
int i;
if (geteuid() != 0) {
REPORT0(LOG_INFO, "Not running as root, no priv-sep");
return;
}
XXXAZ(setgid(mgt_param.gid));
XXXAZ(initgroups(mgt_param.user, mgt_param.gid));
if (who == SANDBOX_CC && strlen(mgt_param.group_cc) > 0) {
/* Add the optional extra group for the C-compiler access */
i = getgroups(NGID, gid_list);
assert(i >= 0);
gid_list[i++] = mgt_param.gid_cc;
XXXAZ(setgroups(i, gid_list));
}
XXXAZ(setuid(mgt_param.uid));
}
#endif
......
varnishtest "304 body handling with ESI"
server s1 {
rxreq
txresp -hdr "Last-Modified: Wed, 04 Jun 2014 08:48:52 GMT" \
-body {<html><esi:include src="/bar"/>}
rxreq
expect req.url == "/bar"
txresp -body {<html>}
} -start
varnish v1 -vcl+backend {
sub vcl_backend_response {
set beresp.do_esi = true;
}
} -start
client c1 {
txreq
rxresp
expect resp.bodylen == 12
expect resp.status == 200
txreq -hdr "If-Modified-Since: Wed, 04 Jun 2014 08:48:52 GMT"
rxresp
expect resp.status == 304
expect resp.bodylen == 0
} -run
......@@ -226,6 +226,15 @@ restart
reload
The VCL programs must be reloaded for this parameter to take effect.
experimental
We're not really sure about this parameter, tell us what you find.
wizard
Do not touch unless you *really* know what you're doing.
only_root
Only works if varnishd is running as root.
Here is a list of all parameters, current as of last time we
remembered to update the manual page. This text is produced from the
same text you will find in the CLI if you use the param.show command,
......
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