Merge "Prevent potential double frees in sg driver"
This commit is contained in:
commit
c4f4e49994
1 changed files with 18 additions and 10 deletions
|
@ -510,7 +510,7 @@ sg_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
|
||||||
old_hdr->result = EIO;
|
old_hdr->result = EIO;
|
||||||
break;
|
break;
|
||||||
case DID_ERROR:
|
case DID_ERROR:
|
||||||
old_hdr->result = (srp->sense_b[0] == 0 &&
|
old_hdr->result = (srp->sense_b[0] == 0 &&
|
||||||
hp->masked_status == GOOD) ? 0 : EIO;
|
hp->masked_status == GOOD) ? 0 : EIO;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -898,8 +898,10 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
if (!access_ok(VERIFY_WRITE, p, SZ_SG_IO_HDR))
|
if (!access_ok(VERIFY_WRITE, p, SZ_SG_IO_HDR))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
mutex_lock(&sfp->parentdp->open_rel_lock);
|
||||||
result = sg_new_write(sfp, filp, p, SZ_SG_IO_HDR,
|
result = sg_new_write(sfp, filp, p, SZ_SG_IO_HDR,
|
||||||
1, read_only, 1, &srp);
|
1, read_only, 1, &srp);
|
||||||
|
mutex_unlock(&sfp->parentdp->open_rel_lock);
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
return result;
|
return result;
|
||||||
result = wait_event_interruptible(sfp->read_wait,
|
result = wait_event_interruptible(sfp->read_wait,
|
||||||
|
@ -939,8 +941,10 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
|
||||||
sfp->low_dma = 1;
|
sfp->low_dma = 1;
|
||||||
if ((0 == sfp->low_dma) && !sfp->res_in_use) {
|
if ((0 == sfp->low_dma) && !sfp->res_in_use) {
|
||||||
val = (int) sfp->reserve.bufflen;
|
val = (int) sfp->reserve.bufflen;
|
||||||
|
mutex_lock(&sfp->parentdp->open_rel_lock);
|
||||||
sg_remove_scat(sfp, &sfp->reserve);
|
sg_remove_scat(sfp, &sfp->reserve);
|
||||||
sg_build_reserve(sfp, val);
|
sg_build_reserve(sfp, val);
|
||||||
|
mutex_unlock(&sfp->parentdp->open_rel_lock);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (atomic_read(&sdp->detaching))
|
if (atomic_read(&sdp->detaching))
|
||||||
|
@ -1009,8 +1013,8 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
|
||||||
result = get_user(val, ip);
|
result = get_user(val, ip);
|
||||||
if (result)
|
if (result)
|
||||||
return result;
|
return result;
|
||||||
if (val < 0)
|
if (val < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
val = min_t(int, val,
|
val = min_t(int, val,
|
||||||
max_sectors_bytes(sdp->device->request_queue));
|
max_sectors_bytes(sdp->device->request_queue));
|
||||||
mutex_lock(&sfp->f_mutex);
|
mutex_lock(&sfp->f_mutex);
|
||||||
|
@ -1020,9 +1024,10 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
|
||||||
mutex_unlock(&sfp->f_mutex);
|
mutex_unlock(&sfp->f_mutex);
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
mutex_lock(&sfp->parentdp->open_rel_lock);
|
||||||
sg_remove_scat(sfp, &sfp->reserve);
|
sg_remove_scat(sfp, &sfp->reserve);
|
||||||
sg_build_reserve(sfp, val);
|
sg_build_reserve(sfp, val);
|
||||||
|
mutex_unlock(&sfp->parentdp->open_rel_lock);
|
||||||
}
|
}
|
||||||
mutex_unlock(&sfp->f_mutex);
|
mutex_unlock(&sfp->f_mutex);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1149,14 +1154,14 @@ static long sg_compat_ioctl(struct file *filp, unsigned int cmd_in, unsigned lon
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
|
|
||||||
sdev = sdp->device;
|
sdev = sdp->device;
|
||||||
if (sdev->host->hostt->compat_ioctl) {
|
if (sdev->host->hostt->compat_ioctl) {
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = sdev->host->hostt->compat_ioctl(sdev, cmd_in, (void __user *)arg);
|
ret = sdev->host->hostt->compat_ioctl(sdev, cmd_in, (void __user *)arg);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -ENOIOCTLCMD;
|
return -ENOIOCTLCMD;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1646,7 +1651,7 @@ init_sg(void)
|
||||||
else
|
else
|
||||||
def_reserved_size = sg_big_buff;
|
def_reserved_size = sg_big_buff;
|
||||||
|
|
||||||
rc = register_chrdev_region(MKDEV(SCSI_GENERIC_MAJOR, 0),
|
rc = register_chrdev_region(MKDEV(SCSI_GENERIC_MAJOR, 0),
|
||||||
SG_MAX_DEVS, "sg");
|
SG_MAX_DEVS, "sg");
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -2304,7 +2309,7 @@ static const struct file_operations adio_fops = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static int sg_proc_single_open_dressz(struct inode *inode, struct file *file);
|
static int sg_proc_single_open_dressz(struct inode *inode, struct file *file);
|
||||||
static ssize_t sg_proc_write_dressz(struct file *filp,
|
static ssize_t sg_proc_write_dressz(struct file *filp,
|
||||||
const char __user *buffer, size_t count, loff_t *off);
|
const char __user *buffer, size_t count, loff_t *off);
|
||||||
static const struct file_operations dressz_fops = {
|
static const struct file_operations dressz_fops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
|
@ -2444,7 +2449,7 @@ static int sg_proc_single_open_adio(struct inode *inode, struct file *file)
|
||||||
return single_open(file, sg_proc_seq_show_int, &sg_allow_dio);
|
return single_open(file, sg_proc_seq_show_int, &sg_allow_dio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
sg_proc_write_adio(struct file *filp, const char __user *buffer,
|
sg_proc_write_adio(struct file *filp, const char __user *buffer,
|
||||||
size_t count, loff_t *off)
|
size_t count, loff_t *off)
|
||||||
{
|
{
|
||||||
|
@ -2465,7 +2470,7 @@ static int sg_proc_single_open_dressz(struct inode *inode, struct file *file)
|
||||||
return single_open(file, sg_proc_seq_show_int, &sg_big_buff);
|
return single_open(file, sg_proc_seq_show_int, &sg_big_buff);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
sg_proc_write_dressz(struct file *filp, const char __user *buffer,
|
sg_proc_write_dressz(struct file *filp, const char __user *buffer,
|
||||||
size_t count, loff_t *off)
|
size_t count, loff_t *off)
|
||||||
{
|
{
|
||||||
|
@ -2640,6 +2645,9 @@ static void sg_proc_debug_helper(struct seq_file *s, Sg_device * sdp)
|
||||||
seq_puts(s, srp->done ?
|
seq_puts(s, srp->done ?
|
||||||
((1 == srp->done) ? "rcv:" : "fin:")
|
((1 == srp->done) ? "rcv:" : "fin:")
|
||||||
: "act:");
|
: "act:");
|
||||||
|
seq_printf(s, srp->done ?
|
||||||
|
((1 == srp->done) ? "rcv:" : "fin:")
|
||||||
|
: "act:");
|
||||||
seq_printf(s, " id=%d blen=%d",
|
seq_printf(s, " id=%d blen=%d",
|
||||||
srp->header.pack_id, blen);
|
srp->header.pack_id, blen);
|
||||||
if (srp->done)
|
if (srp->done)
|
||||||
|
|
Loading…
Add table
Reference in a new issue