On Tue, 2017-11-21 at 15:19 +0100, Petr Lautrbach wrote:
> When a calling process uses umask(0) some files in the SELinux module
> store can be created to be world writeable. With this patch,
> libsemanage
> sets umask(0077) before fopen() operations and restores the original
> umask value when it's done.
> 
> Fixes:
> drwx------. /var/lib/selinux/targeted/active
> -rw-rw-rw-. /var/lib/selinux/targeted/active/booleans.local
> -rw-rw-rw-. /var/lib/selinux/targeted/active/policy.linked
> -rw-rw-rw-. /var/lib/selinux/targeted/active/seusers.local
> 
> drwx------.
> /var/lib/selinux/targeted/active/modules/400/permissive_sshd_t
> -rw-rw-rw-.
> /var/lib/selinux/targeted/active/modules/400/permissive_sshd_t/cil
> -rw-rw-rw-.
> /var/lib/selinux/targeted/active/modules/400/permissive_sshd_t/lang_e
> xt
> drwx------. /var/lib/selinux/targeted/active/modules/disabled
> -rw-rw-rw-.
> /var/lib/selinux/targeted/active/modules/disabled/zosremote
> 
> Signed-off-by: Petr Lautrbach <[email protected]>
> ---
>  libsemanage/src/database_file.c  |  3 +++
>  libsemanage/src/direct_api.c     | 15 +++++++++++++++
>  libsemanage/src/semanage_store.c |  4 ++++
>  3 files changed, 22 insertions(+)
> 
> diff --git a/libsemanage/src/database_file.c
> b/libsemanage/src/database_file.c
> index a21b3eeb..d0172e73 100644
> --- a/libsemanage/src/database_file.c
> +++ b/libsemanage/src/database_file.c
> @@ -119,13 +119,16 @@ static int dbase_file_flush(semanage_handle_t *
> handle, dbase_file_t * dbase)
>       cache_entry_t *ptr;
>       const char *fname = NULL;
>       FILE *str = NULL;
> +     mode_t mask = 0;

Why do we need to initialize this here?

>  
>       if (!dbase_llist_is_modified(&dbase->llist))
>               return STATUS_SUCCESS;
>  
>       fname = dbase->path[handle->is_in_transaction];
>  
> +     mask = umask(0077);
>       str = fopen(fname, "w");
> +     umask(mask);
>       if (!str) {
>               ERR(handle, "could not open %s for writing: %s",
>                   fname, strerror(errno));
> diff --git a/libsemanage/src/direct_api.c
> b/libsemanage/src/direct_api.c
> index 00ad8201..46072f92 100644
> --- a/libsemanage/src/direct_api.c
> +++ b/libsemanage/src/direct_api.c
> @@ -1176,6 +1176,7 @@ static int
> semanage_direct_commit(semanage_handle_t * sh)
>       sepol_policydb_t *out = NULL;
>       struct cil_db *cildb = NULL;
>       semanage_module_info_t *modinfos = NULL;
> +     mode_t mask = 0;

Why do we need to initialize mask here?

>  
>       int do_rebuild, do_write_kernel, do_install;
>       int fcontexts_modified, ports_modified, seusers_modified,
> @@ -1212,6 +1213,8 @@ static int
> semanage_direct_commit(semanage_handle_t * sh)
>       /* Rebuild if explicitly requested or any module changes
> occurred. */
>       do_rebuild = sh->do_rebuild | sh->modules_modified;
>  
> +     mask = umask(0077);
> +
>       /* Create or remove the disable_dontaudit flag file. */
>       path = semanage_path(SEMANAGE_TMP,
> SEMANAGE_DISABLE_DONTAUDIT);
>       if (access(path, F_OK) == 0)
> @@ -1645,6 +1648,10 @@ cleanup:
>       semanage_remove_directory(semanage_final_path
>                                 (SEMANAGE_FINAL_TMP,
>                                  SEMANAGE_FINAL_TOPLEVEL));
> +     if (mask) {
> +             umask(mask);
> +     }

Why is this conditional?

> +
>       return retval;
>  }
>  
> @@ -2016,6 +2023,7 @@ static int
> semanage_direct_set_enabled(semanage_handle_t *sh,
>       const char *path = NULL;
>       FILE *fp = NULL;
>       semanage_module_info_t *modinfo = NULL;
> +     mode_t mask = 0;

Ditto

>  
>       /* check transaction */
>       if (!sh->is_in_transaction) {
> @@ -2076,7 +2084,9 @@ static int
> semanage_direct_set_enabled(semanage_handle_t *sh,
>  
>       switch (enabled) {
>               case 0: /* disable the module */
> +                     mask = umask(0077);
>                       fp = fopen(fn, "w");
> +                     umask(mask);
>  
>                       if (fp == NULL) {
>                               ERR(sh,
> @@ -2722,7 +2732,9 @@ static int
> semanage_direct_install_info(semanage_handle_t *sh,
>       int type;
>  
>       char path[PATH_MAX];
> +     mode_t mask = 0;

No need to initialize this here.
>  
> +     mask = umask(0077);

And this should go after local variable declarations or get folded into
the declaration above.

>       semanage_module_info_t *higher_info = NULL;
>       semanage_module_key_t higher_key;
>       ret = semanage_module_key_init(sh, &higher_key);
> @@ -2834,6 +2846,9 @@ cleanup:
>       semanage_module_info_destroy(sh, higher_info);
>       free(higher_info);
>  
> +     if (mask) {
> +             umask(mask);
> +     }

Why conditional?

>       return status;
>  }
>  
> diff --git a/libsemanage/src/semanage_store.c
> b/libsemanage/src/semanage_store.c
> index 63c80b04..74fbb677 100644
> --- a/libsemanage/src/semanage_store.c
> +++ b/libsemanage/src/semanage_store.c
> @@ -2099,11 +2099,13 @@ int semanage_write_policydb(semanage_handle_t
> * sh, sepol_policydb_t * out,
>       const char *kernel_filename = NULL;
>       struct sepol_policy_file *pf = NULL;
>       FILE *outfile = NULL;
> +     mode_t mask = 0;
>  
>       if ((kernel_filename =
>            semanage_path(SEMANAGE_TMP, file)) == NULL) {
>               goto cleanup;
>       }
> +     mask = umask(0077);

Just move this before the first goto cleanup and then you don't need to
initialize mask or make the test below conditional.

>       if ((outfile = fopen(kernel_filename, "wb")) == NULL) {
>               ERR(sh, "Could not open kernel policy %s for
> writing.",
>                   kernel_filename);
> @@ -2127,6 +2129,8 @@ int semanage_write_policydb(semanage_handle_t *
> sh, sepol_policydb_t * out,
>       if (outfile != NULL) {
>               fclose(outfile);
>       }
> +     if (mask != 0)
> +             umask(mask);
>       sepol_policy_file_free(pf);
>       return retval;
>  }

Reply via email to