From 391f649cc44a61cbe984f71344d573abb1023033 Mon Sep 17 00:00:00 2001 From: Rainer Jung Date: Wed, 15 Aug 2012 14:51:44 +0000 Subject: [PATCH] Fix bus error in mod_socache_shmcb due to a misalignment in some 32 bit builds, especially on Solaris Sparc. PR 53040. Backport of r1373270 from trunk. Submitted by: rjung Reviewed by: rpluem, trawick git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1373439 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 5 +++++ STATUS | 5 ----- modules/cache/mod_socache_shmcb.c | 36 +++++++++++++++++++------------ 3 files changed, 27 insertions(+), 19 deletions(-) diff --git a/CHANGES b/CHANGES index 3f0893199a..62efcc1743 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,6 @@ -*- coding: utf-8 -*- +<<<<<<< .working Changes with Apache 2.4.3 *) SECURITY: CVE-2012-2687 (cve.mitre.org) @@ -7,6 +8,10 @@ Changes with Apache 2.4.3 possible XSS for a site where untrusted users can upload files to a location with MultiViews enabled. [Niels Heinen ] + *) mod_socache_shmcb: Fix bus error due to a misalignment + in some 32 bit builds, especially on Solaris Sparc. + PR 53040. [Rainer Jung] + *) mod_cache: Set content type in case we return stale content. [Ruediger Pluem] diff --git a/STATUS b/STATUS index c5669084b8..bfebad449e 100644 --- a/STATUS +++ b/STATUS @@ -88,11 +88,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - * mod_socache_shmcb: Fix bus error due to a misalignment - in some 64 bit builds, especially on Solaris Sparc. PR 53040. - trunk patch: http://svn.apache.org/viewvc?view=revision&revision=1373270 - 2.4.x patch: trunk patch works. - +1: rjung, rpluem, trawick PATCHES PROPOSED TO BACKPORT FROM TRUNK: [ New proposals should be added at the end of the list ] diff --git a/modules/cache/mod_socache_shmcb.c b/modules/cache/mod_socache_shmcb.c index 4c892d07ce..4d4246b325 100644 --- a/modules/cache/mod_socache_shmcb.c +++ b/modules/cache/mod_socache_shmcb.c @@ -36,6 +36,10 @@ #define DEFAULT_SHMCB_SUFFIX ".cache" +#define ALIGNED_HEADER_SIZE APR_ALIGN_DEFAULT(sizeof(SHMCBHeader)) +#define ALIGNED_SUBCACHE_SIZE APR_ALIGN_DEFAULT(sizeof(SHMCBSubcache)) +#define ALIGNED_INDEX_SIZE APR_ALIGN_DEFAULT(sizeof(SHMCBIndex)) + /* * Header structure - the start of the shared-mem segment */ @@ -141,7 +145,7 @@ struct ap_socache_instance_t { * a pointer to the corresponding subcache. */ #define SHMCB_SUBCACHE(pHeader, num) \ (SHMCBSubcache *)(((unsigned char *)(pHeader)) + \ - sizeof(SHMCBHeader) + \ + ALIGNED_HEADER_SIZE + \ (num) * ((pHeader)->subcache_size)) /* This macro takes a pointer to the header and an id and returns a @@ -157,8 +161,9 @@ struct ap_socache_instance_t { /* This macro takes a pointer to a subcache and a zero-based index and returns * a pointer to the corresponding SHMCBIndex. */ #define SHMCB_INDEX(pSubcache, num) \ - ((SHMCBIndex *)(((unsigned char *)pSubcache) + \ - sizeof(SHMCBSubcache)) + num) + (SHMCBIndex *)(((unsigned char *)pSubcache) + \ + ALIGNED_SUBCACHE_SIZE + \ + (num) * ALIGNED_INDEX_SIZE) /* This macro takes a pointer to the header and a subcache and returns a * pointer to the corresponding data area. */ @@ -194,7 +199,8 @@ static void shmcb_cyclic_ntoc_memcpy(unsigned int buf_size, unsigned char *data, } } -/* A "cyclic-to-normal" memcpy. */static void shmcb_cyclic_cton_memcpy(unsigned int buf_size, unsigned char *dest, +/* A "cyclic-to-normal" memcpy. */ +static void shmcb_cyclic_cton_memcpy(unsigned int buf_size, unsigned char *dest, const unsigned char *data, unsigned int src_offset, unsigned int src_len) { @@ -373,7 +379,7 @@ static apr_status_t socache_shmcb_init(ap_socache_instance_t *ctx, shm_segment = apr_shm_baseaddr_get(ctx->shm); shm_segsize = apr_shm_size_get(ctx->shm); - if (shm_segsize < (5 * sizeof(SHMCBHeader))) { + if (shm_segsize < (5 * ALIGNED_HEADER_SIZE)) { /* the segment is ridiculously small, bail out */ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00820) "shared memory segment too small"); @@ -384,7 +390,7 @@ static apr_status_t socache_shmcb_init(ap_socache_instance_t *ctx, " bytes of shared memory", shm_segsize); /* Discount the header */ - shm_segsize -= sizeof(SHMCBHeader); + shm_segsize -= ALIGNED_HEADER_SIZE; /* Select index size based on average object size hints, if given. */ avg_obj_size = hints && hints->avg_obj_size ? hints->avg_obj_size : 150; avg_id_len = hints && hints->avg_id_len ? hints->avg_id_len : 30; @@ -397,7 +403,8 @@ static apr_status_t socache_shmcb_init(ap_socache_instance_t *ctx, "for %" APR_SIZE_T_FMT " bytes (%" APR_SIZE_T_FMT " including header), recommending %u subcaches, " "%u indexes each", shm_segsize, - shm_segsize + sizeof(SHMCBHeader), num_subcache, num_idx); + shm_segsize + ALIGNED_HEADER_SIZE, + num_subcache, num_idx); if (num_idx < 5) { /* we're still too small, bail out */ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00823) @@ -416,13 +423,14 @@ static apr_status_t socache_shmcb_init(ap_socache_instance_t *ctx, header->stat_removes_miss = 0; header->subcache_num = num_subcache; /* Convert the subcache size (in bytes) to a value that is suitable for - * structure alignment on the host platform, by rounding down if necessary. - * This assumes that sizeof(unsigned long) provides an appropriate - * alignment unit. */ - header->subcache_size = ((size_t)(shm_segsize / num_subcache) & - ~(size_t)(sizeof(unsigned long) - 1)); - header->subcache_data_offset = sizeof(SHMCBSubcache) + - num_idx * sizeof(SHMCBIndex); + * structure alignment on the host platform, by rounding down if necessary. */ + header->subcache_size = (size_t)(shm_segsize / num_subcache); + if (header->subcache_size != APR_ALIGN_DEFAULT(header->subcache_size)) { + header->subcache_size = APR_ALIGN_DEFAULT(header->subcache_size) - + APR_ALIGN_DEFAULT(1); + } + header->subcache_data_offset = ALIGNED_SUBCACHE_SIZE + + num_idx * ALIGNED_INDEX_SIZE; header->subcache_data_size = header->subcache_size - header->subcache_data_offset; header->index_num = num_idx; -- 2.40.0