Re: [systemd-devel] [PATCH/RFC] FuseMAC: user space MAC in systemd
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
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
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 =