Ver código fonte

disp: msm: sde: fix null access for wb modes

Writeback modes are passed from DRM driver client and it may provide
invalid configuration. Add null checks for sde_wb_config provided by
client to avoid null access in subsequent calls.

Change-Id: I0924f8907d98e2ecb891cfc0c09191823d9033e8
Signed-off-by: Lakshmi Narayana Kalavala <[email protected]>
Lakshmi Narayana Kalavala 6 anos atrás
pai
commit
6da86ccee2
1 arquivos alterados com 48 adições e 44 exclusões
  1. 48 44
      msm/sde/sde_wb.c

+ 48 - 44
msm/sde/sde_wb.c

@@ -170,54 +170,58 @@ int sde_wb_connector_set_modes(struct sde_wb_device *wb_dev,
 	if (connected) {
 		SDE_DEBUG("connect\n");
 
-		if (count_modes && modes) {
-			modeinfo = kcalloc(count_modes,
-					sizeof(struct drm_mode_modeinfo),
-					GFP_KERNEL);
-			if (!modeinfo) {
-				SDE_ERROR("invalid params\n");
-				ret = -ENOMEM;
-				goto error;
-			}
+		if (!count_modes || !modes) {
+			SDE_ERROR("invalid count_modes :%u and modes :%d\n",
+				count_modes, !modes);
+			return -EINVAL;
+		}
 
-			if (copy_from_user(modeinfo, modes,
-					count_modes *
-					sizeof(struct drm_mode_modeinfo))) {
-				SDE_ERROR("failed to copy modes\n");
+		modeinfo = kcalloc(count_modes,
+				sizeof(struct drm_mode_modeinfo),
+				GFP_KERNEL);
+		if (!modeinfo) {
+			SDE_ERROR("invalid params\n");
+			ret = -ENOMEM;
+			goto error;
+		}
+
+		if (copy_from_user(modeinfo, modes,
+				count_modes *
+				sizeof(struct drm_mode_modeinfo))) {
+			SDE_ERROR("failed to copy modes\n");
+			kfree(modeinfo);
+			ret = -EFAULT;
+			goto error;
+		}
+
+		for (i = 0; i < count_modes; i++) {
+			struct drm_display_mode dispmode;
+
+			memset(&dispmode, 0, sizeof(dispmode));
+			ret = drm_mode_convert_umode(wb_dev->drm_dev,
+					&dispmode, &modeinfo[i]);
+			if (ret) {
+				SDE_ERROR(
+					"failed to convert mode %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x status:%d rc:%d\n",
+					i,
+					modeinfo[i].name,
+					modeinfo[i].vrefresh,
+					modeinfo[i].clock,
+					modeinfo[i].hdisplay,
+					modeinfo[i].hsync_start,
+					modeinfo[i].hsync_end,
+					modeinfo[i].htotal,
+					modeinfo[i].vdisplay,
+					modeinfo[i].vsync_start,
+					modeinfo[i].vsync_end,
+					modeinfo[i].vtotal,
+					modeinfo[i].type,
+					modeinfo[i].flags,
+					dispmode.status,
+					ret);
 				kfree(modeinfo);
-				ret = -EFAULT;
 				goto error;
 			}
-
-			for (i = 0; i < count_modes; i++) {
-				struct drm_display_mode dispmode;
-
-				memset(&dispmode, 0, sizeof(dispmode));
-				ret = drm_mode_convert_umode(wb_dev->drm_dev,
-						&dispmode, &modeinfo[i]);
-				if (ret) {
-					SDE_ERROR(
-						"failed to convert mode %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x status:%d rc:%d\n",
-						i,
-						modeinfo[i].name,
-						modeinfo[i].vrefresh,
-						modeinfo[i].clock,
-						modeinfo[i].hdisplay,
-						modeinfo[i].hsync_start,
-						modeinfo[i].hsync_end,
-						modeinfo[i].htotal,
-						modeinfo[i].vdisplay,
-						modeinfo[i].vsync_start,
-						modeinfo[i].vsync_end,
-						modeinfo[i].vtotal,
-						modeinfo[i].type,
-						modeinfo[i].flags,
-						dispmode.status,
-						ret);
-					kfree(modeinfo);
-					goto error;
-				}
-			}
 		}
 
 		if (wb_dev->modes) {