Ticket #11246: 0001-kernel-pagecache-provided-buffers-are-not-always-in-.patch

File 0001-kernel-pagecache-provided-buffers-are-not-always-in-.patch, 2.4 KB (added by pdziepak, 6 years ago)
  • src/system/kernel/cache/file_cache.cpp

    From c6eb09d1349a45061a08b6a57d992b8fddaf924e Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Pawe=C5=82=20Dziepak?= <pdziepak@quarnos.org>
    Date: Mon, 15 Sep 2014 23:18:25 +0200
    Subject: [PATCH] kernel: pagecache: provided buffers are not always in user
     memory
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    
    Source or destination buffers passed to pagecache functions may belong
    to kernel memory (e.g. when the caller is packagefs). Because of that
    we should tell vm_memcpy_{from, to}_physical() truth, not assume that all
    buffers are in user memory. That's important because user memory page fault
    handlers cannot be nested and these functions may be used while handling
    a page fault.
    
    Signed-off-by: Paweł Dziepak <pdziepak@quarnos.org>
    ---
     src/system/kernel/cache/file_cache.cpp | 9 +++++----
     1 file changed, 5 insertions(+), 4 deletions(-)
    
    diff --git a/src/system/kernel/cache/file_cache.cpp b/src/system/kernel/cache/file_cache.cpp
    index 01257d7..80f5d41 100644
    a b read_into_cache(file_cache_ref* ref, void* cookie, off_t offset,  
    434434
    435435            vm_memcpy_from_physical((void*)buffer,
    436436                pages[i]->physical_page_number * B_PAGE_SIZE + pageOffset,
    437                 bytes, true);
     437                bytes, IS_USER_ADDRESS(buffer));
    438438
    439439            buffer += bytes;
    440440            bufferSize -= bytes;
    write_to_cache(file_cache_ref* ref, void* cookie, off_t offset,  
    588588        if (useBuffer) {
    589589            // copy data from user buffer
    590590            vm_memcpy_to_physical(base + pageOffset, (void*)buffer, bytes,
    591                 true);
     591                IS_USER_ADDRESS(buffer));
    592592        } else {
    593593            // clear buffer instead
    594594            vm_memset_physical(base + pageOffset, 0, bytes);
    cache_io(void* _cacheRef, void* cookie, off_t offset, addr_t buffer,  
    808808                phys_addr_t pageAddress
    809809                    = (phys_addr_t)page->physical_page_number * B_PAGE_SIZE
    810810                        + pageOffset;
     811                bool userBuffer = IS_USER_ADDRESS(buffer);
    811812                if (doWrite) {
    812813                    if (useBuffer) {
    813814                        vm_memcpy_to_physical(pageAddress, (void*)buffer,
    814                             bytesInPage, true);
     815                            bytesInPage, userBuffer);
    815816                    } else {
    816817                        vm_memset_physical(pageAddress, 0, bytesInPage);
    817818                    }
    818819                } else if (useBuffer) {
    819820                    vm_memcpy_from_physical((void*)buffer, pageAddress,
    820                         bytesInPage, true);
     821                        bytesInPage, userBuffer);
    821822                }
    822823
    823824                locker.Lock();