hwc2: Fix NULL pointer dereference and out of bound access
Change-Id: Ib7a2ce818b1e6f5203f03138a95b2754ff446127
CRs-Fixed: 2114346
diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp
index e0396b6..a114af9 100644
--- a/sdm/libs/hwc2/hwc_session.cpp
+++ b/sdm/libs/hwc2/hwc_session.cpp
@@ -294,6 +294,10 @@
void HWCSession::GetCapabilities(struct hwc2_device *device, uint32_t *outCount,
int32_t *outCapabilities) {
+ if (!outCount) {
+ return;
+ }
+
int value = 0;
bool disable_skip_validate = false;
if (Debug::Get()->GetProperty("sdm.debug.disable_skip_validate", &value) == kErrorNone) {
@@ -320,12 +324,21 @@
// Defined in the same order as in the HWC2 header
int32_t HWCSession::AcceptDisplayChanges(hwc2_device_t *device, hwc2_display_t display) {
+ if (display >= HWC_NUM_DISPLAY_TYPES) {
+ return HWC2_ERROR_BAD_DISPLAY;
+ }
SCOPE_LOCK(locker_[display]);
return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::AcceptDisplayChanges);
}
int32_t HWCSession::CreateLayer(hwc2_device_t *device, hwc2_display_t display,
hwc2_layer_t *out_layer_id) {
+ if (!out_layer_id) {
+ return HWC2_ERROR_BAD_PARAMETER;
+ }
+ if (display >= HWC_NUM_DISPLAY_TYPES) {
+ return HWC2_ERROR_BAD_DISPLAY;
+ }
SEQUENCE_WAIT_SCOPE_LOCK(locker_[display]);
return CallDisplayFunction(device, display, &HWCDisplay::CreateLayer, out_layer_id);
}
@@ -338,6 +351,10 @@
return HWC2_ERROR_BAD_DISPLAY;
}
+ if (!out_display_id || !width || !height || !format) {
+ return HWC2_ERROR_BAD_PARAMETER;
+ }
+
HWCSession *hwc_session = static_cast<HWCSession *>(device);
auto status = hwc_session->CreateVirtualDisplayObject(width, height, format);
if (status == HWC2::Error::None) {
@@ -352,6 +369,9 @@
int32_t HWCSession::DestroyLayer(hwc2_device_t *device, hwc2_display_t display,
hwc2_layer_t layer) {
+ if (display >= HWC_NUM_DISPLAY_TYPES) {
+ return HWC2_ERROR_BAD_DISPLAY;
+ }
SEQUENCE_WAIT_SCOPE_LOCK(locker_[display]);
return CallDisplayFunction(device, display, &HWCDisplay::DestroyLayer, layer);
}
@@ -375,7 +395,7 @@
}
void HWCSession::Dump(hwc2_device_t *device, uint32_t *out_size, char *out_buffer) {
- if (!device) {
+ if (!device || !out_size) {
return;
}
auto *hwc_session = static_cast<HWCSession *>(device);
@@ -407,6 +427,10 @@
static int32_t GetChangedCompositionTypes(hwc2_device_t *device, hwc2_display_t display,
uint32_t *out_num_elements, hwc2_layer_t *out_layers,
int32_t *out_types) {
+ // null_ptr check only for out_num_elements, as out_layers and out_types can be null.
+ if (!out_num_elements) {
+ return HWC2_ERROR_BAD_PARAMETER;
+ }
return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetChangedCompositionTypes,
out_num_elements, out_layers, out_types);
}
diff --git a/sdm/libs/hwc2/hwc_session.h b/sdm/libs/hwc2/hwc_session.h
index 18c652d..b9032a4 100644
--- a/sdm/libs/hwc2/hwc_session.h
+++ b/sdm/libs/hwc2/hwc_session.h
@@ -78,6 +78,10 @@
static int32_t CallDisplayFunction(hwc2_device_t *device, hwc2_display_t display,
HWC2::Error (HWCDisplay::*member)(Args...), Args... args) {
if (!device) {
+ return HWC2_ERROR_BAD_PARAMETER;
+ }
+
+ if (display >= HWC_NUM_DISPLAY_TYPES) {
return HWC2_ERROR_BAD_DISPLAY;
}