Re: [systemd-devel] [PATCH/RFC] FuseMAC: user space MAC in systemd

2015-03-09 Thread Topi Miettinen
On 03/08/15 23:16, Lennart Poettering wrote:
 On Mon, 02.03.15 22:49, Topi Miettinen (toiwo...@gmail.com) wrote:
 
 Intercept and filter filesystem operations of processes launched
 by systemd with FUSE.

 Implement learning, enforcing and auto enforcing/learning modes,
 enabled with new exec directive FuseMAC.

 FS operations can be filtered by access type (e.g. getattr/read,
 cf. AppArmor or TOMOYO Linux) or for more fine grained control,
 which area of the file is being accessed.

 Due to limitations of FUSE, API file systems can't be intercepted.

 Also the patch seems to trigger bugs in kernel (hang CPU).
 
 Hmm, if I understand this patch right, then you proxy all file system
 access through a userspace fuse tool to enforce additional access
 restrictions?

All except file systems like /dev, /proc, /sys etc.

 Well, I am pretty sure that systemd should not be in the business of
 implementing a new access control mechanism. It's fine to expose ones
 that are supported in the kernel in ways, or even using things like
 namespacing to implement access control, but it really shouldn't be
 systemd that is the one enforcing file access rights here, I am very
 sure. It might be the place to encode and configure policy, but not
 the place to enforce it.

OK. It may be better design to keep it separate anyway, for example library.

 I think this is better done outside of systemd, and quite frankly, in
 the kernel, already for performance reasons.

Some of the access control is already performed by kernel (due to flag
default_permissions), I'm only adding on top of that. Performance isn't
so bad either.

Not doing the access control in kernel is actually the strength here. I
don't think it would be reasonable to expect kernel to support fine
grained byte range type of access control or automatic mode. From user
space it's possible to perform very complex checks, involve external
state and even query the user.

For example, one of the nice ideas in TOMOYO Linux is the ability to
base rules on the ancestry of a process, like kernel /sbin/init
/usr/bin/dbus-daemon is different from kernel /sbin/init
/usr/bin/kdm /usr/bin/dbus-daemon. This would be pretty easy to
implement to FuseMAC. I'm not sure this would be possible with SELinux
and it's a weakness in AppArmor.

Byte ranges let FuseMAC differentiate between, for example, 'bash -c
exit' and 'bash -c echo foo;exit', which is far beyond what any current
MAC can do.

The kernel could be a bit more helpful, now it's not possible to know if
reading a file happens due to mmap() or read(). Maybe this information
could be delivered by FUSE as well, or we could ptrace() the process.
Then FuseMAC would match AppArmor's 'm' (mmap) flag.

 Sorry!

NP.

-Topi

 Lennart
 

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [PATCH/RFC] FuseMAC: user space MAC in systemd

2015-03-08 Thread Lennart Poettering
On Mon, 02.03.15 22:49, Topi Miettinen (toiwo...@gmail.com) wrote:

 Intercept and filter filesystem operations of processes launched
 by systemd with FUSE.
 
 Implement learning, enforcing and auto enforcing/learning modes,
 enabled with new exec directive FuseMAC.
 
 FS operations can be filtered by access type (e.g. getattr/read,
 cf. AppArmor or TOMOYO Linux) or for more fine grained control,
 which area of the file is being accessed.
 
 Due to limitations of FUSE, API file systems can't be intercepted.
 
 Also the patch seems to trigger bugs in kernel (hang CPU).

Hmm, if I understand this patch right, then you proxy all file system
access through a userspace fuse tool to enforce additional access
restrictions?

Well, I am pretty sure that systemd should not be in the business of
implementing a new access control mechanism. It's fine to expose ones
that are supported in the kernel in ways, or even using things like
namespacing to implement access control, but it really shouldn't be
systemd that is the one enforcing file access rights here, I am very
sure. It might be the place to encode and configure policy, but not
the place to enforce it.

I think this is better done outside of systemd, and quite frankly, in
the kernel, already for performance reasons.

Sorry!

Lennart

-- 
Lennart Poettering, Red Hat
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] [PATCH/RFC] FuseMAC: user space MAC in systemd

2015-03-02 Thread Topi Miettinen
Intercept and filter filesystem operations of processes launched
by systemd with FUSE.

Implement learning, enforcing and auto enforcing/learning modes,
enabled with new exec directive FuseMAC.

FS operations can be filtered by access type (e.g. getattr/read,
cf. AppArmor or TOMOYO Linux) or for more fine grained control,
which area of the file is being accessed.

Due to limitations of FUSE, API file systems can't be intercepted.

Also the patch seems to trigger bugs in kernel (hang CPU).
---
 Makefile.am   |9 +-
 configure.ac  |   13 +
 src/core/dbus-execute.c   |3 +
 src/core/execute.c|   22 +
 src/core/execute.h|   16 +
 src/core/fusemac.c| 1118 +
 src/core/load-fragment-gperf.gperf.m4 |5 +-
 src/core/load-fragment.c  |   31 +
 src/core/load-fragment.h  |1 +
 src/shared/build.h|9 +-
 src/shared/exit-status.c  |3 +
 src/shared/exit-status.h  |1 +
 src/shared/util.c |2 +-
 src/shared/util.h |2 +
 14 files changed, 1231 insertions(+), 4 deletions(-)
 create mode 100644 src/core/fusemac.c

diff --git a/Makefile.am b/Makefile.am
index 9d41a2c..61598bf 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1186,6 +1186,11 @@ libsystemd_core_la_SOURCES = \
src/core/failure-action.c \
src/core/failure-action.h
 
+if HAVE_FUSE
+libsystemd_core_la_SOURCES += \
+   src/core/fusemac.c
+endif
+
 nodist_libsystemd_core_la_SOURCES = \
src/core/load-fragment-gperf.c \
src/core/load-fragment-gperf-nulstr.c
@@ -1198,6 +1203,7 @@ libsystemd_core_la_CFLAGS = \
$(APPARMOR_CFLAGS) \
$(SECCOMP_CFLAGS) \
$(MOUNT_CFLAGS) \
+   $(FUSE_CFLAGS) \
-pthread
 
 libsystemd_core_la_LIBADD = \
@@ -1211,7 +1217,8 @@ libsystemd_core_la_LIBADD = \
$(KMOD_LIBS) \
$(APPARMOR_LIBS) \
$(SECCOMP_LIBS) \
-   $(MOUNT_LIBS)
+   $(MOUNT_LIBS) \
+   $(FUSE_LIBS)
 
 if HAVE_SECCOMP
 libsystemd_core_la_LIBADD += \
diff --git a/configure.ac b/configure.ac
index 419b5d4..12d7937 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1332,6 +1332,19 @@ AC_ARG_ENABLE(ldconfig,
 AM_CONDITIONAL(ENABLE_LDCONFIG, [test x$enable_ldconfig = xyes])
 
 # 
--
+have_fuse=no
+AC_ARG_ENABLE(fuse, AS_HELP_STRING([--disable-fuse], [Disable optional FUSE 
support]))
+if test x$enable_fuse != xno; then
+PKG_CHECK_MODULES(FUSE, [ fuse ],
+[AC_DEFINE(HAVE_FUSE, 1, [Define if FUSE is available]) 
have_fuse=yes], have_fuse=no)
+if test x$have_fuse = xno -a x$enable_fuse = xyes; then
+AC_MSG_ERROR([*** FUSE support requested but libraries not 
found])
+fi
+M4_DEFINES=$M4_DEFINES -DHAVE_FUSE
+fi
+AM_CONDITIONAL(HAVE_FUSE, [test $have_fuse = yes])
+
+# 
--
 # Location of the init scripts as mandated by LSB
 SYSTEM_SYSVINIT_PATH=/etc/init.d
 SYSTEM_SYSVRCND_PATH=/etc/rc.d
diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c
index a9f7971..9611f29 100644
--- a/src/core/dbus-execute.c
+++ b/src/core/dbus-execute.c
@@ -49,6 +49,8 @@ static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_input, 
exec_input, ExecInp
 static BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_protect_home, 
protect_home, ProtectHome);
 static BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_protect_system, 
protect_system, ProtectSystem);
 
+static BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_fusemac_mode, 
fusemac_mode, FuseMAC);
+
 static int property_get_environment_files(
 sd_bus *bus,
 const char *path,
@@ -665,6 +667,7 @@ const sd_bus_vtable bus_exec_vtable[] = {
 SD_BUS_PROPERTY(RestrictAddressFamilies, (bas), 
property_get_address_families, 0, SD_BUS_VTABLE_PROPERTY_CONST),
 SD_BUS_PROPERTY(RuntimeDirectoryMode, u, bus_property_get_mode, 
offsetof(ExecContext, runtime_directory_mode), SD_BUS_VTABLE_PROPERTY_CONST),
 SD_BUS_PROPERTY(RuntimeDirectory, as, NULL, offsetof(ExecContext, 
runtime_directory), SD_BUS_VTABLE_PROPERTY_CONST),
+SD_BUS_PROPERTY(FuseMAC, s, bus_property_get_fusemac_mode, 
offsetof(ExecContext, fusemac_mode), SD_BUS_VTABLE_PROPERTY_CONST),
 SD_BUS_VTABLE_END
 };
 
diff --git a/src/core/execute.c b/src/core/execute.c
index 39ec5ad..08686bd 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -1600,9 +1600,19 @@ static int exec_child(
 log_close();
 } else if (r  0) {
 *exit_status = EXIT_NAMESPACE;
+
+}
+}
+
+#ifdef HAVE_FUSE
+if (context-fusemac_mode != FUSEMAC_NO) {
+r =