From: Egbert Eich Date: Tue Sep 12 15:51:49 2023 +0200 Subject: Fix a potential vulnerability which allows chown on user-created links Patch-mainline: ae62cdf67b19e80fd821420816f09bf0a56a8166 Git-commit: 6364ce66b4ac487b684d512089eeb0c3d577ba98 References: bsc#1215190 This fixes CVE-2023-41915, bsc#1215190. This is a backport of: Do not follow links when doing "chown" There is a potential issue with allowing a "chown" operation to follow user-created links, so let's limit any use of that function to "lchown" - which directs the "chown" operation to NOT follow a link. Signed-off-by: Ralph Castain Signed-off-by: Egbert Eich Signed-off-by: Egbert Eich --- src/mca/common/dstore/dstore_base.c | 4 ++-- src/mca/common/dstore/dstore_segment.c | 4 ++-- src/mca/gds/ds12/gds_ds12_lock_fcntl.c | 2 +- src/mca/gds/ds12/gds_ds12_lock_pthread.c | 2 +- src/mca/ptl/usock/ptl_usock_component.c | 4 ++-- src/util/pmix_pty.c | 3 ++- 6 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/mca/common/dstore/dstore_base.c b/src/mca/common/dstore/dstore_base.c index f22461c..7ff2e4d 100644 --- a/src/mca/common/dstore/dstore_base.c +++ b/src/mca/common/dstore/dstore_base.c @@ -528,7 +528,7 @@ static int _esh_session_init(pmix_common_dstore_ctx_t *ds_ctx, size_t idx, ns_ma } } if (s->setjobuid > 0){ - if (0 > chown(s->nspace_path, (uid_t) s->jobuid, (gid_t) -1)){ + if (0 > lchown(s->nspace_path, (uid_t) s->jobuid, (gid_t) -1)){ rc = PMIX_ERROR; PMIX_ERROR_LOG(rc); return rc; @@ -1682,7 +1682,7 @@ pmix_common_dstore_ctx_t *pmix_common_dstor_init(const char *ds_name, pmix_info_ } } if (ds_ctx->setjobuid > 0) { - if (chown(ds_ctx->base_path, (uid_t) ds_ctx->jobuid, (gid_t) -1) < 0){ + if (lchown(ds_ctx->base_path, (uid_t) ds_ctx->jobuid, (gid_t) -1) < 0){ rc = PMIX_ERR_NO_PERMISSIONS; PMIX_ERROR_LOG(rc); goto err_exit; diff --git a/src/mca/common/dstore/dstore_segment.c b/src/mca/common/dstore/dstore_segment.c index f0c4f9b..0e68dbf 100644 --- a/src/mca/common/dstore/dstore_segment.c +++ b/src/mca/common/dstore/dstore_segment.c @@ -120,7 +120,7 @@ PMIX_EXPORT pmix_dstore_seg_desc_t *pmix_common_dstor_create_new_lock_seg(const if (setuid > 0){ rc = PMIX_ERR_PERM; - if (0 > chown(file_name, (uid_t) uid, (gid_t) -1)){ + if (0 > lchown(file_name, (uid_t) uid, (gid_t) -1)){ PMIX_ERROR_LOG(rc); goto err_exit; } @@ -211,7 +211,7 @@ PMIX_EXPORT pmix_dstore_seg_desc_t *pmix_common_dstor_create_new_segment(pmix_ds if (setuid > 0){ rc = PMIX_ERR_PERM; - if (0 > chown(file_name, (uid_t) uid, (gid_t) -1)){ + if (0 > lchown(file_name, (uid_t) uid, (gid_t) -1)){ PMIX_ERROR_LOG(rc); goto err_exit; } diff --git a/src/mca/gds/ds12/gds_ds12_lock_fcntl.c b/src/mca/gds/ds12/gds_ds12_lock_fcntl.c index 4452316..82b6d35 100644 --- a/src/mca/gds/ds12/gds_ds12_lock_fcntl.c +++ b/src/mca/gds/ds12/gds_ds12_lock_fcntl.c @@ -127,7 +127,7 @@ pmix_status_t pmix_gds_ds12_lock_init(pmix_common_dstor_lock_ctx_t *ctx, const c } } if (0 != setuid) { - if (0 > chown(lock_ctx->lockfile, uid, (gid_t) -1)) { + if (0 > lchown(lock_ctx->lockfile, uid, (gid_t) -1)) { rc = PMIX_ERROR; PMIX_ERROR_LOG(rc); goto error; diff --git a/src/mca/gds/ds12/gds_ds12_lock_pthread.c b/src/mca/gds/ds12/gds_ds12_lock_pthread.c index 8192f05..57d855f 100644 --- a/src/mca/gds/ds12/gds_ds12_lock_pthread.c +++ b/src/mca/gds/ds12/gds_ds12_lock_pthread.c @@ -113,7 +113,7 @@ pmix_status_t pmix_gds_ds12_lock_init(pmix_common_dstor_lock_ctx_t *ctx, const c } memset(lock_ctx->segment->seg_base_addr, 0, size); if (0 != setuid) { - if (0 > chown(lock_ctx->lockfile, (uid_t) uid, (gid_t) -1)){ + if (0 > lchown(lock_ctx->lockfile, (uid_t) uid, (gid_t) -1)){ rc = PMIX_ERROR; PMIX_ERROR_LOG(rc); goto error; diff --git a/src/mca/ptl/usock/ptl_usock_component.c b/src/mca/ptl/usock/ptl_usock_component.c index 3120302..ff2542d 100644 --- a/src/mca/ptl/usock/ptl_usock_component.c +++ b/src/mca/ptl/usock/ptl_usock_component.c @@ -267,14 +267,14 @@ static pmix_status_t setup_listener(pmix_info_t info[], size_t ninfo, } /* chown as required */ if (lt->owner_given) { - if (0 != chown(address->sun_path, lt->owner, -1)) { + if (0 != lchown(address->sun_path, lt->owner, -1)) { pmix_output(0, "CANNOT CHOWN socket %s: %s", address->sun_path, strerror (errno)); CLOSE_THE_SOCKET(lt->socket); goto sockerror; } } if (lt->group_given) { - if (0 != chown(address->sun_path, -1, lt->group)) { + if (0 != lchown(address->sun_path, -1, lt->group)) { pmix_output(0, "CANNOT CHOWN socket %s: %s", address->sun_path, strerror (errno)); CLOSE_THE_SOCKET(lt->socket); goto sockerror; diff --git a/src/util/pmix_pty.c b/src/util/pmix_pty.c index 58e8d51..a5e3c0c 100644 --- a/src/util/pmix_pty.c +++ b/src/util/pmix_pty.c @@ -11,6 +11,7 @@ * All rights reserved. * Copyright (c) 2018 Cisco Systems, Inc. All rights reserved * Copyright (c) 2019-2020 Intel, Inc. All rights reserved. + * Copyright (c) 2021-2023 Nanook Consulting. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -248,7 +249,7 @@ static int ptys_open(int fdm, char *pts_name) gid = -1; /* group tty is not in the group file */ } /* following two functions don't work unless we're root */ - chown(pts_name, getuid(), gid); + lchown(pts_name, getuid(), gid); // DO NOT FOLLOW LINKS chmod(pts_name, S_IRUSR | S_IWUSR | S_IWGRP); fds = open(pts_name, O_RDWR); if (fds < 0) {