Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > fc11cd6e1c513a17304da94a5390f3cd > files > 3647

kernel-2.6.18-194.11.1.el5.src.rpm

From: David Jeffery <djeffery@redhat.com>
Date: Mon, 28 Sep 2009 15:43:04 -0400
Subject: [scsi] st.c: memory use after free after MTSETBLK ioctl
Message-id: 1931932430.588751254166984157.JavaMail.root@zmail02.collab.prod.int.phx2.redhat.com
O-Subject: [PATCH RHEL5.5] BZ 520192: st.c, possible memory use after free after MTSETBLK ioctl
Bugzilla: 520192
RH-Acked-by: Jay Fenlason <fenlason@redhat.com>
RH-Acked-by: Prarit Bhargava <prarit@redhat.com>
RH-Acked-by: David Milburn <dmilburn@redhat.com>
RH-Acked-by: David Howells <dhowells@redhat.com>

Resolves BZ 520192.

A memory use after free bug can manifest if the MTSETBLK or SET_DENS_AND_BLK
ioctl features are used to set a scsi tape's blocksize from 0 to non-zero.
After the driver sets the new block size, in this one case it calls
normalize_buffer() to free the device's internal data buffers.  However, the
ioctl code assumes there is always a buffer and does not check or allocate
a buffer if there isn't one.  So any following ioctl calls can corrupt
a part of memory by writing data to memory that the st driver had freed.

This patch has been submitted upstream and fixes the problem by removing
this call to normalize_buffer().  The call to normalize_buffer() doesn't
serve a real purpose any more.  There is no need to drop all buffer memory
for this one case of a block size change.

diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 08c2ee0..f50405f 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -2791,11 +2791,8 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon
 			ioctl_result = st_int_ioctl(STp, MTBSF, 1);
 
 		if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) {
-			int old_block_size = STp->block_size;
 			STp->block_size = arg & MT_ST_BLKSIZE_MASK;
 			if (STp->block_size != 0) {
-				if (old_block_size == 0)
-					normalize_buffer(STp->buffer);
 				(STp->buffer)->buffer_blocks =
 				    (STp->buffer)->buffer_size / STp->block_size;
 			}