[media] ivtv: ivtv_write_vbi() should use copy_from_user() for user data buffers
ivtv_write_vbi() is used for both VBI data that came from the driver internally and VBI data that came from the user. However, it did not use copy_from_user() for reading the VBI data from the user buffers. This change adds a new version of the function, ivtv_write_vbi_from_user(), that uses copy_from_user() to read the VBI data provided via user buffers. This should resolve a sparse build warning reported by Dave Gilbert. Reported-by: Dr. David Alan Gilbert <linux at treblig.org> Signed-off-by: Andy Walls <awalls@md.metrocast.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
754f9969c3
commit
b0c45686c8
@ -570,7 +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);
|
||||
|
||||
set_bit(IVTV_F_S_APPL_IO, &s->s_flags);
|
||||
ivtv_write_vbi(itv, (const struct v4l2_sliced_vbi_data *)user_buf, elems);
|
||||
ivtv_write_vbi_from_user(itv,
|
||||
(const struct v4l2_sliced_vbi_data __user *)user_buf, elems);
|
||||
return elems * sizeof(struct v4l2_sliced_vbi_data);
|
||||
}
|
||||
|
||||
|
@ -92,52 +92,89 @@ static int odd_parity(u8 c)
|
||||
return c & 1;
|
||||
}
|
||||
|
||||
void ivtv_write_vbi(struct ivtv *itv, const struct v4l2_sliced_vbi_data *sliced, size_t cnt)
|
||||
static void ivtv_write_vbi_line(struct ivtv *itv,
|
||||
const struct v4l2_sliced_vbi_data *d,
|
||||
struct vbi_cc *cc, int *found_cc)
|
||||
{
|
||||
struct vbi_info *vi = &itv->vbi;
|
||||
|
||||
if (d->id == V4L2_SLICED_CAPTION_525 && d->line == 21) {
|
||||
if (d->field) {
|
||||
cc->even[0] = d->data[0];
|
||||
cc->even[1] = d->data[1];
|
||||
} else {
|
||||
cc->odd[0] = d->data[0];
|
||||
cc->odd[1] = d->data[1];
|
||||
}
|
||||
*found_cc = 1;
|
||||
} else if (d->id == V4L2_SLICED_VPS && d->line == 16 && d->field == 0) {
|
||||
struct vbi_vps vps;
|
||||
|
||||
vps.data[0] = d->data[2];
|
||||
vps.data[1] = d->data[8];
|
||||
vps.data[2] = d->data[9];
|
||||
vps.data[3] = d->data[10];
|
||||
vps.data[4] = d->data[11];
|
||||
if (memcmp(&vps, &vi->vps_payload, sizeof(vps))) {
|
||||
vi->vps_payload = vps;
|
||||
set_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags);
|
||||
}
|
||||
} else if (d->id == V4L2_SLICED_WSS_625 &&
|
||||
d->line == 23 && d->field == 0) {
|
||||
int wss = d->data[0] | d->data[1] << 8;
|
||||
|
||||
if (vi->wss_payload != wss) {
|
||||
vi->wss_payload = wss;
|
||||
set_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ivtv_write_vbi_cc_lines(struct ivtv *itv, const struct vbi_cc *cc)
|
||||
{
|
||||
struct vbi_info *vi = &itv->vbi;
|
||||
|
||||
if (vi->cc_payload_idx < ARRAY_SIZE(vi->cc_payload)) {
|
||||
memcpy(&vi->cc_payload[vi->cc_payload_idx], cc,
|
||||
sizeof(struct vbi_cc));
|
||||
vi->cc_payload_idx++;
|
||||
set_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
|
||||
}
|
||||
}
|
||||
|
||||
static void ivtv_write_vbi(struct ivtv *itv,
|
||||
const struct v4l2_sliced_vbi_data *sliced,
|
||||
size_t cnt)
|
||||
{
|
||||
struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
|
||||
int found_cc = 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < cnt; i++)
|
||||
ivtv_write_vbi_line(itv, sliced + i, &cc, &found_cc);
|
||||
|
||||
if (found_cc)
|
||||
ivtv_write_vbi_cc_lines(itv, &cc);
|
||||
}
|
||||
|
||||
void ivtv_write_vbi_from_user(struct ivtv *itv,
|
||||
const struct v4l2_sliced_vbi_data __user *sliced,
|
||||
size_t cnt)
|
||||
{
|
||||
struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
|
||||
int found_cc = 0;
|
||||
size_t i;
|
||||
struct v4l2_sliced_vbi_data d;
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
const struct v4l2_sliced_vbi_data *d = sliced + i;
|
||||
|
||||
if (d->id == V4L2_SLICED_CAPTION_525 && d->line == 21) {
|
||||
if (d->field) {
|
||||
cc.even[0] = d->data[0];
|
||||
cc.even[1] = d->data[1];
|
||||
} else {
|
||||
cc.odd[0] = d->data[0];
|
||||
cc.odd[1] = d->data[1];
|
||||
}
|
||||
found_cc = 1;
|
||||
}
|
||||
else if (d->id == V4L2_SLICED_VPS && d->line == 16 && d->field == 0) {
|
||||
struct vbi_vps vps;
|
||||
|
||||
vps.data[0] = d->data[2];
|
||||
vps.data[1] = d->data[8];
|
||||
vps.data[2] = d->data[9];
|
||||
vps.data[3] = d->data[10];
|
||||
vps.data[4] = d->data[11];
|
||||
if (memcmp(&vps, &vi->vps_payload, sizeof(vps))) {
|
||||
vi->vps_payload = vps;
|
||||
set_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags);
|
||||
}
|
||||
}
|
||||
else if (d->id == V4L2_SLICED_WSS_625 && d->line == 23 && d->field == 0) {
|
||||
int wss = d->data[0] | d->data[1] << 8;
|
||||
|
||||
if (vi->wss_payload != wss) {
|
||||
vi->wss_payload = wss;
|
||||
set_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (found_cc && vi->cc_payload_idx < ARRAY_SIZE(vi->cc_payload)) {
|
||||
vi->cc_payload[vi->cc_payload_idx++] = cc;
|
||||
set_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
|
||||
if (copy_from_user(&d, sliced + i,
|
||||
sizeof(struct v4l2_sliced_vbi_data)))
|
||||
break;
|
||||
ivtv_write_vbi_line(itv, sliced + i, &cc, &found_cc);
|
||||
}
|
||||
|
||||
if (found_cc)
|
||||
ivtv_write_vbi_cc_lines(itv, &cc);
|
||||
}
|
||||
|
||||
static void copy_vbi_data(struct ivtv *itv, int lines, u32 pts_stamp)
|
||||
|
@ -20,7 +20,9 @@
|
||||
#ifndef IVTV_VBI_H
|
||||
#define IVTV_VBI_H
|
||||
|
||||
void ivtv_write_vbi(struct ivtv *itv, const struct v4l2_sliced_vbi_data *sliced, size_t count);
|
||||
void ivtv_write_vbi_from_user(struct ivtv *itv,
|
||||
const struct v4l2_sliced_vbi_data __user *sliced,
|
||||
size_t count);
|
||||
void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf,
|
||||
u64 pts_stamp, int streamtype);
|
||||
int ivtv_used_line(struct ivtv *itv, int line, int field);
|
||||
|
Loading…
Reference in New Issue
Block a user