⬢ DragonFlyBSD Kernel Audit
DF-5047 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/raid/ida/ida.c
+++ b/sys/dev/raid/ida/ida.c
@@ -355,8 +355,16 @@
 	error = ida_wait(ida, qcb);
 	crit_exit();
 
-	/* XXX should have status returned here? */
-	/* XXX have "status pointer" area in QCB? */
+	/*
+	 * DF-5047: ida_wait() only reports queue/timeout failures; the
+	 * controller's own error status (HARD_ERROR / CMD_REJECTED) is
+	 * recorded by ida_done() in qcb->error.  Propagate it so callers
+	 * (notably idad_dump()) do not report success for failed commands.
+	 * (Reading qcb->error is race-free on the polling path used by
+	 * dumps; the tsleep path may race a fast qcb reuse on other CPUs.)
+	 */
+	if (error == 0)
+		error = qcb->error;
 
 	return (error);
 }
@@ -523,6 +531,8 @@
 		device_printf(ida->dev, "invalid request\n");
 	}
 
+	qcb->error = error ? EIO : 0;
+
 	if (qcb->flags & IDA_COMMAND) {
 		if (ida->flags & IDA_INTERRUPTS)
 			wakeup(qcb);