Commit b3a58f3b authored by Stefan Haberland's avatar Stefan Haberland Committed by Heiko Carstens
Browse files

s390/dasd: Fix invalid dereferencing of indirect CCW data pointer



Fix invalid dereferencing of indirect CCW data pointer in
dasd_eckd_dump_sense() that leads to a kernel panic in error cases.

When using indirect addressing for DASD CCWs (IDAW) the CCW CDA pointer
does not contain the data address itself but a pointer to the IDAL.
This needs to be translated from physical to virtual as well before
using it.

This dereferencing is also used for dasd_page_cache and also fixed
although it is very unlikely that this code path ever gets used.

Fixes: c0bd3960 ("s390/dasd: use new address translation helpers")
Cc: stable@vger.kernel.org
Signed-off-by: default avatarStefan Haberland <sth@linux.ibm.com>
Reviewed-by: default avatarHeiko Carstens <hca@linux.ibm.com>
Signed-off-by: default avatarHeiko Carstens <hca@linux.ibm.com>
parent 2ae157ec
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -4906,7 +4906,7 @@ dasd_eckd_free_cp(struct dasd_ccw_req *cqr, struct request *req)
				ccw++;
			if (dst) {
				if (ccw->flags & CCW_FLAG_IDA)
					cda = *((char **)dma32_to_virt(ccw->cda));
					cda = dma64_to_virt(*((dma64_t *)dma32_to_virt(ccw->cda)));
				else
					cda = dma32_to_virt(ccw->cda);
				if (dst != cda) {
@@ -5525,7 +5525,7 @@ dasd_eckd_dump_ccw_range(struct dasd_device *device, struct ccw1 *from,

		/* get pointer to data (consider IDALs) */
		if (from->flags & CCW_FLAG_IDA)
			datap = (char *)*((addr_t *)dma32_to_virt(from->cda));
			datap = dma64_to_virt(*((dma64_t *)dma32_to_virt(from->cda)));
		else
			datap = dma32_to_virt(from->cda);

+1 −1
Original line number Diff line number Diff line
@@ -585,7 +585,7 @@ dasd_fba_free_cp(struct dasd_ccw_req *cqr, struct request *req)
				ccw++;
			if (dst) {
				if (ccw->flags & CCW_FLAG_IDA)
					cda = *((char **)dma32_to_virt(ccw->cda));
					cda = dma64_to_virt(*((dma64_t *)dma32_to_virt(ccw->cda)));
				else
					cda = dma32_to_virt(ccw->cda);
				if (dst != cda) {