diff options
| author | 2024-12-03 12:49:01 -0800 | |
|---|---|---|
| committer | 2024-12-03 21:40:01 +0000 | |
| commit | 8f4be0294d89e745be4b6b9add263932b8235f6e (patch) | |
| tree | 6518339fbb73605b0c6e0534eb56d4be01144003 | |
| parent | dde612297a95746beaefe205afc1d55795f43eb1 (diff) | |
Fix error handling in CursorWindow
If a CursorWindow is created from a Parcel but the file descriptor is
invalid or the mmap() call fails, the CursorWindow destructor will be
invoked with an inconsistent object. The destructor will attempt to
call munmap() with an unconfigured mData attribute.
This makes two changes. First, the destructor only attempts to unmap
memory if the file descriptor is non-negative. The old code unmapped
memory if the file descriptor was not -1. However, the construction
code treated any negative file descriptor as an error.
Second, when a CursorWindow is created from a parcel, the file
descriptor field is not changed from -1 (the constructor default)
until it is known that the memory mapping has succeeded. If the
function exits early, it is no longer in a half-constructed state. As
a bonus, if mmap() fails in the method, the duplicated file descriptor
is closed rather than leaked.
Flag: EXEMPT bug-fix
Bug: 330108840
Test: atest
* libandroidfw_tests
Change-Id: I94a9240dbd06b255bff9491ea390b485bac3cb88
| -rw-r--r-- | libs/androidfw/CursorWindow.cpp | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/libs/androidfw/CursorWindow.cpp b/libs/androidfw/CursorWindow.cpp index 5e645cceea2d..a592749c5398 100644 --- a/libs/androidfw/CursorWindow.cpp +++ b/libs/androidfw/CursorWindow.cpp @@ -38,7 +38,7 @@ CursorWindow::CursorWindow() { } CursorWindow::~CursorWindow() { - if (mAshmemFd != -1) { + if (mAshmemFd >= 0) { ::munmap(mData, mSize); ::close(mAshmemFd); } else { @@ -155,23 +155,27 @@ status_t CursorWindow::createFromParcel(Parcel* parcel, CursorWindow** outWindow bool isAshmem; if (parcel->readBool(&isAshmem)) goto fail; if (isAshmem) { - window->mAshmemFd = parcel->readFileDescriptor(); - if (window->mAshmemFd < 0) { + int tempFd = parcel->readFileDescriptor(); + if (tempFd < 0) { LOG(ERROR) << "Failed readFileDescriptor"; goto fail_silent; } - window->mAshmemFd = ::fcntl(window->mAshmemFd, F_DUPFD_CLOEXEC, 0); - if (window->mAshmemFd < 0) { + tempFd = ::fcntl(tempFd, F_DUPFD_CLOEXEC, 0); + if (tempFd < 0) { PLOG(ERROR) << "Failed F_DUPFD_CLOEXEC"; goto fail_silent; } - window->mData = ::mmap(nullptr, window->mSize, PROT_READ, MAP_SHARED, window->mAshmemFd, 0); + window->mData = ::mmap(nullptr, window->mSize, PROT_READ, MAP_SHARED, tempFd, 0); if (window->mData == MAP_FAILED) { + ::close(tempFd); PLOG(ERROR) << "Failed mmap"; goto fail_silent; } + + window->mAshmemFd = tempFd; + } else { window->mAshmemFd = -1; |