Unverified Commit ddf67b14 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!15644 ata: libata-sff: Ensure that we cannot write outside the allocated buffer

parents 045e2df9 a3b59ec1
Loading
Loading
Loading
Loading
+10 −8
Original line number Diff line number Diff line
@@ -602,7 +602,7 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
{
	struct ata_port *ap = qc->ap;
	struct page *page;
	unsigned int offset;
	unsigned int offset, count;

	if (!qc->cursg) {
		qc->curbytes = qc->nbytes;
@@ -618,25 +618,27 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
	page = nth_page(page, (offset >> PAGE_SHIFT));
	offset %= PAGE_SIZE;

	trace_ata_sff_pio_transfer_data(qc, offset, qc->sect_size);
	/* don't overrun current sg */
	count = min(qc->cursg->length - qc->cursg_ofs, qc->sect_size);

	trace_ata_sff_pio_transfer_data(qc, offset, count);

	/*
	 * Split the transfer when it splits a page boundary.  Note that the
	 * split still has to be dword aligned like all ATA data transfers.
	 */
	WARN_ON_ONCE(offset % 4);
	if (offset + qc->sect_size > PAGE_SIZE) {
	if (offset + count > PAGE_SIZE) {
		unsigned int split_len = PAGE_SIZE - offset;

		ata_pio_xfer(qc, page, offset, split_len);
		ata_pio_xfer(qc, nth_page(page, 1), 0,
			     qc->sect_size - split_len);
		ata_pio_xfer(qc, nth_page(page, 1), 0, count - split_len);
	} else {
		ata_pio_xfer(qc, page, offset, qc->sect_size);
		ata_pio_xfer(qc, page, offset, count);
	}

	qc->curbytes += qc->sect_size;
	qc->cursg_ofs += qc->sect_size;
	qc->curbytes += count;
	qc->cursg_ofs += count;

	if (qc->cursg_ofs == qc->cursg->length) {
		qc->cursg = sg_next(qc->cursg);