diff options
author | Steven Toth <stoth@kernellabs.com> | 2010-07-31 14:11:59 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-10-21 05:54:53 -0400 |
commit | 46eeb8dd30d3651e6ea55c2e60594206cd591d79 (patch) | |
tree | ec3d2d34b7f6e7c68aadec8aca8091e213e274c4 | |
parent | 58acca1056434dbbbcb3f1aacd759f1039a3169d (diff) |
[media] saa7164: add guard bytes around critical buffers to detect failure
If the guard bytes are trampled then we have a memory related problem.
Signed-off-by: Steven Toth <stoth@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/video/saa7164/saa7164-core.c | 22 | ||||
-rw-r--r-- | drivers/media/video/saa7164/saa7164-encoder.c | 21 |
2 files changed, 37 insertions, 6 deletions
diff --git a/drivers/media/video/saa7164/saa7164-core.c b/drivers/media/video/saa7164/saa7164-core.c index 624ad3e1b61..e96bbe4698b 100644 --- a/drivers/media/video/saa7164/saa7164-core.c +++ b/drivers/media/video/saa7164/saa7164-core.c | |||
@@ -216,6 +216,7 @@ static void saa7164_work_enchandler(struct work_struct *w) | |||
216 | struct saa7164_user_buffer *ubuf; | 216 | struct saa7164_user_buffer *ubuf; |
217 | struct list_head *c, *n; | 217 | struct list_head *c, *n; |
218 | int wp, rp, i = 0; | 218 | int wp, rp, i = 0; |
219 | u8 *p; | ||
219 | 220 | ||
220 | port->last_svc_msecs_diff = port->last_svc_msecs; | 221 | port->last_svc_msecs_diff = port->last_svc_msecs; |
221 | port->last_svc_msecs = jiffies_to_msecs(jiffies); | 222 | port->last_svc_msecs = jiffies_to_msecs(jiffies); |
@@ -262,6 +263,20 @@ static void saa7164_work_enchandler(struct work_struct *w) | |||
262 | break; | 263 | break; |
263 | } | 264 | } |
264 | 265 | ||
266 | p = (u8 *)buf->cpu; | ||
267 | if ( (*(p + buf->actual_size + 0) != 0xff) || | ||
268 | (*(p + buf->actual_size + 1) != 0xff) || | ||
269 | (*(p + buf->actual_size + 2) != 0xff) || | ||
270 | (*(p + buf->actual_size + 3) != 0xff) || | ||
271 | (*(p + buf->actual_size + 0x10) != 0xff) || | ||
272 | (*(p + buf->actual_size + 0x11) != 0xff) || | ||
273 | (*(p + buf->actual_size + 0x12) != 0xff) || | ||
274 | (*(p + buf->actual_size + 0x13) != 0xff) ) | ||
275 | { | ||
276 | printk(KERN_ERR "buf %p failed guard check\n", buf); | ||
277 | saa7164_dumphex16(dev, p + buf->actual_size - 32, 64); | ||
278 | } | ||
279 | |||
265 | if (buf->idx == rp) { | 280 | if (buf->idx == rp) { |
266 | /* Found the buffer, deal with it */ | 281 | /* Found the buffer, deal with it */ |
267 | dprintk(DBGLVL_IRQ, "%s() wp: %d processing: %d\n", | 282 | dprintk(DBGLVL_IRQ, "%s() wp: %d processing: %d\n", |
@@ -278,9 +293,12 @@ static void saa7164_work_enchandler(struct work_struct *w) | |||
278 | ubuf = list_first_entry(&port->list_buf_free.list, | 293 | ubuf = list_first_entry(&port->list_buf_free.list, |
279 | struct saa7164_user_buffer, list); | 294 | struct saa7164_user_buffer, list); |
280 | 295 | ||
281 | if (ubuf->actual_size == buf->actual_size) | 296 | if (ubuf->actual_size == buf->actual_size) { |
282 | memcpy(ubuf->data, buf->cpu, | 297 | memcpy(ubuf->data, buf->cpu, |
283 | ubuf->actual_size); | 298 | ubuf->actual_size); |
299 | } else { | ||
300 | printk(KERN_ERR "buf %p actual fails match\n", buf); | ||
301 | } | ||
284 | 302 | ||
285 | /* Requeue the buffer on the free list */ | 303 | /* Requeue the buffer on the free list */ |
286 | ubuf->pos = 0; | 304 | ubuf->pos = 0; |
@@ -297,7 +315,7 @@ static void saa7164_work_enchandler(struct work_struct *w) | |||
297 | /* Ensure offset into buffer remains 0, fill buffer | 315 | /* Ensure offset into buffer remains 0, fill buffer |
298 | * with known bad data. */ | 316 | * with known bad data. */ |
299 | saa7164_buffer_zero_offsets(port, rp); | 317 | saa7164_buffer_zero_offsets(port, rp); |
300 | memset(buf->cpu, 0xDE, buf->pci_size); | 318 | memset(buf->cpu, 0xff, buf->pci_size); |
301 | 319 | ||
302 | break; | 320 | break; |
303 | } | 321 | } |
diff --git a/drivers/media/video/saa7164/saa7164-encoder.c b/drivers/media/video/saa7164/saa7164-encoder.c index 5f73ceded31..c61907d0efb 100644 --- a/drivers/media/video/saa7164/saa7164-encoder.c +++ b/drivers/media/video/saa7164/saa7164-encoder.c | |||
@@ -1038,14 +1038,18 @@ static ssize_t fops_read(struct file *file, char __user *buffer, | |||
1038 | saa7164_histogram_update(&port->read_interval, | 1038 | saa7164_histogram_update(&port->read_interval, |
1039 | port->last_read_msecs_diff); | 1039 | port->last_read_msecs_diff); |
1040 | 1040 | ||
1041 | if (*pos) | 1041 | if (*pos) { |
1042 | printk(KERN_ERR "%s() ESPIPE\n", __func__); | ||
1042 | return -ESPIPE; | 1043 | return -ESPIPE; |
1044 | } | ||
1043 | 1045 | ||
1044 | if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) { | 1046 | if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) { |
1045 | if (atomic_inc_return(&port->v4l_reader_count) == 1) { | 1047 | if (atomic_inc_return(&port->v4l_reader_count) == 1) { |
1046 | 1048 | ||
1047 | if (saa7164_encoder_initialize(port) < 0) | 1049 | if (saa7164_encoder_initialize(port) < 0) { |
1050 | printk(KERN_ERR "%s() EINVAL\n", __func__); | ||
1048 | return -EINVAL; | 1051 | return -EINVAL; |
1052 | } | ||
1049 | 1053 | ||
1050 | saa7164_encoder_start_streaming(port); | 1054 | saa7164_encoder_start_streaming(port); |
1051 | msleep(200); | 1055 | msleep(200); |
@@ -1056,6 +1060,7 @@ static ssize_t fops_read(struct file *file, char __user *buffer, | |||
1056 | if ((file->f_flags & O_NONBLOCK) == 0) { | 1060 | if ((file->f_flags & O_NONBLOCK) == 0) { |
1057 | if (wait_event_interruptible(port->wait_read, | 1061 | if (wait_event_interruptible(port->wait_read, |
1058 | saa7164_enc_next_buf(port))) { | 1062 | saa7164_enc_next_buf(port))) { |
1063 | printk(KERN_ERR "%s() ERESTARTSYS\n", __func__); | ||
1059 | return -ERESTARTSYS; | 1064 | return -ERESTARTSYS; |
1060 | } | 1065 | } |
1061 | } | 1066 | } |
@@ -1077,8 +1082,10 @@ static ssize_t fops_read(struct file *file, char __user *buffer, | |||
1077 | 1082 | ||
1078 | if (copy_to_user(buffer, p, cnt)) { | 1083 | if (copy_to_user(buffer, p, cnt)) { |
1079 | printk(KERN_ERR "%s() copy_to_user failed\n", __func__); | 1084 | printk(KERN_ERR "%s() copy_to_user failed\n", __func__); |
1080 | if (!ret) | 1085 | if (!ret) { |
1086 | printk(KERN_ERR "%s() EFAULT\n", __func__); | ||
1081 | ret = -EFAULT; | 1087 | ret = -EFAULT; |
1088 | } | ||
1082 | goto err; | 1089 | goto err; |
1083 | } | 1090 | } |
1084 | 1091 | ||
@@ -1087,6 +1094,10 @@ static ssize_t fops_read(struct file *file, char __user *buffer, | |||
1087 | buffer += cnt; | 1094 | buffer += cnt; |
1088 | ret += cnt; | 1095 | ret += cnt; |
1089 | 1096 | ||
1097 | if (ubuf->pos > ubuf->actual_size) { | ||
1098 | printk(KERN_ERR "read() pos > actual, huh?\n"); | ||
1099 | } | ||
1100 | |||
1090 | if (ubuf->pos == ubuf->actual_size) { | 1101 | if (ubuf->pos == ubuf->actual_size) { |
1091 | 1102 | ||
1092 | /* finished with current buffer, take next buffer */ | 1103 | /* finished with current buffer, take next buffer */ |
@@ -1109,8 +1120,10 @@ static ssize_t fops_read(struct file *file, char __user *buffer, | |||
1109 | } | 1120 | } |
1110 | } | 1121 | } |
1111 | err: | 1122 | err: |
1112 | if (!ret && !ubuf) | 1123 | if (!ret && !ubuf) { |
1124 | printk(KERN_ERR "%s() EAGAIN\n", __func__); | ||
1113 | ret = -EAGAIN; | 1125 | ret = -EAGAIN; |
1126 | } | ||
1114 | 1127 | ||
1115 | return ret; | 1128 | return ret; |
1116 | } | 1129 | } |