diff --git a/sys/dev/raid/mpr/mpr_user.c b/sys/dev/raid/mpr/mpr_user.c --- a/sys/dev/raid/mpr/mpr_user.c +++ b/sys/dev/raid/mpr/mpr_user.c @@ -862,10 +862,13 @@ mpr_printf(sc, "%s: user reply buffer (%d) " "smaller than returned buffer (%d)\n", __func__, data->ReplySize, sz); + sz = data->ReplySize; } mpr_unlock(sc); - copyout(cm->cm_reply, PTRIN(data->PtrReply), - data->ReplySize); + /* DF-1327: never copyout more than the actual reply + * length; ReplySize is user-controlled and was used + * directly, leaking kernel heap past cm->cm_reply. */ + copyout(cm->cm_reply, PTRIN(data->PtrReply), sz); mpr_lock(sc); } mprsas_free_tm(sc, cm); @@ -1088,9 +1091,12 @@ mpr_printf(sc, "%s: user reply buffer (%d) smaller " "than returned buffer (%d)\n", __func__, data->ReplySize, sz); + sz = data->ReplySize; } mpr_unlock(sc); - copyout(cm->cm_reply, PTRIN(data->PtrReply), data->ReplySize); + /* DF-1327: copyout is bounded by the real reply length, + * never by the user-supplied ReplySize. */ + copyout(cm->cm_reply, PTRIN(data->PtrReply), sz); mpr_lock(sc); if ((function == MPI2_FUNCTION_SCSI_IO_REQUEST) ||