[llvm-dev] UB in MemoryBufferMMapFile

Mehdi Amini via llvm-dev llvm-dev at lists.llvm.org
Wed Nov 16 22:10:05 PST 2016


> On Nov 16, 2016, at 9:46 PM, Justin Bogner via llvm-dev <llvm-dev at lists.llvm.org> wrote:
> 
> In MemoryBuffer::init, we have an assert that reads the memory at
> `BufEnd`, which is one past the end of some memory region:
> 
> from lib/Support/MemoryBuffer.cpp:45:
>> void MemoryBuffer::init(const char *BufStart, const char *BufEnd,
>>                        bool RequiresNullTerminator) {
>>  assert((!RequiresNullTerminator || BufEnd[0] == 0) &&

Why isn’t it BufEnd[-1] == 0 ?

What is the use-case for this RequiresNullTerminator after the end of the buffer?

I feel I’m missing some piece here!

— 
Mehdi


>>         "Buffer is not null terminated!");
>>  BufferStart = BufStart;
>>  BufferEnd = BufEnd;
>> }
> 
> However, this can be, and often is, one past an allocated region, since
> in MemoryBufferMMapFile we mmap `Len` bytes and then call this with
> `BufEnd = Start + Len`:
> 
> from lib/Support/MemoryBuffer.cpp:210:
>>  MemoryBufferMMapFile(bool RequiresNullTerminator, int FD, uint64_t Len,
>>                       uint64_t Offset, std::error_code &EC)
>>      : MFR(FD, sys::fs::mapped_file_region::readonly,
>>            getLegalMapSize(Len, Offset), getLegalMapOffset(Offset), EC) {
>>    if (!EC) {
>>      const char *Start = getStart(Len, Offset);
>>      init(Start, Start + Len, RequiresNullTerminator);
>>    }
>>  }
> 
> This is UB, since we're reading one past an allocated region, and I have
> an internal test case where I'm seeing it crash because that memory
> happens to be unreadable.
> 
> There are three options here:
> 
> 1. Remove the assert - it isn't possible to write correctly.
> 2. Remove the RequiresNullTerminator argument from MemoryBufferMMapFile
>   and hard code it to false.
> 3. Allocate an extra byte here and zero it.
> 
> I'm not sure which is best. Thoughts?
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev



More information about the llvm-dev mailing list