diff options
author | Andy Walls <awalls@md.metrocast.net> | 2010-12-18 08:48:17 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-12-29 05:17:10 -0500 |
commit | b0c45686c8e8aecc7b0cd04d9b6af48d74418d53 (patch) | |
tree | d817077c5820d2ecec94d9cecf508a1e5df51513 /drivers/media/video/ivtv/ivtv-vbi.c | |
parent | 754f9969c323559a12bce1475f3c1e6574129856 (diff) |
[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>
Diffstat (limited to 'drivers/media/video/ivtv/ivtv-vbi.c')
-rw-r--r-- | drivers/media/video/ivtv/ivtv-vbi.c | 109 |
1 files changed, 73 insertions, 36 deletions
diff --git a/drivers/media/video/ivtv/ivtv-vbi.c b/drivers/media/video/ivtv/ivtv-vbi.c index e1c347e5ebd8..7275f2d6597e 100644 --- a/drivers/media/video/ivtv/ivtv-vbi.c +++ b/drivers/media/video/ivtv/ivtv-vbi.c | |||
@@ -92,54 +92,91 @@ static int odd_parity(u8 c) | |||
92 | return c & 1; | 92 | return c & 1; |
93 | } | 93 | } |
94 | 94 | ||
95 | void ivtv_write_vbi(struct ivtv *itv, const struct v4l2_sliced_vbi_data *sliced, size_t cnt) | 95 | static void ivtv_write_vbi_line(struct ivtv *itv, |
96 | const struct v4l2_sliced_vbi_data *d, | ||
97 | struct vbi_cc *cc, int *found_cc) | ||
96 | { | 98 | { |
97 | struct vbi_info *vi = &itv->vbi; | 99 | struct vbi_info *vi = &itv->vbi; |
98 | struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } }; | ||
99 | int found_cc = 0; | ||
100 | size_t i; | ||
101 | |||
102 | for (i = 0; i < cnt; i++) { | ||
103 | const struct v4l2_sliced_vbi_data *d = sliced + i; | ||
104 | 100 | ||
105 | if (d->id == V4L2_SLICED_CAPTION_525 && d->line == 21) { | 101 | if (d->id == V4L2_SLICED_CAPTION_525 && d->line == 21) { |
106 | if (d->field) { | 102 | if (d->field) { |
107 | cc.even[0] = d->data[0]; | 103 | cc->even[0] = d->data[0]; |
108 | cc.even[1] = d->data[1]; | 104 | cc->even[1] = d->data[1]; |
109 | } else { | 105 | } else { |
110 | cc.odd[0] = d->data[0]; | 106 | cc->odd[0] = d->data[0]; |
111 | cc.odd[1] = d->data[1]; | 107 | cc->odd[1] = d->data[1]; |
112 | } | ||
113 | found_cc = 1; | ||
114 | } | 108 | } |
115 | else if (d->id == V4L2_SLICED_VPS && d->line == 16 && d->field == 0) { | 109 | *found_cc = 1; |
116 | struct vbi_vps vps; | 110 | } else if (d->id == V4L2_SLICED_VPS && d->line == 16 && d->field == 0) { |
117 | 111 | struct vbi_vps vps; | |
118 | vps.data[0] = d->data[2]; | 112 | |
119 | vps.data[1] = d->data[8]; | 113 | vps.data[0] = d->data[2]; |
120 | vps.data[2] = d->data[9]; | 114 | vps.data[1] = d->data[8]; |
121 | vps.data[3] = d->data[10]; | 115 | vps.data[2] = d->data[9]; |
122 | vps.data[4] = d->data[11]; | 116 | vps.data[3] = d->data[10]; |
123 | if (memcmp(&vps, &vi->vps_payload, sizeof(vps))) { | 117 | vps.data[4] = d->data[11]; |
124 | vi->vps_payload = vps; | 118 | if (memcmp(&vps, &vi->vps_payload, sizeof(vps))) { |
125 | set_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags); | 119 | vi->vps_payload = vps; |
126 | } | 120 | set_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags); |
127 | } | 121 | } |
128 | else if (d->id == V4L2_SLICED_WSS_625 && d->line == 23 && d->field == 0) { | 122 | } else if (d->id == V4L2_SLICED_WSS_625 && |
129 | int wss = d->data[0] | d->data[1] << 8; | 123 | d->line == 23 && d->field == 0) { |
124 | int wss = d->data[0] | d->data[1] << 8; | ||
130 | 125 | ||
131 | if (vi->wss_payload != wss) { | 126 | if (vi->wss_payload != wss) { |
132 | vi->wss_payload = wss; | 127 | vi->wss_payload = wss; |
133 | set_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags); | 128 | set_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags); |
134 | } | ||
135 | } | 129 | } |
136 | } | 130 | } |
137 | if (found_cc && vi->cc_payload_idx < ARRAY_SIZE(vi->cc_payload)) { | 131 | } |
138 | vi->cc_payload[vi->cc_payload_idx++] = cc; | 132 | |
133 | static void ivtv_write_vbi_cc_lines(struct ivtv *itv, const struct vbi_cc *cc) | ||
134 | { | ||
135 | struct vbi_info *vi = &itv->vbi; | ||
136 | |||
137 | if (vi->cc_payload_idx < ARRAY_SIZE(vi->cc_payload)) { | ||
138 | memcpy(&vi->cc_payload[vi->cc_payload_idx], cc, | ||
139 | sizeof(struct vbi_cc)); | ||
140 | vi->cc_payload_idx++; | ||
139 | set_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags); | 141 | set_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags); |
140 | } | 142 | } |
141 | } | 143 | } |
142 | 144 | ||
145 | static void ivtv_write_vbi(struct ivtv *itv, | ||
146 | const struct v4l2_sliced_vbi_data *sliced, | ||
147 | size_t cnt) | ||
148 | { | ||
149 | struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } }; | ||
150 | int found_cc = 0; | ||
151 | size_t i; | ||
152 | |||
153 | for (i = 0; i < cnt; i++) | ||
154 | ivtv_write_vbi_line(itv, sliced + i, &cc, &found_cc); | ||
155 | |||
156 | if (found_cc) | ||
157 | ivtv_write_vbi_cc_lines(itv, &cc); | ||
158 | } | ||
159 | |||
160 | void ivtv_write_vbi_from_user(struct ivtv *itv, | ||
161 | const struct v4l2_sliced_vbi_data __user *sliced, | ||
162 | size_t cnt) | ||
163 | { | ||
164 | struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } }; | ||
165 | int found_cc = 0; | ||
166 | size_t i; | ||
167 | struct v4l2_sliced_vbi_data d; | ||
168 | |||
169 | for (i = 0; i < cnt; i++) { | ||
170 | if (copy_from_user(&d, sliced + i, | ||
171 | sizeof(struct v4l2_sliced_vbi_data))) | ||
172 | break; | ||
173 | ivtv_write_vbi_line(itv, sliced + i, &cc, &found_cc); | ||
174 | } | ||
175 | |||
176 | if (found_cc) | ||
177 | ivtv_write_vbi_cc_lines(itv, &cc); | ||
178 | } | ||
179 | |||
143 | static void copy_vbi_data(struct ivtv *itv, int lines, u32 pts_stamp) | 180 | static void copy_vbi_data(struct ivtv *itv, int lines, u32 pts_stamp) |
144 | { | 181 | { |
145 | int line = 0; | 182 | int line = 0; |