Implement secure_getenv(3) if not provided by stdlib #147

Merged
merged 4 commits into from Sep 19, 2016
View
@@ -30,7 +30,7 @@ AC_FUNC_CHOWN
AC_FUNC_ERROR_AT_LINE
AC_FUNC_FORK
AC_FUNC_STRNLEN
-AC_CHECK_FUNCS([mkdir regcomp setenv strdup strerror])
+AC_CHECK_FUNCS([mkdir regcomp setenv strdup strerror secure_getenv])
AC_ARG_WITH([unit-tests],
AC_HELP_STRING([--without-unit-tests], [do not build unit test programs]),
@@ -161,15 +161,5 @@ AS_IF([test "x$enable_caps_over_setuid" = "xyes"], [
AC_DEFINE([CAPS_OVER_SETUID], [1],
[Use capabilities rather than setuid bit])])
-AC_CHECK_FUNCS([secure_getenv], [], [
- AC_MSG_WARN([
- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
- X X
- X secure_getenv missing; suid binaries at risk X
- X X
- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX])
- AC_DEFINE([secure_getenv], [getenv],
- [Fallback for missing secure_getenv])])
-
AC_CONFIG_FILES([Makefile src/Makefile tests/Makefile docs/Makefile])
AC_OUTPUT
View
@@ -10,6 +10,8 @@ snap_discard_ns_SOURCES = \
user-support.h \
utils.c \
utils.h \
+ secure-getenv.c \
+ secure-getenv.h \
cleanup-funcs.c \
cleanup-funcs.h \
mountinfo.c \
@@ -32,6 +34,8 @@ snap_confine_SOURCES = \
sc-main.h \
utils.c \
utils.h \
+ secure-getenv.c \
+ secure-getenv.h \
snap.c \
snap.h \
classic.c \
View
@@ -0,0 +1,31 @@
+/*
+ * 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/>.
+ *
+ */
+#include "secure-getenv.h"
+
+#include <stdlib.h>
+#include <sys/auxv.h>
+
+#ifndef HAVE_SECURE_GETENV
+char *secure_getenv(const char *name)
@chipaca

chipaca Sep 19, 2016

Member

you could add __attribute__((nonnull)) so that gcc and clang warn you if you pass in null, i think?

@chipaca

chipaca Sep 19, 2016

Member

also warn_unused_result fwiw

@zyga

zyga Sep 19, 2016

Collaborator

Nice, I'll do it

+{
+ unsigned long secure = getauxval(AT_SECURE);
+ if (secure != 0) {
+ return NULL;
+ }
+ return getenv(name);
+}
+#endif // ! HAVE_SECURE_GETENV
View
@@ -0,0 +1,36 @@
+/*
+ * 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 SNAP_CONFINE_SECURE_GETENV_H
+#define SNAP_CONFINE_SECURE_GETENV_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifndef HAVE_SECURE_GETENV
+/**
+ * Secure version of getenv()
+ *
+ * This version returns NULL if the process is running within a secure context.
+ * This is exactly the same as the GNU extension to the standard library. It is
+ * only used when glibc is not available.
+ **/
+char *secure_getenv(const char *name)
+ __attribute__ ((nonnull(1), warn_unused_result));
+#endif // ! HAVE_SECURE_GETENV
+
+#endif