Merge "hwc2: Fix NULL pointer dereference and out of bound access"
diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp
index 74af5d8..390f39e 100644
--- a/sdm/libs/hwc2/hwc_session.cpp
+++ b/sdm/libs/hwc2/hwc_session.cpp
@@ -296,6 +296,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) {
@@ -322,12 +326,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);
}
@@ -339,6 +352,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);
@@ -354,6 +371,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);
}
@@ -377,7 +397,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);
@@ -409,6 +429,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 d28a407..3659370 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;
}