From 88d584a6df1dcc7d45e7f5f73db33c4c68e29c01 Mon Sep 17 00:00:00 2001 From: Cristy Date: Thu, 13 Jul 2017 10:57:35 -0400 Subject: [PATCH] Support max-request-limit security policy --- MagickCore/memory.c | 160 +++++++++++++++++++++++--------------------- config/policy.xml | 1 + 2 files changed, 83 insertions(+), 78 deletions(-) diff --git a/MagickCore/memory.c b/MagickCore/memory.c index c49428d8e..701979534 100644 --- a/MagickCore/memory.c +++ b/MagickCore/memory.c @@ -64,6 +64,7 @@ #include "MagickCore/resource_.h" #include "MagickCore/semaphore.h" #include "MagickCore/string_.h" +#include "MagickCore/string-private.h" #include "MagickCore/utility-private.h" /* @@ -547,8 +548,9 @@ MagickExport void *AcquireQuantumMemory(const size_t count,const size_t quantum) % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % -% AcquireVirtualMemory() allocates a pointer to a block of memory at least size -% bytes suitably aligned for any use. +% AcquireVirtualMemory() allocates a pointer to a block of memory at least +% size bytes suitably aligned for any use. In addition to heap, it also +% supports memory-mapped and file-based memory-mapped memory requests. % % The format of the AcquireVirtualMemory method is: % @@ -561,117 +563,119 @@ MagickExport void *AcquireQuantumMemory(const size_t count,const size_t quantum) % o quantum: the number of bytes in each quantum. % */ + +static inline size_t StringToSizeType(const char *string,const double interval) +{ + double + value; + + value=SiPrefixToDoubleInterval(string,interval); + if (value >= (double) MagickULLConstant(~0)) + return((size_t) MagickULLConstant(~0)); + return((size_t) value); +} + MagickExport MemoryInfo *AcquireVirtualMemory(const size_t count, const size_t quantum) { + char + *value; + MemoryInfo *memory_info; size_t extent; - static ssize_t - virtual_anonymous_memory = (-1); + static size_t + max_memory_request = 0, + virtual_anonymous_memory = 0; if (HeapOverflowSanityCheck(count,quantum) != MagickFalse) return((MemoryInfo *) NULL); - memory_info=(MemoryInfo *) MagickAssumeAligned(AcquireAlignedMemory(1, - sizeof(*memory_info))); - if (memory_info == (MemoryInfo *) NULL) - ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); - (void) ResetMagickMemory(memory_info,0,sizeof(*memory_info)); - extent=count*quantum; - memory_info->length=extent; - memory_info->signature=MagickCoreSignature; - if (virtual_anonymous_memory < 0) + if (max_memory_request == 0) { - char - *value; - - /* - Does the security policy require anonymous mapping for pixel cache? - */ - virtual_anonymous_memory=0; + max_memory_request=(size_t) MagickULLConstant(~0); + value=GetPolicyValue("system:max-memory-request"); + if (value != (char *) NULL) + { + /* + The security policy sets a max memory request limit. + */ + max_memory_request=StringToSizeType(value,100.0); + value=DestroyString(value); + } + } + if ((count*quantum) > (size_t) max_memory_request) + return((MemoryInfo *) NULL); + if (virtual_anonymous_memory == 0) + { + virtual_anonymous_memory=1; value=GetPolicyValue("system:memory-map"); if (LocaleCompare(value,"anonymous") == 0) { + /* + The security policy sets anonymous mapping for the memory request. + */ #if defined(MAGICKCORE_HAVE_MMAP) && defined(MAP_ANONYMOUS) - virtual_anonymous_memory=1; + virtual_anonymous_memory=2; #endif } value=DestroyString(value); } - if (virtual_anonymous_memory <= 0) + memory_info=(MemoryInfo *) MagickAssumeAligned(AcquireAlignedMemory(1, + sizeof(*memory_info))); + if (memory_info == (MemoryInfo *) NULL) + ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); + (void) ResetMagickMemory(memory_info,0,sizeof(*memory_info)); + extent=count*quantum; + memory_info->length=extent; + memory_info->signature=MagickCoreSignature; + if (virtual_anonymous_memory == 1) { - if (AcquireMagickResource(MemoryResource,extent) != MagickFalse) - { - memory_info->blob=AcquireAlignedMemory(1,extent); - if (memory_info->blob != NULL) - { - memory_info->type=AlignedVirtualMemory; - return(memory_info); - } - } - RelinquishMagickResource(MemoryResource,extent); + memory_info->blob=AcquireAlignedMemory(1,extent); + if (memory_info->blob != NULL) + memory_info->type=AlignedVirtualMemory; } else { - if (AcquireMagickResource(MapResource,extent) != MagickFalse) + /* + Acquire anonymous memory map. + */ + memory_info->blob=MapBlob(-1,IOMode,0,extent); + if (memory_info->blob != NULL) + memory_info->type=MapVirtualMemory; + else { + int + file; + /* - Acquire anonymous memory map. + Anonymous memory mapping failed, try file-backed memory mapping. */ - memory_info->blob=MapBlob(-1,IOMode,0,extent); - if (memory_info->blob != NULL) - { - memory_info->type=MapVirtualMemory; - return(memory_info); - } - if (AcquireMagickResource(DiskResource,extent) != MagickFalse) + file=AcquireUniqueFileResource(memory_info->filename); + if (file != -1) { - int - file; - - /* - Anonymous memory mapping failed, try file-backed memory mapping. - If the MapResource request failed, there is no point in trying - file-backed memory mapping. - */ - file=AcquireUniqueFileResource(memory_info->filename); - if (file != -1) - { - MagickOffsetType - offset; + MagickOffsetType + offset; - offset=(MagickOffsetType) lseek(file,extent-1,SEEK_SET); - if ((offset == (MagickOffsetType) (extent-1)) && - (write(file,"",1) == 1)) + offset=(MagickOffsetType) lseek(file,extent-1,SEEK_SET); + (void) close(file); + if ((offset == (MagickOffsetType) (extent-1)) && + (write(file,"",1) == 1)) + { + memory_info->blob=MapBlob(file,IOMode,0,extent); + if (memory_info->blob != NULL) + memory_info->type=MapVirtualMemory; + else { - memory_info->blob=MapBlob(file,IOMode,0,extent); - if (memory_info->blob != NULL) - { - (void) close(file); - memory_info->type=MapVirtualMemory; - return(memory_info); - } + (void) RelinquishUniqueFileResource( + memory_info->filename); + *memory_info->filename='\0'; } - /* - File-backed memory mapping fail, delete the temporary file. - */ - (void) close(file); - (void) RelinquishUniqueFileResource(memory_info->filename); - *memory_info->filename = '\0'; } } - RelinquishMagickResource(DiskResource,extent); } - RelinquishMagickResource(MapResource,extent); - } - if (memory_info->blob == NULL) - { - memory_info->blob=AcquireMagickMemory(extent); - if (memory_info->blob != NULL) - memory_info->type=UnalignedVirtualMemory; } if (memory_info->blob == NULL) memory_info=RelinquishVirtualMemory(memory_info); diff --git a/config/policy.xml b/config/policy.xml index 7ee2f2663..6330084a5 100644 --- a/config/policy.xml +++ b/config/policy.xml @@ -58,6 +58,7 @@ + -- 2.40.0