From 9f1b5bdb8b23b2cbf7d1a8700296e3f7ba0a9647 Mon Sep 17 00:00:00 2001 From: William Hua Date: Thu, 16 Feb 2017 10:27:22 -0500 Subject: add apparmor confinement check --- configure.ac | 4 ++ proxy/Makefile.am | 7 ++++ proxy/confinement-apparmor.c | 90 ++++++++++++++++++++++++++++++++++++++++++++ proxy/confinement.c | 4 +- proxy/confinement.h | 5 +++ 5 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 proxy/confinement-apparmor.c diff --git a/configure.ac b/configure.ac index 8fbff08..f908a9a 100644 --- a/configure.ac +++ b/configure.ac @@ -47,6 +47,10 @@ GTK_DOC_CHECK([1.15]) # Dependencies PKG_CHECK_MODULES(glib, glib-2.0 >= 2.44.0) PKG_CHECK_MODULES(gio, gio-unix-2.0) +PKG_CHECK_MODULES(apparmor, libapparmor, enable_apparmor=yes, enable_apparmor=no) +AM_CONDITIONAL(ENABLE_APPARMOR, test "$enable_apparmor" = "yes") +AC_SUBST(apparmor_CFLAGS) +AC_SUBST(apparmor_LIBS) AC_ARG_WITH(gio_modules_dir, [ --with-gio-modules-dir=PATH choose directory for the GIO module, [default=LIBDIR/gio/modules]], giomodulesdir="$withval", giomodulesdir=${libdir}/gio/modules) AC_SUBST(giomodulesdir) diff --git a/proxy/Makefile.am b/proxy/Makefile.am index 7faa269..ad3e30a 100644 --- a/proxy/Makefile.am +++ b/proxy/Makefile.am @@ -14,12 +14,19 @@ dconf_proxy_LDADD = \ dconf_proxy_SOURCES = \ ../gvdb/gvdb-builder.c \ confinement.c \ + confinement-apparmor.c \ confinement-flatpak.c \ confinement.h \ permissions.c \ permissions.h \ proxy.c +if ENABLE_APPARMOR +dconf_proxy_CPPFLAGS = -DHAVE_APPARMOR +dconf_proxy_CFLAGS += $(apparmor_CFLAGS) +dconf_proxy_LDADD += $(apparmor_LIBS) +endif + DISTCLEANFILES = ca.desrt.dconf.service ca.desrt.dconf.Proxy.service: Makefile diff --git a/proxy/confinement-apparmor.c b/proxy/confinement-apparmor.c new file mode 100644 index 0000000..92eca60 --- /dev/null +++ b/proxy/confinement-apparmor.c @@ -0,0 +1,90 @@ +/* + * Copyright © 2017 Canonical Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the licence, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Author: William Hua + */ + +#define _GNU_SOURCE + +#include "confinement.h" + +#ifdef HAVE_APPARMOR +#include +#endif /* HAVE_APPARMOR */ + +gboolean +confinement_check_apparmor (GVariant *credentials, + gboolean *out_is_confined, + Permissions *out_permissions) +{ +#ifdef HAVE_APPARMOR + g_autofree gchar *context = NULL; + const gchar *label; + aa_dconf_info info; + gchar **readable; + gchar **writable; + gint i; + + if (!g_variant_lookup (credentials, "LinuxSecurityLabel", "^ay", &context)) + { + g_warning ("Caller credentials are missing LinuxSecurityLabel field"); + return FALSE; + } + + label = aa_splitcon (context, NULL); + + if (!g_strcmp0 (label, "unconfined")) + { + *out_is_confined = FALSE; + return TRUE; + } + + if (aa_query_dconf_info (label, &info)) + { + g_warning ("Kernel has no dconf data for %s", label); + return FALSE; + } + + /* Merge the readable path lists */ + readable = g_new (gchar *, info.r_n + info.ar_n + 1); + for (i = 0; i < info.r_n; i++) + readable[i] = g_strdup (info.r_paths[i]); + for (i = 0; i < info.ar_n; i++) + readable[info.r_n + i] = g_strdup (info.ar_paths[i]); + readable[info.r_n + info.ar_n] = NULL; + + /* Merge the writable path lists */ + writable = g_new (gchar *, info.rw_n + info.arw_n + 1); + for (i = 0; i < info.rw_n; i++) + writable[i] = g_strdup (info.rw_paths[i]); + for (i = 0; i < info.arw_n; i++) + writable[info.rw_n + i] = g_strdup (info.arw_paths[i]); + writable[info.rw_n + info.arw_n] = NULL; + + aa_clear_dconf_info (&info); + + permission_list_init (&out_permissions->readable, readable); + permission_list_init (&out_permissions->writable, writable); + out_permissions->ipc_dir = g_build_filename (g_get_user_runtime_dir (), label, NULL); + out_permissions->app_id = g_strdup (label); + + *out_is_confined = TRUE; +#else + *out_is_confined = FALSE; +#endif /* HAVE_APPARMOR */ + + return TRUE; +} diff --git a/proxy/confinement.c b/proxy/confinement.c index 2f1e295..21d5f32 100644 --- a/proxy/confinement.c +++ b/proxy/confinement.c @@ -30,8 +30,8 @@ confinement_check (GVariant *credentials, if (!confinement_check_flatpak (credentials, &is_confined, &permissions)) return FALSE; - if (!is_confined) - /* snap goes here */; + if (!is_confined && !confinement_check_apparmor (credentials, &is_confined, &permissions)) + return FALSE; *out_is_confined = is_confined; diff --git a/proxy/confinement.h b/proxy/confinement.h index 9b6b625..04034a2 100644 --- a/proxy/confinement.h +++ b/proxy/confinement.h @@ -30,3 +30,8 @@ gboolean confinement_check_flatpak (GVariant *credentials, gboolean *out_is_confined, Permissions *out_permissions); + +gboolean +confinement_check_apparmor (GVariant *credentials, + gboolean *out_is_confined, + Permissions *out_permissions); -- cgit v1.2.1