From 6563993f8da416e3a363edae2bc97efbcb716b7e Mon Sep 17 00:00:00 2001 From: Joe Orton Date: Wed, 7 Aug 2024 09:47:27 +0000 Subject: [PATCH] * test/testshm.c (test_named_perms): Add test case. * shmem/unix/shm.c (APR_PERMS_SET_IMPLEMENT): Implement for the POSIX shm and "classic mmap" cases. CI: Add tests for various SHM configurations, and that the decision logic is setting the correct APR_USE_SHM_* variables. Submitted by: jorton, rpluem Github: closes #59 git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1919714 13f79535-47bb-0310-9956-ffa450edef68 --- .github/workflows/linux.yml | 8 ++++++++ shmem/unix/shm.c | 41 +++++++++++++++++++++++++++++++++++++ test/testshm.c | 31 ++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 9b322f216e..75c22ed8d4 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -17,10 +17,18 @@ jobs: matrix: include: - name: Default + # Check default shm decision logic for Linux: + config-output: APR_USE_SHMEM_MMAP_SHM APR_USE_SHMEM_MMAP_ANON - name: Static config: --enable-static - name: Maintainer-mode config: --enable-maintainer-mode + - name: Named SHM - SysV, Maintainer-mode + config: --enable-maintainer-mode --enable-sysv-shm + config-output: APR_USE_SHMEM_SHMGET + - name: Named SHM - Classic mmap, Maintainer-mode + config: --enable-maintainer-mode ac_cv_func_shm_open=no ac_cv_func_shmget=no + config-output: APR_USE_SHMEM_MMAP_TMP - name: Pool-debug config: --enable-pool-debug - name: Pool-debug, maintainer-mode diff --git a/shmem/unix/shm.c b/shmem/unix/shm.c index 55f4cfb5e6..ab55abce39 100644 --- a/shmem/unix/shm.c +++ b/shmem/unix/shm.c @@ -705,6 +705,47 @@ APR_PERMS_SET_IMPLEMENT(shm) if (shmctl(shmid, IPC_SET, &shmbuf) == -1) { return errno; } + return APR_SUCCESS; +#elif APR_USE_SHMEM_MMAP_SHM + apr_shm_t *shm = (apr_shm_t *)theshm; + const char *shm_name; + int fd; + apr_status_t rv; + + if (!shm->filename) + return APR_ENOTIMPL; + + shm_name = make_shm_open_safe_name(shm->filename, shm->pool); + + fd = shm_open(shm_name, O_RDWR, 0); + if (fd == -1) + return errno; + + if (fchown(fd, uid, gid)) { + rv = errno; + close(fd); + return rv; + } + + if (fchmod(fd, apr_unix_perms2mode(perms))) { + rv = errno; + close(fd); + return rv; + } + close(fd); + return APR_SUCCESS; +#elif APR_USE_SHMEM_MMAP_TMP + apr_shm_t *shm = (apr_shm_t *)theshm; + + if (!shm->filename) + return APR_ENOTIMPL; + + if (chown(shm->filename, uid, gid)) + return errno; + + if (chmod(shm->filename, apr_unix_perms2mode(perms))) + return errno; + return APR_SUCCESS; #else return APR_ENOTIMPL; diff --git a/test/testshm.c b/test/testshm.c index c04ec18482..d17a28c883 100644 --- a/test/testshm.c +++ b/test/testshm.c @@ -285,6 +285,36 @@ static void test_named_delete(abts_case *tc, void *data) ABTS_TRUE(tc, rv != 0); } +static void test_named_perms(abts_case *tc, void *data) +{ + apr_status_t rv; + apr_shm_t *shm; + apr_uid_t uid; + apr_gid_t gid; + + apr_shm_remove(SHARED_FILENAME, p); + + rv = apr_shm_create(&shm, SHARED_SIZE, SHARED_FILENAME, p); + APR_ASSERT_SUCCESS(tc, "Error allocating shared memory block", rv); + if (rv != APR_SUCCESS) { + return; + } + ABTS_PTR_NOTNULL(tc, shm); + + rv = apr_uid_current(&uid, &gid, p); + APR_ASSERT_SUCCESS(tc, "retrieve current uid/gid", rv); + if (rv) return; + + rv = apr_shm_perms_set(shm, + APR_FPROT_UREAD|APR_FPROT_UWRITE, uid, gid); + apr_shm_destroy(shm); + + if (rv == APR_ENOTIMPL) + ABTS_SKIP(tc, data, "apr_shm_perms_set not implemented for named shm"); + else + APR_ASSERT_SUCCESS(tc, "Could not change permissions of shm segment", rv); +} + #endif abts_suite *testshm(abts_suite *suite) @@ -301,6 +331,7 @@ abts_suite *testshm(abts_suite *suite) abts_run_test(suite, test_named, NULL); abts_run_test(suite, test_named_remove, NULL); abts_run_test(suite, test_named_delete, NULL); + abts_run_test(suite, test_named_perms, NULL); #endif return suite;