staging: stradis: fix error handling and information leak to userland
configure_saa7146() didn't free irq on error. saa_open() didn't decrease reference count of saa on error. saa_ioctl() leaked information from the kernel stack to userland as it didn't fill copied structs with zeros. Signed-off-by: Vasiliy Kulikov <segooon@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
c888d4e7b2
commit
ea07a9f255
|
@ -1286,6 +1286,7 @@ static long saa_ioctl(struct file *file,
|
||||||
case VIDIOCGCAP:
|
case VIDIOCGCAP:
|
||||||
{
|
{
|
||||||
struct video_capability b;
|
struct video_capability b;
|
||||||
|
memset(&b, 0, sizeof(b));
|
||||||
strcpy(b.name, saa->video_dev.name);
|
strcpy(b.name, saa->video_dev.name);
|
||||||
b.type = VID_TYPE_CAPTURE | VID_TYPE_OVERLAY |
|
b.type = VID_TYPE_CAPTURE | VID_TYPE_OVERLAY |
|
||||||
VID_TYPE_CLIPPING | VID_TYPE_FRAMERAM |
|
VID_TYPE_CLIPPING | VID_TYPE_FRAMERAM |
|
||||||
|
@ -1416,6 +1417,7 @@ static long saa_ioctl(struct file *file,
|
||||||
case VIDIOCGWIN:
|
case VIDIOCGWIN:
|
||||||
{
|
{
|
||||||
struct video_window vw;
|
struct video_window vw;
|
||||||
|
memset(&vw, 0, sizeof(vw));
|
||||||
vw.x = saa->win.x;
|
vw.x = saa->win.x;
|
||||||
vw.y = saa->win.y;
|
vw.y = saa->win.y;
|
||||||
vw.width = saa->win.width;
|
vw.width = saa->win.width;
|
||||||
|
@ -1448,6 +1450,7 @@ static long saa_ioctl(struct file *file,
|
||||||
case VIDIOCGFBUF:
|
case VIDIOCGFBUF:
|
||||||
{
|
{
|
||||||
struct video_buffer v;
|
struct video_buffer v;
|
||||||
|
memset(&v, 0, sizeof(v));
|
||||||
v.base = (void *)saa->win.vidadr;
|
v.base = (void *)saa->win.vidadr;
|
||||||
v.height = saa->win.sheight;
|
v.height = saa->win.sheight;
|
||||||
v.width = saa->win.swidth;
|
v.width = saa->win.swidth;
|
||||||
|
@ -1492,6 +1495,7 @@ static long saa_ioctl(struct file *file,
|
||||||
case VIDIOCGAUDIO:
|
case VIDIOCGAUDIO:
|
||||||
{
|
{
|
||||||
struct video_audio v;
|
struct video_audio v;
|
||||||
|
memset(&v, 0, sizeof(v));
|
||||||
v = saa->audio_dev;
|
v = saa->audio_dev;
|
||||||
v.flags &= ~(VIDEO_AUDIO_MUTE | VIDEO_AUDIO_MUTABLE);
|
v.flags &= ~(VIDEO_AUDIO_MUTE | VIDEO_AUDIO_MUTABLE);
|
||||||
v.flags |= VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME;
|
v.flags |= VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME;
|
||||||
|
@ -1534,6 +1538,7 @@ static long saa_ioctl(struct file *file,
|
||||||
case VIDIOCGUNIT:
|
case VIDIOCGUNIT:
|
||||||
{
|
{
|
||||||
struct video_unit vu;
|
struct video_unit vu;
|
||||||
|
memset(&vu, 0, sizeof(vu));
|
||||||
vu.video = saa->video_dev.minor;
|
vu.video = saa->video_dev.minor;
|
||||||
vu.vbi = VIDEO_NO_UNIT;
|
vu.vbi = VIDEO_NO_UNIT;
|
||||||
vu.radio = VIDEO_NO_UNIT;
|
vu.radio = VIDEO_NO_UNIT;
|
||||||
|
@ -1888,6 +1893,7 @@ static int saa_open(struct file *file)
|
||||||
|
|
||||||
saa->user++;
|
saa->user++;
|
||||||
if (saa->user > 1) {
|
if (saa->user > 1) {
|
||||||
|
saa->user--;
|
||||||
unlock_kernel();
|
unlock_kernel();
|
||||||
return 0; /* device open already, don't reset */
|
return 0; /* device open already, don't reset */
|
||||||
}
|
}
|
||||||
|
@ -2000,10 +2006,13 @@ static int __devinit configure_saa7146(struct pci_dev *pdev, int num)
|
||||||
if (retval < 0) {
|
if (retval < 0) {
|
||||||
dev_err(&pdev->dev, "%d: error in registering video device!\n",
|
dev_err(&pdev->dev, "%d: error in registering video device!\n",
|
||||||
num);
|
num);
|
||||||
goto errio;
|
goto errirq;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
errirq:
|
||||||
|
free_irq(saa->irq, saa);
|
||||||
errio:
|
errio:
|
||||||
iounmap(saa->saa7146_mem);
|
iounmap(saa->saa7146_mem);
|
||||||
err:
|
err:
|
||||||
|
|
Loading…
Reference in New Issue