aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Walls <awalls@md.metrocast.net>2010-12-19 19:59:56 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-12-29 05:17:10 -0500
commitddda424999817fbc17adf9013feb066903382ede (patch)
tree1f75abf4d6a4814519b74fce450296cd495ba56e
parentb0c45686c8e8aecc7b0cd04d9b6af48d74418d53 (diff)
[media] ivtv: Return EFAULT when copy_from_user() fails in ivtv_write_vbi_from_user()
If write() on a VBI device node fails due to a bad buffer pointer from userspace, we should notify the application properly with EFAULT, per the V4L2 API spec. Signed-off-by: Andy Walls <awalls@md.metrocast.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/video/ivtv/ivtv-fileops.c3
-rw-r--r--drivers/media/video/ivtv/ivtv-vbi.c14
-rw-r--r--drivers/media/video/ivtv/ivtv-vbi.h7
3 files changed, 15 insertions, 9 deletions
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c
index 4f46b0070806..c57a58523ca8 100644
--- a/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/drivers/media/video/ivtv/ivtv-fileops.c
@@ -570,9 +570,8 @@ ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t c
570 int elems = count / sizeof(struct v4l2_sliced_vbi_data); 570 int elems = count / sizeof(struct v4l2_sliced_vbi_data);
571 571
572 set_bit(IVTV_F_S_APPL_IO, &s->s_flags); 572 set_bit(IVTV_F_S_APPL_IO, &s->s_flags);
573 ivtv_write_vbi_from_user(itv, 573 return ivtv_write_vbi_from_user(itv,
574 (const struct v4l2_sliced_vbi_data __user *)user_buf, elems); 574 (const struct v4l2_sliced_vbi_data __user *)user_buf, elems);
575 return elems * sizeof(struct v4l2_sliced_vbi_data);
576 } 575 }
577 576
578 mode = s->type == IVTV_DEC_STREAM_TYPE_MPG ? OUT_MPG : OUT_YUV; 577 mode = s->type == IVTV_DEC_STREAM_TYPE_MPG ? OUT_MPG : OUT_YUV;
diff --git a/drivers/media/video/ivtv/ivtv-vbi.c b/drivers/media/video/ivtv/ivtv-vbi.c
index 7275f2d6597e..2dfa957b0fd5 100644
--- a/drivers/media/video/ivtv/ivtv-vbi.c
+++ b/drivers/media/video/ivtv/ivtv-vbi.c
@@ -157,24 +157,30 @@ static void ivtv_write_vbi(struct ivtv *itv,
157 ivtv_write_vbi_cc_lines(itv, &cc); 157 ivtv_write_vbi_cc_lines(itv, &cc);
158} 158}
159 159
160void ivtv_write_vbi_from_user(struct ivtv *itv, 160ssize_t
161 const struct v4l2_sliced_vbi_data __user *sliced, 161ivtv_write_vbi_from_user(struct ivtv *itv,
162 size_t cnt) 162 const struct v4l2_sliced_vbi_data __user *sliced,
163 size_t cnt)
163{ 164{
164 struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } }; 165 struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
165 int found_cc = 0; 166 int found_cc = 0;
166 size_t i; 167 size_t i;
167 struct v4l2_sliced_vbi_data d; 168 struct v4l2_sliced_vbi_data d;
169 ssize_t ret = cnt * sizeof(struct v4l2_sliced_vbi_data);
168 170
169 for (i = 0; i < cnt; i++) { 171 for (i = 0; i < cnt; i++) {
170 if (copy_from_user(&d, sliced + i, 172 if (copy_from_user(&d, sliced + i,
171 sizeof(struct v4l2_sliced_vbi_data))) 173 sizeof(struct v4l2_sliced_vbi_data))) {
174 ret = -EFAULT;
172 break; 175 break;
176 }
173 ivtv_write_vbi_line(itv, sliced + i, &cc, &found_cc); 177 ivtv_write_vbi_line(itv, sliced + i, &cc, &found_cc);
174 } 178 }
175 179
176 if (found_cc) 180 if (found_cc)
177 ivtv_write_vbi_cc_lines(itv, &cc); 181 ivtv_write_vbi_cc_lines(itv, &cc);
182
183 return ret;
178} 184}
179 185
180static void copy_vbi_data(struct ivtv *itv, int lines, u32 pts_stamp) 186static void copy_vbi_data(struct ivtv *itv, int lines, u32 pts_stamp)
diff --git a/drivers/media/video/ivtv/ivtv-vbi.h b/drivers/media/video/ivtv/ivtv-vbi.h
index eda38d0ad7ce..166dd0b75d0f 100644
--- a/drivers/media/video/ivtv/ivtv-vbi.h
+++ b/drivers/media/video/ivtv/ivtv-vbi.h
@@ -20,9 +20,10 @@
20#ifndef IVTV_VBI_H 20#ifndef IVTV_VBI_H
21#define IVTV_VBI_H 21#define IVTV_VBI_H
22 22
23void ivtv_write_vbi_from_user(struct ivtv *itv, 23ssize_t
24 const struct v4l2_sliced_vbi_data __user *sliced, 24ivtv_write_vbi_from_user(struct ivtv *itv,
25 size_t count); 25 const struct v4l2_sliced_vbi_data __user *sliced,
26 size_t count);
26void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf, 27void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf,
27 u64 pts_stamp, int streamtype); 28 u64 pts_stamp, int streamtype);
28int ivtv_used_line(struct ivtv *itv, int line, int field); 29int ivtv_used_line(struct ivtv *itv, int line, int field);