Commit ddda4249 authored by Andy Walls's avatar Andy Walls Committed by Mauro Carvalho Chehab

[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: default avatarAndy Walls <awalls@md.metrocast.net>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent b0c45686
...@@ -570,9 +570,8 @@ ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t c ...@@ -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,7 +157,8 @@ static void ivtv_write_vbi(struct ivtv *itv, ...@@ -157,7 +157,8 @@ 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
ivtv_write_vbi_from_user(struct ivtv *itv,
const struct v4l2_sliced_vbi_data __user *sliced, const struct v4l2_sliced_vbi_data __user *sliced,
size_t cnt) size_t cnt)
{ {
...@@ -165,16 +166,21 @@ void ivtv_write_vbi_from_user(struct ivtv *itv, ...@@ -165,16 +166,21 @@ void ivtv_write_vbi_from_user(struct ivtv *itv,
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,7 +20,8 @@ ...@@ -20,7 +20,8 @@
#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
ivtv_write_vbi_from_user(struct ivtv *itv,
const struct v4l2_sliced_vbi_data __user *sliced, const struct v4l2_sliced_vbi_data __user *sliced,
size_t count); 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,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment