Re: [PATCH] libsemanage: Use umask(0077) for fopen() write operations

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 <plautrba@xxxxxxxxxx>
> ---
>  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;
>  }



[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux