On 03/09/2018 10:21 AM, Vit Mojzis wrote:
> access() uses real UID instead of effective UID which causes false
> negative checks in setuid programs.
> Replace access() calls (mostly tests for file existence) by stat().
> 
> Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1186431
> 
> Signed-off-by: Vit Mojzis <vmoj...@redhat.com>
> ---
>  libsemanage/src/direct_api.c     | 137 
> +++++++++++++++++++++++++--------------
>  libsemanage/src/semanage_store.c |  11 +++-
>  2 files changed, 98 insertions(+), 50 deletions(-)
> 
> diff --git a/libsemanage/src/direct_api.c b/libsemanage/src/direct_api.c
> index 92d7517d..439122df 100644
> --- a/libsemanage/src/direct_api.c
> +++ b/libsemanage/src/direct_api.c
> @@ -140,6 +140,7 @@ int semanage_direct_is_managed(semanage_handle_t * sh)
>  int semanage_direct_connect(semanage_handle_t * sh)
>  {
>       const char *path;
> +     struct stat sb;
>  
>       if (semanage_check_init(sh, sh->conf->store_root_path))
>               goto err;
> @@ -302,10 +303,16 @@ int semanage_direct_connect(semanage_handle_t * sh)
>  
>       /* set the disable dontaudit value */
>       path = semanage_path(SEMANAGE_ACTIVE, SEMANAGE_DISABLE_DONTAUDIT);
> -     if (access(path, F_OK) == 0)
> +
> +     if (stat(path, &sb) == 0)
>               sepol_set_disable_dontaudit(sh->sepolh, 1);
> -     else
> +     else if (errno == ENOENT) {
> +             /* The file does not exist */
>               sepol_set_disable_dontaudit(sh->sepolh, 0);
> +     } else {
> +             ERR(sh, "Unable to access %s: %s\n", path, strerror(errno));
> +             goto err;
> +     }
>  
>       return STATUS_SUCCESS;
>  
> @@ -1139,6 +1146,7 @@ static int 
> semanage_compile_hll_modules(semanage_handle_t *sh,
>       int status = 0;
>       int i;
>       char cil_path[PATH_MAX];
> +     struct stat sb;
>  
>       assert(sh);
>       assert(modinfos);
> @@ -1155,9 +1163,13 @@ static int 
> semanage_compile_hll_modules(semanage_handle_t *sh,
>               }
>  
>               if (semanage_get_ignore_module_cache(sh) == 0 &&
> -                             access(cil_path, F_OK) == 0) {
> +                             (status = stat(cil_path, &sb)) == 0) {
>                       continue;
>               }
> +             if (status != 0 && errno != ENOENT) {
> +                     ERR(sh, "Unable to access %s: %s\n", cil_path, 
> strerror(errno));
> +                     goto cleanup; //an error in the "stat" call
> +             }
>  
>               status = semanage_compile_module(sh, &modinfos[i]);
>               if (status < 0) {
> @@ -1196,6 +1208,7 @@ static int semanage_direct_commit(semanage_handle_t * 
> sh)
>       struct cil_db *cildb = NULL;
>       semanage_module_info_t *modinfos = NULL;
>       mode_t mask = umask(0077);
> +     struct stat sb;
>  
>       int do_rebuild, do_write_kernel, do_install;
>       int fcontexts_modified, ports_modified, seusers_modified,
> @@ -1234,10 +1247,16 @@ static int semanage_direct_commit(semanage_handle_t * 
> sh)
>  
>       /* Create or remove the disable_dontaudit flag file. */
>       path = semanage_path(SEMANAGE_TMP, SEMANAGE_DISABLE_DONTAUDIT);
> -     if (access(path, F_OK) == 0)
> +     if (stat(path, &sb) == 0)
>               do_rebuild |= !(sepol_get_disable_dontaudit(sh->sepolh) == 1);
> -     else
> +     else if (errno == ENOENT) {
> +             /* The file does not exist */
>               do_rebuild |= (sepol_get_disable_dontaudit(sh->sepolh) == 1);
> +     } else {
> +             ERR(sh, "Unable to access %s: %s\n", path, strerror(errno));
> +             retval = -1;
> +             goto cleanup;
> +     }
>       if (sepol_get_disable_dontaudit(sh->sepolh) == 1) {
>               FILE *touch;
>               touch = fopen(path, "w");
> @@ -1259,10 +1278,17 @@ static int semanage_direct_commit(semanage_handle_t * 
> sh)
>  
>       /* Create or remove the preserve_tunables flag file. */
>       path = semanage_path(SEMANAGE_TMP, SEMANAGE_PRESERVE_TUNABLES);
> -     if (access(path, F_OK) == 0)
> +     if (stat(path, &sb) == 0)
>               do_rebuild |= !(sepol_get_preserve_tunables(sh->sepolh) == 1);
> -     else
> +     else if (errno == ENOENT) {
> +             /* The file does not exist */
>               do_rebuild |= (sepol_get_preserve_tunables(sh->sepolh) == 1);
> +     } else {
> +             ERR(sh, "Unable to access %s: %s\n", path, strerror(errno));
> +             retval = -1;
> +             goto cleanup;
> +     }
> +
>       if (sepol_get_preserve_tunables(sh->sepolh) == 1) {
>               FILE *touch;
>               touch = fopen(path, "w");
> @@ -1299,40 +1325,25 @@ static int semanage_direct_commit(semanage_handle_t * 
> sh)
>        * a rebuild.
>        */
>       if (!do_rebuild) {
> -             path = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL);
> -             if (access(path, F_OK) != 0) {
> -                     do_rebuild = 1;
> -                     goto rebuild;
> -             }
> -
> -             path = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC);
> -             if (access(path, F_OK) != 0) {
> -                     do_rebuild = 1;
> -                     goto rebuild;
> -             }
> -
> -             path = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_SEUSERS);
> -             if (access(path, F_OK) != 0) {
> -                     do_rebuild = 1;
> -                     goto rebuild;
> -             }
> -
> -             path = semanage_path(SEMANAGE_TMP, SEMANAGE_LINKED);
> -             if (access(path, F_OK) != 0) {
> -                     do_rebuild = 1;
> -                     goto rebuild;
> -             }
> -
> -             path = semanage_path(SEMANAGE_TMP, SEMANAGE_SEUSERS_LINKED);
> -             if (access(path, F_OK) != 0) {
> -                     do_rebuild = 1;
> -                     goto rebuild;
> -             }
> +             int files[] = {SEMANAGE_STORE_KERNEL,
> +                                        SEMANAGE_STORE_FC,
> +                                        SEMANAGE_STORE_SEUSERS,
> +                                        SEMANAGE_LINKED,
> +                                        SEMANAGE_SEUSERS_LINKED,
> +                                        SEMANAGE_USERS_EXTRA_LINKED};
> +
> +             for (i = 0; i < (int) sizeof(files); i++) {
> +                     path = semanage_path(SEMANAGE_TMP, files[i]);
> +                     if (stat(path, &sb) != 0) {
> +                             if (errno != ENOENT) {
> +                                     ERR(sh, "Unable to access %s: %s\n", 
> path, strerror(errno));
> +                                     retval = -1;
> +                                     goto cleanup;
> +                             }
>  
> -             path = semanage_path(SEMANAGE_TMP, SEMANAGE_USERS_EXTRA_LINKED);
> -             if (access(path, F_OK) != 0) {
> -                     do_rebuild = 1;
> -                     goto rebuild;
> +                             do_rebuild = 1;
> +                             goto rebuild;
> +                     }
>               }
>       }
>  
> @@ -1465,7 +1476,7 @@ rebuild:
>                       goto cleanup;
>  
>               path = semanage_path(SEMANAGE_TMP, SEMANAGE_SEUSERS_LINKED);
> -             if (access(path, F_OK) == 0) {
> +             if (stat(path, &sb) == 0) {
>                       retval = semanage_copy_file(path,
>                                                   semanage_path(SEMANAGE_TMP,
>                                                                 
> SEMANAGE_STORE_SEUSERS),
> @@ -1473,12 +1484,17 @@ rebuild:
>                       if (retval < 0)
>                               goto cleanup;
>                       pseusers->dtable->drop_cache(pseusers->dbase);
> -             } else {
> +             } else if (errno == ENOENT) {
> +                     /* The file does not exist */
>                       pseusers->dtable->clear(sh, pseusers->dbase);
> +             } else {
> +                     ERR(sh, "Unable to access %s: %s\n", path, 
> strerror(errno));
> +                     retval = -1;
> +                     goto cleanup;
>               }
>  
>               path = semanage_path(SEMANAGE_TMP, SEMANAGE_USERS_EXTRA_LINKED);
> -             if (access(path, F_OK) == 0) {
> +             if (stat(path, &sb) == 0) {
>                       retval = semanage_copy_file(path,
>                                                   semanage_path(SEMANAGE_TMP,
>                                                                 
> SEMANAGE_USERS_EXTRA),
> @@ -1486,8 +1502,13 @@ rebuild:
>                       if (retval < 0)
>                               goto cleanup;
>                       pusers_extra->dtable->drop_cache(pusers_extra->dbase);
> -             } else {
> +             } else if (errno == ENOENT) {
> +                     /* The file does not exist */
>                       pusers_extra->dtable->clear(sh, pusers_extra->dbase);
> +             } else {
> +                     ERR(sh, "Unable to access %s: %s\n", path, 
> strerror(errno));
> +                     retval = -1;
> +                     goto cleanup;
>               }
>       }
>  
> @@ -1817,6 +1838,7 @@ static int semanage_direct_extract(semanage_handle_t * 
> sh,
>       ssize_t _data_len;
>       char *_data;
>       int compressed;
> +     struct stat sb;
>  
>       /* get path of module */
>       rc = semanage_module_get_path(
> @@ -1829,8 +1851,8 @@ static int semanage_direct_extract(semanage_handle_t * 
> sh,
>               goto cleanup;
>       }
>  
> -     if (access(module_path, F_OK) != 0) {
> -             ERR(sh, "Module does not exist: %s", module_path);
> +     if (stat(module_path, &sb) != 0) {
> +             ERR(sh, "Unable to access %s: %s\n", module_path, 
> strerror(errno));
>               rc = -1;
>               goto cleanup;
>       }
> @@ -1859,7 +1881,13 @@ static int semanage_direct_extract(semanage_handle_t * 
> sh,
>               goto cleanup;
>       }
>  
> -     if (extract_cil == 1 && strcmp(_modinfo->lang_ext, "cil") && 
> access(input_file, F_OK) != 0) {
> +     if (extract_cil == 1 && strcmp(_modinfo->lang_ext, "cil") && 
> stat(input_file, &sb) != 0) {
> +             if (errno != ENOENT) {
> +                     ERR(sh, "Unable to access %s: %s\n", input_file, 
> strerror(errno));
> +                     rc = -1;
> +                     goto cleanup;
> +             }
> +
>               rc = semanage_compile_module(sh, _modinfo);
>               if (rc < 0) {
>                       goto cleanup;
> @@ -2004,6 +2032,12 @@ static int 
> semanage_direct_get_enabled(semanage_handle_t *sh,
>       }
>  
>       if (stat(path, &sb) < 0) {
> +             if (errno != ENOENT) {
> +                     ERR(sh, "Unable to access %s: %s\n", path, 
> strerror(errno));
> +                     status = -1;
> +                     goto cleanup;
> +             }
> +
>               *enabled = 1;
>       }
>       else {
> @@ -2330,6 +2364,12 @@ static int 
> semanage_direct_get_module_info(semanage_handle_t *sh,
>  
>       /* set enabled/disabled status */
>       if (stat(fn, &sb) < 0) {
> +             if (errno != ENOENT) {
> +                     ERR(sh, "Unable to access %s: %s\n", fn, 
> strerror(errno));
> +                     status = -1;
> +                     goto cleanup;
> +             }
> +
>               ret = semanage_module_info_set_enabled(sh, *modinfo, 1);
>               if (ret != 0) {
>                       status = -1;
> @@ -2738,6 +2778,7 @@ static int 
> semanage_direct_install_info(semanage_handle_t *sh,
>       int status = 0;
>       int ret = 0;
>       int type;
> +     struct stat sb;
>  
>       char path[PATH_MAX];
>       mode_t mask = umask(0077);
> @@ -2838,7 +2879,7 @@ static int 
> semanage_direct_install_info(semanage_handle_t *sh,
>                       goto cleanup;
>               }
>  
> -             if (access(path, F_OK) == 0) {
> +             if (stat(path, &sb) == 0) {
>                       ret = unlink(path);
>                       if (ret != 0) {
>                               ERR(sh, "Error while removing cached CIL file 
> %s: %s", path, strerror(errno));
> diff --git a/libsemanage/src/semanage_store.c 
> b/libsemanage/src/semanage_store.c
> index 4bd1d651..1e71ab67 100644
> --- a/libsemanage/src/semanage_store.c
> +++ b/libsemanage/src/semanage_store.c
> @@ -514,6 +514,7 @@ char *semanage_conf_path(void)
>  {
>       char *semanage_conf = NULL;
>       int len;
> +     struct stat sb;
>  
>       len = strlen(semanage_root()) + strlen(selinux_path()) + 
> strlen(SEMANAGE_CONF_FILE);
>       semanage_conf = calloc(len + 1, sizeof(char));
> @@ -522,7 +523,7 @@ char *semanage_conf_path(void)
>       snprintf(semanage_conf, len + 1, "%s%s%s", semanage_root(), 
> selinux_path(),
>                SEMANAGE_CONF_FILE);
>  
> -     if (access(semanage_conf, R_OK) != 0) {
> +     if (stat(semanage_conf, &sb) != 0 && errno == ENONET) {

Typo: ENONET vs ENOENT.

>               snprintf(semanage_conf, len + 1, "%s%s", selinux_path(), 
> SEMANAGE_CONF_FILE);
>       }
>  
> @@ -1508,8 +1509,14 @@ int semanage_split_fc(semanage_handle_t * sh)
>  static int sefcontext_compile(semanage_handle_t * sh, const char *path) {
>  
>       int r;
> +     struct stat sb;
> +
> +     if (stat(path, &sb) < 0) {
> +             if (errno != ENOENT) {
> +                     ERR(sh, "Unable to access %s: %s\n", path, 
> strerror(errno));
> +                     return -1;
> +             }
>  
> -     if (access(path, F_OK) != 0) {
>               return 0;
>       }
>  
> 

Reply via email to