[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);
|
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(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);
|
return elems * sizeof(struct v4l2_sliced_vbi_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,27 +92,22 @@ static int odd_parity(u8 c)
|
|||||||
return c & 1;
|
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;
|
struct vbi_info *vi = &itv->vbi;
|
||||||
struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
|
|
||||||
int found_cc = 0;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
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->id == V4L2_SLICED_CAPTION_525 && d->line == 21) {
|
||||||
if (d->field) {
|
if (d->field) {
|
||||||
cc.even[0] = d->data[0];
|
cc->even[0] = d->data[0];
|
||||||
cc.even[1] = d->data[1];
|
cc->even[1] = d->data[1];
|
||||||
} else {
|
} else {
|
||||||
cc.odd[0] = d->data[0];
|
cc->odd[0] = d->data[0];
|
||||||
cc.odd[1] = d->data[1];
|
cc->odd[1] = d->data[1];
|
||||||
}
|
}
|
||||||
found_cc = 1;
|
*found_cc = 1;
|
||||||
}
|
} else if (d->id == V4L2_SLICED_VPS && d->line == 16 && d->field == 0) {
|
||||||
else if (d->id == V4L2_SLICED_VPS && d->line == 16 && d->field == 0) {
|
|
||||||
struct vbi_vps vps;
|
struct vbi_vps vps;
|
||||||
|
|
||||||
vps.data[0] = d->data[2];
|
vps.data[0] = d->data[2];
|
||||||
@ -124,8 +119,8 @@ void ivtv_write_vbi(struct ivtv *itv, const struct v4l2_sliced_vbi_data *sliced,
|
|||||||
vi->vps_payload = vps;
|
vi->vps_payload = vps;
|
||||||
set_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags);
|
set_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags);
|
||||||
}
|
}
|
||||||
}
|
} else if (d->id == V4L2_SLICED_WSS_625 &&
|
||||||
else if (d->id == V4L2_SLICED_WSS_625 && d->line == 23 && d->field == 0) {
|
d->line == 23 && d->field == 0) {
|
||||||
int wss = d->data[0] | d->data[1] << 8;
|
int wss = d->data[0] | d->data[1] << 8;
|
||||||
|
|
||||||
if (vi->wss_payload != wss) {
|
if (vi->wss_payload != wss) {
|
||||||
@ -133,13 +128,55 @@ void ivtv_write_vbi(struct ivtv *itv, const struct v4l2_sliced_vbi_data *sliced,
|
|||||||
set_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags);
|
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;
|
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);
|
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++) {
|
||||||
|
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)
|
static void copy_vbi_data(struct ivtv *itv, int lines, u32 pts_stamp)
|
||||||
{
|
{
|
||||||
int line = 0;
|
int line = 0;
|
||||||
|
@ -20,7 +20,9 @@
|
|||||||
#ifndef IVTV_VBI_H
|
#ifndef IVTV_VBI_H
|
||||||
#define 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,
|
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…
x
Reference in New Issue
Block a user