Make pass driver better support CAM_CDB_POINTER flag.
Previously pass driver just ignored the flag, making random kernel code access user-space pointer, sometime causing crashes even for correctly written applications if user-level context was switched or swapped out. This patch tries to copyin the CDB into kernel space to avoid it. MFC after: 2 weeks
This commit is contained in:
parent
f5a12f2447
commit
7945b79f20
@ -1876,6 +1876,18 @@ passdoioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread
|
||||
break;
|
||||
}
|
||||
|
||||
if (ccb->ccb_h.flags & CAM_CDB_POINTER) {
|
||||
if (ccb->csio.cdb_len > IOCDBLEN) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
error = copyin(ccb->csio.cdb_io.cdb_ptr,
|
||||
ccb->csio.cdb_io.cdb_bytes, ccb->csio.cdb_len);
|
||||
if (error)
|
||||
break;
|
||||
ccb->ccb_h.flags &= ~CAM_CDB_POINTER;
|
||||
}
|
||||
|
||||
/*
|
||||
* Some CCB types, like scan bus and scan lun can only go
|
||||
* through the transport layer device.
|
||||
@ -2143,6 +2155,7 @@ passsendccb(struct cam_periph *periph, union ccb *ccb, union ccb *inccb)
|
||||
{
|
||||
struct pass_softc *softc;
|
||||
struct cam_periph_map_info mapinfo;
|
||||
uint8_t *cmd;
|
||||
xpt_opcode fc;
|
||||
int error;
|
||||
|
||||
@ -2154,6 +2167,14 @@ passsendccb(struct cam_periph *periph, union ccb *ccb, union ccb *inccb)
|
||||
*/
|
||||
xpt_merge_ccb(ccb, inccb);
|
||||
|
||||
if (ccb->ccb_h.flags & CAM_CDB_POINTER) {
|
||||
cmd = __builtin_alloca(ccb->csio.cdb_len);
|
||||
error = copyin(ccb->csio.cdb_io.cdb_ptr, cmd, ccb->csio.cdb_len);
|
||||
if (error)
|
||||
return (error);
|
||||
ccb->csio.cdb_io.cdb_ptr = cmd;
|
||||
}
|
||||
|
||||
/*
|
||||
*/
|
||||
ccb->ccb_h.cbfcnp = passdone;
|
||||
|
Loading…
x
Reference in New Issue
Block a user