Implement setting app specific environment vars #3

Closed
wants to merge 2 commits into
from
Jump to file or symbol
Failed to load files and symbols.
+147 −0
Split
@@ -70,6 +70,9 @@
# reading seccomp filters
/var/lib/snapd/seccomp/profiles/* r,
+ # reading the environment
+ /var/lib/snapd/environment/* r,
+
# set up snap-specific private /tmp dir
capability chown,
/tmp/ w,
View
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2016 Canonical Ltd
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "utils.h"
+
+char *env_profile_dir = "/var/lib/snapd/environment/";
+
+void setenv_from_line(char *line)
+{
+ const char *name = NULL;
+ const char *value = NULL;
+ debug("reading line: '%s'", line);
+
+ if (strlen(line) == 0)
+ return;
+
+ // kill final \n
+ char *nl = strchr(line, '\n');
+ if (nl != NULL)
+ *nl = 0;
+
+ // find first "="
+ char *t = strchr(line, '=');
+ if (t == NULL)
+ return;
+
+ // before the "=" is the env key
+ *t = 0;
+ name = line;
+
+ // after the "=" is the env value
+ // note that there is always a t+1 because fgets() gives us a final \0
+ if (*(t + 1) == 0)
+ return;
+ value = t + 1;
+
+ debug("setenv: '%s'='%s'", name, value);
+ if (setenv(name, value, 0) != 0)
+ die("setenv failed");
+}
+
+void apply_environment_file(const char *env_tag)
+{
+ debug("apply_environment_file %s", env_tag);
+
+ if (secure_getenv("SNAPPY_LAUNCHER_ENVIRONMENT_DIR") != NULL)
+ env_profile_dir =
+ secure_getenv("SNAPPY_LAUNCHER_ENVIRONMENT_DIR");
+
+ char env_path[512]; // ought to be enough for everybody
+ must_snprintf(env_path, sizeof(env_path), "%s/%s", env_profile_dir,
+ env_tag);
+
+ char buf[1024]; // LD_LIBRARY_PATH can get long
+ debug("reading '%s'", env_path);
+ FILE *f = fopen(env_path, "r");
+ if (f == NULL) {
+ return;
+ }
+ while (fgets(buf, sizeof(buf), f) != NULL) {
+ setenv_from_line(buf);
+ }
+ fclose(f);
+}
View
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2016 Canonical Ltd
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef CORE_LAUNCHER_ENVIRONMENT_H
+#define CORE_LAUNCHER_ENVIRONMENT_H
+
+void apply_environment_file(const char *env_profile);
+
+#endif
View
@@ -43,6 +43,7 @@
#include "utils.h"
#include "seccomp.h"
+#include "environment.h"
#define MAX_BUF 1000
@@ -569,6 +570,9 @@ int main(int argc, char **argv)
if (real_uid != 0 && (getgid() == 0 || getegid() == 0))
die("permanently dropping privs did not work");
}
+ // apply environment file as *non* root
+ apply_environment_file(aa_profile);
+
// and exec the new binary
execv(binary, (char *const *)&argv[NR_ARGS]);
perror("execv failed");
View
@@ -7,9 +7,13 @@ TMP="$(mktemp -d)"
trap 'rm -rf $TMP' EXIT
export SNAPPY_LAUNCHER_SECCOMP_PROFILE_DIR="$TMP"
+export SNAPPY_LAUNCHER_ENVIRONMENT_DIR="$TMP/environment"
+mkdir "$SNAPPY_LAUNCHER_ENVIRONMENT_DIR"
+
export SNAPPY_LAUNCHER_INSIDE_TESTS="1"
export UBUNTU_CORE_LAUNCHER_NO_ROOT=1
+
FAIL() {
printf ": FAIL\n"
exit 1
View
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+set -e
+
+. $(pwd)/common.sh
+
+test() {
+ needle="$1"
+ cat >$TMP/environment/myprofile <<EOF
+$needle
+EOF
+ if ! $L snap.name.app myprofile /usr/bin/env |grep -q "$needle"; then
+ FAIL
+ fi
+
+ PASS
+}
+
+cat >$TMP//myprofile <<EOF
+@unrestricted
+EOF
+
+
+printf "Set environment from launcher"
+test "LD_LIBRARY_PATH=/some/path"
+
+printf "With '=' in environment"
+test "FOO=bar=baz"