make ip vrf exec SELinux-aware
Subsystems (3)
cover make ip vrf exec SELinux-aware
In order to execute a service with VRF, a user should start it using "ip vrf exec". For example, using systemd, the user can encapsulate the ExecStart command in ip vrf exec as shown below:
ExecStart=/usr/sbin/ip vrf exec vrf1 /usr/sbin/httpd $OPTIONS -DFOREGROUND
Assuming SELinux is in permissive mode, starting the service with the current ip vrf implementation results in:
# systemctl start httpd # ps -eafZ | grep httpd system_u:system_r:ifconfig_t:s0 root 597448 1 1 19:22 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND system_u:system_r:ifconfig_t:s0 apache 597452 597448 0 19:22 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND [snip]
This is incorrect, as the context for httpd should be httpd_t, not ifconfig_t.
This happens because ipvrf_exec invokes cmd_exec without setting the correct SELinux context before. Without the correct setting, the process is executed using ip's SELinux context.
This patch series makes "ip vrf exec" SELinux-aware using the setexecfilecon functions, which retrieves the correct context to be used on the next execvp() call.
After this series:
# systemctl start httpd # ps -eafZ | grep httpd system_u:system_r:httpd_t:s0 root 595805 1 0 19:01 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND system_u:system_r:httpd_t:s0 apache 595809 595805 0 19:01 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
Patch series description:
- 1/4 and 2/4 are preliminary changes to make SELinux helper functions used in ss conformant to the SELinux API definitions;
- 3/4 makes SELinux helper functions into a library, so they can be used in other iproute tools - such as ip - when iproute is compiled without SELinux support;
- 4/4, finally, add setexecfilecon to the SELinux stubs, and uses it to actually set the correct file context for the command to be executed.
Andrea Claudi (4):
ss: make is_selinux_enabled stub work like in SELinux
ss: make SELinux stub functions conformant to API definitions
lib: add SELinux include and stub functions
ip vrf: make ipvrf_exec SELinux-aware
include/selinux.h | 10 ++++++++++ ip/ipvrf.c | 6 ++++++ lib/Makefile | 4 ++++ lib/selinux.c | 37 +++++++++++++++++++++++++++++++++++++ misc/ss.c | 36 ++---------------------------------- 5 files changed, 59 insertions(+), 34 deletions(-) create mode 100644 include/selinux.h create mode 100644 lib/selinux.c
Signature · 1 line
2.41.0
PATCH 1/4 ss: make is_selinux_enabled stub work like in SELinux
From the is_selinux_enabled() manpage:
is_selinux_enabled() returns 1 if SELinux is running or 0 if it is not.
This makes the is_selinux_enabled() stub functions works exactly like the SELinux function it is supposed to replace.
--- misc/ss.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
misc/ss.c +2 -2
@@ -77,7 +77,7 @@/* Stubs for SELinux functions */ static int is_selinux_enabled (void ) { -return -1 ; +return 0 ; }static int getpidcon (pid_t pid,char **context)
@@ -5682,7 +5682,7 @@ int main(int argc, char *argv[]) show_sock_ctx++;/* fall through */ case 'Z' : -if (is_selinux_enabled () <=0 ) { +if (!is_selinux_enabled ()) {fprintf (stderr,"ss: SELinux is not enabled.\n" );exit (1 ); }
Signature · 1 line
2.41.0
PATCH 2/4 ss: make SELinux stub functions conformant to API definitions
In reply to Andrea Claudigetfilecon() and security_get_initial_context() use the const qualifier for their first paramater in SELinux APIs.
This commit adds the const qualifier to these functions, making them conformant to API definitions.
--- misc/ss.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
misc/ss.c +2 -2
@@ -86,13 +86,13 @@ static int getpidcon(pid_t pid, char **context)return -1 ; } -static int getfilecon (char *path,char **context) +static int getfilecon (const char *path,char **context) { *context =NULL ;return -1 ; } -static int security_get_initial_context (char *name,char **context) +static int security_get_initial_context (const char *name,char **context) { *context =NULL ;return -1 ;
Signature · 1 line
2.41.0
PATCH 3/4 lib: add SELinux include and stub functions
In reply to Andrea Claudiss provides some selinux stub functions, useful when iproute2 is compiled without selinux support.
Move them to lib/ so we can use them in other iproute2 tools.
--- include/selinux.h | 9 +++++++++ lib/Makefile | 4 ++++ lib/selinux.c | 32 ++++++++++++++++++++++++++++++++ misc/ss.c | 34 +--------------------------------- 4 files changed, 46 insertions(+), 33 deletions(-) create mode 100644 include/selinux.h create mode 100644 lib/selinux.c
include/selinux.h new file +9 -0
@@ -0,0 +1,9 @@ +#if HAVE_SELINUX +#include <selinux/selinux.h> +#else +int is_selinux_enabled (void ); +void freecon (char *context); +int getpidcon (pid_t pid,char **context); +int getfilecon (const char *path,char **context); +int security_get_initial_context (const char *name,char **context); +#endif
lib/Makefile +4 -0
@@ -13,6 +13,10 @@ UTILOBJ += bpf_libbpf.o endif endif +ifneq ($(HAVE_SELINUX),y) +UTILOBJ += selinux.o +endif + NLOBJ=libgenl.o libnetlink.o ifeq ($(HAVE_MNL),y) NLOBJ += mnl_utils.o
lib/selinux.c new file +32 -0
@@ -0,0 +1,32 @@ +#include <stdlib.h> +#include <unistd.h> +#include "selinux.h" + +/* Stubs for SELinux functions */ +int is_selinux_enabled (void ) +{ +return 0 ; +} + +void freecon (char *context) +{ +free (context); +} + +int getpidcon (pid_t pid,char **context) +{ + *context =NULL ; +return -1 ; +} + +int getfilecon (const char *path,char **context) +{ + *context =NULL ; +return -1 ; +} + +int security_get_initial_context (const char *name,char **context) +{ + *context =NULL ; +return -1 ; +}
misc/ss.c +1 -33
@@ -33,6 +33,7 @@#include "version.h" #include "rt_names.h" #include "cg_map.h" +#include "selinux.h" #include <linux/tcp.h> #include <linux/unix_diag.h>
@@ -71,39 +72,6 @@#define BUF_CHUNKS_MAX 5/* Maximum number of allocated buffer chunks */ #define LEN_ALIGN (x) (((x) + 1) & ~1) -#if HAVE_SELINUX -#include <selinux/selinux.h> -#else -/* Stubs for SELinux functions */ -static int is_selinux_enabled (void ) -{ -return 0 ; -} - -static int getpidcon (pid_t pid,char **context) -{ - *context =NULL ; -return -1 ; -} - -static int getfilecon (const char *path,char **context) -{ - *context =NULL ; -return -1 ; -} - -static int security_get_initial_context (const char *name,char **context) -{ - *context =NULL ; -return -1 ; -} - -static void freecon (char *context) -{ -free (context); -} -#endif -int preferred_family =AF_UNSPEC ;static int show_options;int show_details;
Signature · 1 line
2.41.0
PATCH 4/4 ip vrf: make ipvrf_exec SELinux-aware
In reply to Andrea ClaudiWhen using ip vrf and SELinux is enabled, make sure to set the exec file context before calling cmd_exec.
This ensures that the command is executed with the right context, falling back to the ifconfig_t context when needed.
--- include/selinux.h | 1 + ip/ipvrf.c | 6 ++++++ lib/selinux.c | 5 +++++ 3 files changed, 12 insertions(+)
include/selinux.h +1 -0
@@ -6,4 +6,5 @@ void freecon(char *context);int getpidcon (pid_t pid,char **context);int getfilecon (const char *path,char **context);int security_get_initial_context (const char *name,char **context); +int setexecfilecon (const char *filename,const char *fallback_type);#endif
ip/ipvrf.c +6 -0
@@ -24,6 +24,7 @@#include "utils.h" #include "ip_common.h" #include "bpf_util.h" +#include "selinux.h" #define CGRP_PROC_FILE "/cgroup.procs"
@@ -455,6 +456,11 @@ static int ipvrf_exec(int argc, char **argv)return -1 ; } +if (is_selinux_enabled () &&setexecfilecon (argv[1 ],"ifconfig_t" )) { +fprintf (stderr,"setexecfilecon for \"%s\" failed\n" , argv[1 ]); +return -1 ; + } +return -cmd_exec (argv[1 ], argv +1 , !!batch_mode, do_switch, argv[0 ]); }
lib/selinux.c +5 -0
@@ -30,3 +30,8 @@ int security_get_initial_context(const char *name, char **context) *context =NULL ;return -1 ; } + +int setexecfilecon (const char *filename,const char *fallback_type) +{ +return -1 ; +}
Signature · 1 line
2.41.0
This series was applied to iproute2/iproute2-next.git (main) by David Ahern <[email protected]>:
Hello:
This series was applied to iproute2/iproute2-next.git (main) by David Ahern <[email protected]>:
Quoted 10 lines · On Wed, 23 Aug 2023 19:29:58 +0200 you wrote:
In order to execute a service with VRF, a user should start it using "ip vrf exec". For example, using systemd, the user can encapsulate the ExecStart command in ip vrf exec as shown below:
ExecStart=/usr/sbin/ip vrf exec vrf1
/usr/sbin/httpd$OPTIONS -DFOREGROUNDAssuming SELinux is in permissive mode, starting the service with the current ip vrf implementation results in:
[...]
Here is the summary with links:
- [iproute2-next,1/4] ss: make is_selinux_enabled stub work like in SELinux
https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=c8970828b650 - [iproute2-next,2/4] ss: make SELinux stub functions conformant to API definitions https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=61c6882ce21c - [iproute2-next,3/4] lib: add SELinux include and stub functions https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=e246ebc3b7f1 - [iproute2-next,4/4] ip vrf: make ipvrf_exec SELinux-aware https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=0d0eeaa6cb92
You are awesome, thank you!
Signature · 2 lines
Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html