mirror of
https://github.com/torvalds/linux.git
synced 2024-11-17 09:31:50 +00:00
zoran: racy refcount handling in vm_ops ->open()/->close()
worse, we lock ->resource_lock too late when we are destroying the final clonal VMA; the check for lack of other mappings of the same opened file can race with mmap(). Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
448293aadb
commit
4ad1f70ebc
@ -176,7 +176,7 @@ struct zoran_fh;
|
|||||||
|
|
||||||
struct zoran_mapping {
|
struct zoran_mapping {
|
||||||
struct zoran_fh *fh;
|
struct zoran_fh *fh;
|
||||||
int count;
|
atomic_t count;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct zoran_buffer {
|
struct zoran_buffer {
|
||||||
|
@ -2803,8 +2803,7 @@ static void
|
|||||||
zoran_vm_open (struct vm_area_struct *vma)
|
zoran_vm_open (struct vm_area_struct *vma)
|
||||||
{
|
{
|
||||||
struct zoran_mapping *map = vma->vm_private_data;
|
struct zoran_mapping *map = vma->vm_private_data;
|
||||||
|
atomic_inc(&map->count);
|
||||||
map->count++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -2815,7 +2814,7 @@ zoran_vm_close (struct vm_area_struct *vma)
|
|||||||
struct zoran *zr = fh->zr;
|
struct zoran *zr = fh->zr;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (--map->count > 0)
|
if (!atomic_dec_and_mutex_lock(&map->count, &zr->resource_lock))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
dprintk(3, KERN_INFO "%s: %s - munmap(%s)\n", ZR_DEVNAME(zr),
|
dprintk(3, KERN_INFO "%s: %s - munmap(%s)\n", ZR_DEVNAME(zr),
|
||||||
@ -2828,14 +2827,16 @@ zoran_vm_close (struct vm_area_struct *vma)
|
|||||||
kfree(map);
|
kfree(map);
|
||||||
|
|
||||||
/* Any buffers still mapped? */
|
/* Any buffers still mapped? */
|
||||||
for (i = 0; i < fh->buffers.num_buffers; i++)
|
for (i = 0; i < fh->buffers.num_buffers; i++) {
|
||||||
if (fh->buffers.buffer[i].map)
|
if (fh->buffers.buffer[i].map) {
|
||||||
|
mutex_unlock(&zr->resource_lock);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dprintk(3, KERN_INFO "%s: %s - free %s buffers\n", ZR_DEVNAME(zr),
|
dprintk(3, KERN_INFO "%s: %s - free %s buffers\n", ZR_DEVNAME(zr),
|
||||||
__func__, mode_name(fh->map_mode));
|
__func__, mode_name(fh->map_mode));
|
||||||
|
|
||||||
mutex_lock(&zr->resource_lock);
|
|
||||||
|
|
||||||
if (fh->map_mode == ZORAN_MAP_MODE_RAW) {
|
if (fh->map_mode == ZORAN_MAP_MODE_RAW) {
|
||||||
if (fh->buffers.active != ZORAN_FREE) {
|
if (fh->buffers.active != ZORAN_FREE) {
|
||||||
@ -2939,7 +2940,7 @@ zoran_mmap (struct file *file,
|
|||||||
goto mmap_unlock_and_return;
|
goto mmap_unlock_and_return;
|
||||||
}
|
}
|
||||||
map->fh = fh;
|
map->fh = fh;
|
||||||
map->count = 1;
|
atomic_set(&map->count, 1);
|
||||||
|
|
||||||
vma->vm_ops = &zoran_vm_ops;
|
vma->vm_ops = &zoran_vm_ops;
|
||||||
vma->vm_flags |= VM_DONTEXPAND;
|
vma->vm_flags |= VM_DONTEXPAND;
|
||||||
|
Loading…
Reference in New Issue
Block a user