[dconf/wip/apparmor] add apparmor confinement check



commit fc4b0d592679d1bc672ccd10763fe81343c00b8f
Author: William Hua <william hua canonical com>
Date:   Thu Feb 16 10:27:22 2017 -0500

    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(-)
---
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..2903444 100644
--- a/proxy/Makefile.am
+++ b/proxy/Makefile.am
@@ -20,6 +20,13 @@ dconf_proxy_SOURCES = \
        permissions.h                   \
        proxy.c
 
+if ENABLE_APPARMOR
+dconf_proxy_CPPFLAGS = -DHAVE_APPARMOR
+dconf_proxy_CFLAGS += $(apparmor_CFLAGS)
+dconf_proxy_LDADD += $(apparmor_LIBS)
+dconf_proxy_SOURCES += confinement-apparmor.c
+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 <http://www.gnu.org/licenses/>.
+ *
+ * Author: William Hua <william hua canonical com>
+ */
+
+#define _GNU_SOURCE
+
+#include "confinement.h"
+
+#ifdef HAVE_APPARMOR
+#include <sys/apparmor.h>
+#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);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]