mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
[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>
This commit is contained in:
parent
b0c45686c8
commit
ddda424999
3 changed files with 15 additions and 9 deletions
|
@ -570,9 +570,8 @@ ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t c
|
||||||
int elems = count / sizeof(struct v4l2_sliced_vbi_data);
|
int elems = count / sizeof(struct v4l2_sliced_vbi_data);
|
||||||
|
|
||||||
set_bit(IVTV_F_S_APPL_IO, &s->s_flags);
|
set_bit(IVTV_F_S_APPL_IO, &s->s_flags);
|
||||||
ivtv_write_vbi_from_user(itv,
|
return ivtv_write_vbi_from_user(itv,
|
||||||
(const struct v4l2_sliced_vbi_data __user *)user_buf, elems);
|
(const struct v4l2_sliced_vbi_data __user *)user_buf, elems);
|
||||||
return elems * sizeof(struct v4l2_sliced_vbi_data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mode = s->type == IVTV_DEC_STREAM_TYPE_MPG ? OUT_MPG : OUT_YUV;
|
mode = s->type == IVTV_DEC_STREAM_TYPE_MPG ? OUT_MPG : OUT_YUV;
|
||||||
|
|
|
@ -157,24 +157,30 @@ static void ivtv_write_vbi(struct ivtv *itv,
|
||||||
ivtv_write_vbi_cc_lines(itv, &cc);
|
ivtv_write_vbi_cc_lines(itv, &cc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ivtv_write_vbi_from_user(struct ivtv *itv,
|
ssize_t
|
||||||
const struct v4l2_sliced_vbi_data __user *sliced,
|
ivtv_write_vbi_from_user(struct ivtv *itv,
|
||||||
size_t cnt)
|
const struct v4l2_sliced_vbi_data __user *sliced,
|
||||||
|
size_t cnt)
|
||||||
{
|
{
|
||||||
struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
|
struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
|
||||||
int found_cc = 0;
|
int found_cc = 0;
|
||||||
size_t i;
|
size_t i;
|
||||||
struct v4l2_sliced_vbi_data d;
|
struct v4l2_sliced_vbi_data d;
|
||||||
|
ssize_t ret = cnt * sizeof(struct v4l2_sliced_vbi_data);
|
||||||
|
|
||||||
for (i = 0; i < cnt; i++) {
|
for (i = 0; i < cnt; i++) {
|
||||||
if (copy_from_user(&d, sliced + i,
|
if (copy_from_user(&d, sliced + i,
|
||||||
sizeof(struct v4l2_sliced_vbi_data)))
|
sizeof(struct v4l2_sliced_vbi_data))) {
|
||||||
|
ret = -EFAULT;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
ivtv_write_vbi_line(itv, sliced + i, &cc, &found_cc);
|
ivtv_write_vbi_line(itv, sliced + i, &cc, &found_cc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (found_cc)
|
if (found_cc)
|
||||||
ivtv_write_vbi_cc_lines(itv, &cc);
|
ivtv_write_vbi_cc_lines(itv, &cc);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void copy_vbi_data(struct ivtv *itv, int lines, u32 pts_stamp)
|
static void copy_vbi_data(struct ivtv *itv, int lines, u32 pts_stamp)
|
||||||
|
|
|
@ -20,9 +20,10 @@
|
||||||
#ifndef IVTV_VBI_H
|
#ifndef IVTV_VBI_H
|
||||||
#define IVTV_VBI_H
|
#define IVTV_VBI_H
|
||||||
|
|
||||||
void ivtv_write_vbi_from_user(struct ivtv *itv,
|
ssize_t
|
||||||
const struct v4l2_sliced_vbi_data __user *sliced,
|
ivtv_write_vbi_from_user(struct ivtv *itv,
|
||||||
size_t count);
|
const struct v4l2_sliced_vbi_data __user *sliced,
|
||||||
|
size_t count);
|
||||||
void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf,
|
void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf,
|
||||||
u64 pts_stamp, int streamtype);
|
u64 pts_stamp, int streamtype);
|
||||||
int ivtv_used_line(struct ivtv *itv, int line, int field);
|
int ivtv_used_line(struct ivtv *itv, int line, int field);
|
||||||
|
|
Loading…
Reference in a new issue