diff options
author | Jim Jagielski <jim@apache.org> | 2014-01-25 05:51:13 +0000 |
---|---|---|
committer | Jim Jagielski <jim@apache.org> | 2014-01-25 05:51:13 +0000 |
commit | 65d7750a86230137e7776da2caaeff70c8d11a25 (patch) | |
tree | a5d375e376a6c5dec14fdf714bbeaa52b2b02e29 /shmem | |
parent | 81d001a0dbf61b6373b57a8589c0d4841adad3b6 (diff) | |
download | apr-65d7750a86230137e7776da2caaeff70c8d11a25.tar.gz |
*) Fix POSIX shared memory (shm_open) use for named shared memory.
PR 55928. [Jozef Hatala <jh-asf skrt org>]
git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1561260 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'shmem')
-rw-r--r-- | shmem/unix/shm.c | 88 |
1 files changed, 82 insertions, 6 deletions
diff --git a/shmem/unix/shm.c b/shmem/unix/shm.c index 060a36945..90dc3061a 100644 --- a/shmem/unix/shm.c +++ b/shmem/unix/shm.c @@ -23,6 +23,61 @@ #include "apr_strings.h" #include "apr_hash.h" +#if APR_USE_SHMEM_MMAP_SHM +/* + * For portable use, a shared memory object should be identified by a name of + * the form /somename; that is, a null-terminated string of up to NAME_MAX + * (i.e., 255) characters consisting of an initial slash, followed by one or + * more characters, none of which are slashes. + */ +#ifndef NAME_MAX +#define NAME_MAX 255 +#endif +static const char *make_shm_open_safe_name(const char *filename, + apr_pool_t *pool) +{ + const char *in; + char *result; + char *out; + apr_size_t len = 0; + + if (filename == NULL) + return NULL; + + len = strlen(filename); + if (filename[0] != '/') { + ++len; + } + if (len > NAME_MAX) { + len = NAME_MAX; + } + /* Allocate the required string */ + result = apr_palloc(pool, len+1); + + in = filename; + if (*in == '/') { + ++in; + } + + out = result; + *out++ = '/'; + + for ( ; --len; ++in, ++out) { + if (*in == '/') { + /* '/' becomes '|' */ + *out = '|'; + } else { + /* Everything else remains unchanged */ + *out = *in; + } + } + + *out = '\0'; + + return result; +} +#endif + static apr_status_t shm_cleanup_owner(void *m_) { apr_shm_t *m = (apr_shm_t *)m_; @@ -60,7 +115,7 @@ static apr_status_t shm_cleanup_owner(void *m_) if (munmap(m->base, m->realsize) == -1) { return errno; } - if (shm_unlink(m->filename) == -1) { + if (shm_unlink(make_shm_open_safe_name(m->filename, m->pool)) == -1 && errno != ENOENT) { return errno; } return APR_SUCCESS; @@ -221,7 +276,9 @@ APR_DECLARE(apr_status_t) apr_shm_create(apr_shm_t **m, new_m->pool = pool; new_m->reqsize = reqsize; new_m->filename = apr_pstrdup(pool, filename); - +#if APR_USE_SHMEM_MMAP_SHM + const char *shm_name = make_shm_open_safe_name(filename, pool); +#endif #if APR_USE_SHMEM_MMAP_TMP || APR_USE_SHMEM_MMAP_SHM new_m->realsize = reqsize + APR_ALIGN_DEFAULT(sizeof(apr_size_t)); /* room for metadata */ @@ -262,7 +319,7 @@ APR_DECLARE(apr_status_t) apr_shm_create(apr_shm_t **m, } #endif /* APR_USE_SHMEM_MMAP_TMP */ #if APR_USE_SHMEM_MMAP_SHM - tmpfd = shm_open(filename, O_RDWR | O_CREAT | O_EXCL, 0644); + tmpfd = shm_open(shm_name, O_RDWR | O_CREAT | O_EXCL, 0644); if (tmpfd == -1) { return errno; } @@ -276,10 +333,10 @@ APR_DECLARE(apr_status_t) apr_shm_create(apr_shm_t **m, status = apr_file_trunc(file, new_m->realsize); if (status != APR_SUCCESS) { - shm_unlink(filename); /* we're failing, remove the object */ + shm_unlink(shm_name); /* we're failing, remove the object */ return status; } - new_m->base = mmap(NULL, reqsize, PROT_READ | PROT_WRITE, + new_m->base = mmap(NULL, new_m->realsize, PROT_READ | PROT_WRITE, MAP_SHARED, tmpfd, 0); /* FIXME: check for errors */ @@ -388,7 +445,8 @@ APR_DECLARE(apr_status_t) apr_shm_remove(const char *filename, #if APR_USE_SHMEM_MMAP_TMP return apr_file_remove(filename, pool); #elif APR_USE_SHMEM_MMAP_SHM - if (shm_unlink(filename) == -1) { + const char *shm_name = make_shm_open_safe_name(filename, pool); + if (shm_unlink(shm_name) == -1) { return errno; } return APR_SUCCESS; @@ -483,7 +541,22 @@ APR_DECLARE(apr_status_t) apr_shm_attach(apr_shm_t **m, new_m = apr_palloc(pool, sizeof(apr_shm_t)); new_m->pool = pool; new_m->filename = apr_pstrdup(pool, filename); +#if APR_USE_SHMEM_MMAP_SHM + const char *shm_name = make_shm_open_safe_name(filename, pool); + + tmpfd = shm_open(shm_name, O_RDWR, 0644); + if (tmpfd == -1) { + return errno; + } + status = apr_os_file_put(&file, &tmpfd, + APR_READ | APR_WRITE, + pool); + if (status != APR_SUCCESS) { + return status; + } + +#elif APR_USE_SHMEM_MMAP_TMP status = apr_file_open(&file, filename, APR_FOPEN_READ | APR_FOPEN_WRITE, APR_FPROT_OS_DEFAULT, pool); @@ -494,6 +567,9 @@ APR_DECLARE(apr_status_t) apr_shm_attach(apr_shm_t **m, if (status != APR_SUCCESS) { return status; } +#else + return APR_ENOTIMPL; +#endif nbytes = sizeof(new_m->realsize); status = apr_file_read(file, (void *)&(new_m->realsize), |