diff mbox series

[RFC] libsemanage: Do not change file context when copying files

Message ID 20240711145257.392771-2-vmojzis@redhat.com (mailing list archive)
State Superseded
Delegated to: Petr Lautrbach
Headers show
Series [RFC] libsemanage: Do not change file context when copying files | expand

Commit Message

Vit Mojzis July 11, 2024, 2:15 p.m. UTC
Issue:
  # semodule -B
  # ls -lZ  /etc/selinux/targeted/contexts/files

-rw-r--r--. 1 root root unconfined_u:object_r:file_context_t:s0 421397 Jul 11 09:57 file_contexts
-rw-r--r--. 1 root root unconfined_u:object_r:file_context_t:s0 593470 Jul 11 09:57 file_contexts.bin
-rw-r--r--. 1 root root unconfined_u:object_r:file_context_t:s0  14704 Jul 11 09:57 file_contexts.homedirs
-rw-r--r--. 1 root root unconfined_u:object_r:file_context_t:s0  20289 Jul 11 09:57 file_contexts.homedirs.bin

  SELinux user changed from system_u to the user used to execute semodule

Signed-off-by: Vit Mojzis <vmojzis@redhat.com>
---
 libsemanage/src/semanage_store.c | 24 +++++++++++++++++++++++-
 libsemanage/src/semanage_store.h |  1 +
 2 files changed, 24 insertions(+), 1 deletion(-)

Comments

Christian Göttsche July 12, 2024, 9:36 a.m. UTC | #1
On Thu, 11 Jul 2024 at 16:53, Vit Mojzis <vmojzis@redhat.com> wrote:
>
> Issue:
>   # semodule -B
>   # ls -lZ  /etc/selinux/targeted/contexts/files
>
> -rw-r--r--. 1 root root unconfined_u:object_r:file_context_t:s0 421397 Jul 11 09:57 file_contexts
> -rw-r--r--. 1 root root unconfined_u:object_r:file_context_t:s0 593470 Jul 11 09:57 file_contexts.bin
> -rw-r--r--. 1 root root unconfined_u:object_r:file_context_t:s0  14704 Jul 11 09:57 file_contexts.homedirs
> -rw-r--r--. 1 root root unconfined_u:object_r:file_context_t:s0  20289 Jul 11 09:57 file_contexts.homedirs.bin
>
>   SELinux user changed from system_u to the user used to execute semodule
>
> Signed-off-by: Vit Mojzis <vmojzis@redhat.com>
> ---
>  libsemanage/src/semanage_store.c | 24 +++++++++++++++++++++++-
>  libsemanage/src/semanage_store.h |  1 +
>  2 files changed, 24 insertions(+), 1 deletion(-)
>
> diff --git a/libsemanage/src/semanage_store.c b/libsemanage/src/semanage_store.c
> index 27c5d349..694c1519 100644
> --- a/libsemanage/src/semanage_store.c
> +++ b/libsemanage/src/semanage_store.c
> @@ -731,7 +731,9 @@ int semanage_copy_file(const char *src, const char *dst, mode_t mode,
>
>         if (!mode)
>                 mode = S_IRUSR | S_IWUSR;
> -
> +
> +       semanage_setfscreatecon(src);
> +
>         mask = umask(0);
>         if ((out = open(tmp, O_WRONLY | O_CREAT | O_TRUNC, mode)) == -1) {

The setfscreatecon context should be reset directly after the creating
syscall (also in the failure case), e.g. via

void semanage_reset_setfscreatecon(void) {
    int saved_errno = errno;
    setfscreatecon_raw(NULL);
    errno = saved_errno;
}

>                 umask(mask);
> @@ -812,6 +814,7 @@ static int semanage_copy_dir_flags(const char *src, const char *dst, int flag)
>         }
>
>         if (stat(dst, &sb) != 0) {
> +               semanage_setfscreatecon(src);
>                 mask = umask(0077);
>                 if (mkdir(dst, S_IRWXU) != 0) {
>                         umask(mask);
> @@ -831,6 +834,7 @@ static int semanage_copy_dir_flags(const char *src, const char *dst, int flag)
>                 snprintf(path2, sizeof(path2), "%s/%s", dst, names[i]->d_name);
>                 if (S_ISDIR(sb.st_mode)) {
>                         mask = umask(0077);
> +                       semanage_setfscreatecon(path);
>                         if (mkdir(path2, 0700) == -1 ||
>                             semanage_copy_dir_flags(path, path2, flag) == -1) {
>                                 umask(mask);
> @@ -952,6 +956,24 @@ cleanup:
>         return status;
>  }
>
> +/* Get file context of "path" and use it for the next file to be created.
> + * To be used for creating a sandbox labeled the same as the original SELinux store */
> +int semanage_setfscreatecon(const char *path)
> +{
> +       int status = 0;
> +       char *fcontext_raw = NULL;
> +
> +       if (getfilecon(path, &fcontext_raw) < 0){
> +               fcontext_raw = NULL;
> +       }
> +
> +       status = setfscreatecon_raw(fcontext_raw);
> +
> +       freecon(fcontext_raw);
> +
> +       return status;
> +}
> +
>  /********************* sandbox management routines *********************/
>
>  /* Creates a sandbox for a single client. Returns 0 if a
> diff --git a/libsemanage/src/semanage_store.h b/libsemanage/src/semanage_store.h
> index 1fc77da8..135e6ac6 100644
> --- a/libsemanage/src/semanage_store.h
> +++ b/libsemanage/src/semanage_store.h
> @@ -124,6 +124,7 @@ int semanage_get_cil_paths(semanage_handle_t * sh, semanage_module_info_t *modin
>  int semanage_get_active_modules(semanage_handle_t *sh,
>                                semanage_module_info_t **modinfo, int *num_modules);
>
> +int semanage_setfscreatecon(const char *path);
>
>  /* lock file routines */
>  int semanage_get_trans_lock(semanage_handle_t * sh);
> --
> 2.43.0
>
>
Stephen Smalley July 12, 2024, 12:14 p.m. UTC | #2
On Fri, Jul 12, 2024 at 5:36 AM Christian Göttsche
<cgzones@googlemail.com> wrote:
>
> On Thu, 11 Jul 2024 at 16:53, Vit Mojzis <vmojzis@redhat.com> wrote:
> >
> > Issue:
> >   # semodule -B
> >   # ls -lZ  /etc/selinux/targeted/contexts/files
> >
> > -rw-r--r--. 1 root root unconfined_u:object_r:file_context_t:s0 421397 Jul 11 09:57 file_contexts
> > -rw-r--r--. 1 root root unconfined_u:object_r:file_context_t:s0 593470 Jul 11 09:57 file_contexts.bin
> > -rw-r--r--. 1 root root unconfined_u:object_r:file_context_t:s0  14704 Jul 11 09:57 file_contexts.homedirs
> > -rw-r--r--. 1 root root unconfined_u:object_r:file_context_t:s0  20289 Jul 11 09:57 file_contexts.homedirs.bin
> >
> >   SELinux user changed from system_u to the user used to execute semodule
> >
> > Signed-off-by: Vit Mojzis <vmojzis@redhat.com>
> > ---
> >  libsemanage/src/semanage_store.c | 24 +++++++++++++++++++++++-
> >  libsemanage/src/semanage_store.h |  1 +
> >  2 files changed, 24 insertions(+), 1 deletion(-)
> >
> > diff --git a/libsemanage/src/semanage_store.c b/libsemanage/src/semanage_store.c
> > index 27c5d349..694c1519 100644
> > --- a/libsemanage/src/semanage_store.c
> > +++ b/libsemanage/src/semanage_store.c
> > @@ -731,7 +731,9 @@ int semanage_copy_file(const char *src, const char *dst, mode_t mode,
> >
> >         if (!mode)
> >                 mode = S_IRUSR | S_IWUSR;
> > -
> > +
> > +       semanage_setfscreatecon(src);
> > +
> >         mask = umask(0);
> >         if ((out = open(tmp, O_WRONLY | O_CREAT | O_TRUNC, mode)) == -1) {
>
> The setfscreatecon context should be reset directly after the creating
> syscall (also in the failure case), e.g. via
>
> void semanage_reset_setfscreatecon(void) {
>     int saved_errno = errno;
>     setfscreatecon_raw(NULL);
>     errno = saved_errno;
> }

Yes, agreed if you retain this approach instead of just using
name-based type transitions to label these files automatically.
Other options in addition to name-based type transitions:
- Call selinux_restorecon(3) after creating to label in accordance
with file_contexts configuration, OR
- Use selabel_lookup(3) prior to creating to obtain the correct label
rather than relying on the source label as authoritative.
diff mbox series

Patch

diff --git a/libsemanage/src/semanage_store.c b/libsemanage/src/semanage_store.c
index 27c5d349..694c1519 100644
--- a/libsemanage/src/semanage_store.c
+++ b/libsemanage/src/semanage_store.c
@@ -731,7 +731,9 @@  int semanage_copy_file(const char *src, const char *dst, mode_t mode,
 
 	if (!mode)
 		mode = S_IRUSR | S_IWUSR;
-	
+
+	semanage_setfscreatecon(src);
+
 	mask = umask(0);
 	if ((out = open(tmp, O_WRONLY | O_CREAT | O_TRUNC, mode)) == -1) {
 		umask(mask);
@@ -812,6 +814,7 @@  static int semanage_copy_dir_flags(const char *src, const char *dst, int flag)
 	}
 
 	if (stat(dst, &sb) != 0) {
+		semanage_setfscreatecon(src);
 		mask = umask(0077);
 		if (mkdir(dst, S_IRWXU) != 0) {
 			umask(mask);
@@ -831,6 +834,7 @@  static int semanage_copy_dir_flags(const char *src, const char *dst, int flag)
 		snprintf(path2, sizeof(path2), "%s/%s", dst, names[i]->d_name);
 		if (S_ISDIR(sb.st_mode)) {
 			mask = umask(0077);
+			semanage_setfscreatecon(path);
 			if (mkdir(path2, 0700) == -1 ||
 			    semanage_copy_dir_flags(path, path2, flag) == -1) {
 				umask(mask);
@@ -952,6 +956,24 @@  cleanup:
 	return status;
 }
 
+/* Get file context of "path" and use it for the next file to be created.
+ * To be used for creating a sandbox labeled the same as the original SELinux store */
+int semanage_setfscreatecon(const char *path)
+{
+	int status = 0;
+	char *fcontext_raw = NULL;
+
+	if (getfilecon(path, &fcontext_raw) < 0){
+		fcontext_raw = NULL;
+	}
+
+	status = setfscreatecon_raw(fcontext_raw);
+
+	freecon(fcontext_raw);
+
+	return status;
+}
+
 /********************* sandbox management routines *********************/
 
 /* Creates a sandbox for a single client. Returns 0 if a
diff --git a/libsemanage/src/semanage_store.h b/libsemanage/src/semanage_store.h
index 1fc77da8..135e6ac6 100644
--- a/libsemanage/src/semanage_store.h
+++ b/libsemanage/src/semanage_store.h
@@ -124,6 +124,7 @@  int semanage_get_cil_paths(semanage_handle_t * sh, semanage_module_info_t *modin
 int semanage_get_active_modules(semanage_handle_t *sh,
 			       semanage_module_info_t **modinfo, int *num_modules);
 
+int semanage_setfscreatecon(const char *path);
 
 /* lock file routines */
 int semanage_get_trans_lock(semanage_handle_t * sh);