lkml.org 
[lkml]   [2013]   [Oct]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH 1/1] drivers/vga: check decodes for vgaarb lock/unlock
Date
There is a bug that X windows system may use an invalid decodes iostat
on the VGA Arbiter device when lock and unlock. this may cause system
crash. So we must validate the value of iostat.

Signed-off-by: Li, Zhen-Hua <zhen-hual@hp.com>
---
drivers/gpu/vga/vgaarb.c | 55 ++++++++++++++++++++++++++++++++----------------
1 file changed, 37 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c
index af02597..4772367 100644
--- a/drivers/gpu/vga/vgaarb.c
+++ b/drivers/gpu/vga/vgaarb.c
@@ -906,8 +906,9 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf,
struct vga_arb_private *priv = file->private_data;
struct vga_arb_user_card *uc = NULL;
struct pci_dev *pdev;
+ struct vga_device *vgadev = NULL;

- unsigned int io_state;
+ unsigned int io_state = 0;

char *kbuf, *curr_pos;
size_t remaining = count;
@@ -927,6 +928,19 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf,
curr_pos = kbuf;
kbuf[count] = '\0'; /* Just to make sure... */

+ pdev = priv->target;
+ if (priv->target == NULL) {
+ pr_debug("No device found");
+ ret_val = -ENODEV;
+ goto done;
+ }
+ vgadev = vgadev_find(pdev);
+ if (vgadev == NULL) {
+ pr_debug("Could not find vga device for %s", pci_name(pdev));
+ ret_val = -ENODEV;
+ goto done;
+ }
+
if (strncmp(curr_pos, "lock ", 5) == 0) {
curr_pos += 5;
remaining -= 5;
@@ -937,14 +951,15 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf,
ret_val = -EPROTO;
goto done;
}
- if (io_state == VGA_RSRC_NONE) {
+ if ((vgadev->owns & io_state) != io_state) {
+ pr_debug("iostate (%x and %x ) do not match",
+ io_state, vgadev->owns);
+
ret_val = -EPROTO;
goto done;
}
-
- pdev = priv->target;
- if (priv->target == NULL) {
- ret_val = -ENODEV;
+ if (io_state == VGA_RSRC_NONE) {
+ ret_val = -EPROTO;
goto done;
}

@@ -969,14 +984,21 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf,

pr_debug("client 0x%p called 'unlock'\n", priv);

- if (strncmp(curr_pos, "all", 3) == 0)
+ if (strncmp(curr_pos, "all", 3) == 0) {
io_state = VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM;
- else {
+ } else {
if (!vga_str_to_iostate
(curr_pos, remaining, &io_state)) {
ret_val = -EPROTO;
goto done;
}
+ if ((vgadev->owns & io_state) != io_state) {
+ pr_debug("iostate (%x and %x ) do not match",
+ io_state, vgadev->owns);
+
+ ret_val = -EPROTO;
+ goto done;
+ }
/* TODO: Add this?
if (io_state == VGA_RSRC_NONE) {
ret_val = -EPROTO;
@@ -985,11 +1007,6 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf,
*/
}

- pdev = priv->target;
- if (priv->target == NULL) {
- ret_val = -ENODEV;
- goto done;
- }
for (i = 0; i < MAX_USER_CARDS; i++) {
if (priv->cards[i].pdev == pdev)
uc = &priv->cards[i];
@@ -1029,6 +1046,13 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf,
ret_val = -EPROTO;
goto done;
}
+ if ((vgadev->owns & io_state) != io_state) {
+ pr_debug("iostate (%x and %x ) do not match",
+ io_state, vgadev->owns);
+
+ ret_val = -EPROTO;
+ goto done;
+ }
/* TODO: Add this?
if (io_state == VGA_RSRC_NONE) {
ret_val = -EPROTO;
@@ -1036,11 +1060,6 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf,
}
*/

- pdev = priv->target;
- if (priv->target == NULL) {
- ret_val = -ENODEV;
- goto done;
- }

if (vga_tryget(pdev, io_state)) {
/* Update the client's locks lists... */
--
1.8.4.rc3


\
 
 \ /
  Last update: 2013-10-28 09:21    [W:0.029 / U:2.152 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site