Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/dp/mst: Validate REMOTE_I2C_READ harder

Make sure i2c msgs we're asked to transfer conform to the
requirements of REMOTE_I2C_READ. We were only checking that the
last message is a read, but we must also check that the preceding
messages are all writes. Also check that the length of each
message isn't too long.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180928180403.22499-2-ville.syrjala@linux.intel.com
Reviewed-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>

+18 -7
+18 -7
drivers/gpu/drm/drm_dp_mst_topology.c
··· 3250 3250 } 3251 3251 EXPORT_SYMBOL(drm_dp_mst_topology_mgr_destroy); 3252 3252 3253 + static bool remote_i2c_read_ok(const struct i2c_msg msgs[], int num) 3254 + { 3255 + int i; 3256 + 3257 + if (num - 1 > DP_REMOTE_I2C_READ_MAX_TRANSACTIONS) 3258 + return false; 3259 + 3260 + for (i = 0; i < num - 1; i++) { 3261 + if (msgs[i].flags & I2C_M_RD || 3262 + msgs[i].len > 0xff) 3263 + return false; 3264 + } 3265 + 3266 + return msgs[num - 1].flags & I2C_M_RD && 3267 + msgs[num - 1].len <= 0xff; 3268 + } 3269 + 3253 3270 /* I2C device */ 3254 3271 static int drm_dp_mst_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, 3255 3272 int num) ··· 3276 3259 struct drm_dp_mst_branch *mstb; 3277 3260 struct drm_dp_mst_topology_mgr *mgr = port->mgr; 3278 3261 unsigned int i; 3279 - bool reading = false; 3280 3262 struct drm_dp_sideband_msg_req_body msg; 3281 3263 struct drm_dp_sideband_msg_tx *txmsg = NULL; 3282 3264 int ret; ··· 3284 3268 if (!mstb) 3285 3269 return -EREMOTEIO; 3286 3270 3287 - /* construct i2c msg */ 3288 - /* see if last msg is a read */ 3289 - if (msgs[num - 1].flags & I2C_M_RD) 3290 - reading = true; 3291 - 3292 - if (!reading || (num - 1 > DP_REMOTE_I2C_READ_MAX_TRANSACTIONS)) { 3271 + if (!remote_i2c_read_ok(msgs, num)) { 3293 3272 DRM_DEBUG_KMS("Unsupported I2C transaction for MST device\n"); 3294 3273 ret = -EIO; 3295 3274 goto out;