hc
2024-10-12 a5969cabbb4660eab42b6ef0412cbbd1200cf14d
kernel/sound/core/oss/pcm_plugin.c
....@@ -61,7 +61,10 @@
6161 }
6262 if ((width = snd_pcm_format_physical_width(format->format)) < 0)
6363 return width;
64
- size = frames * format->channels * width;
64
+ size = array3_size(frames, format->channels, width);
65
+ /* check for too large period size once again */
66
+ if (size > 1024 * 1024)
67
+ return -ENOMEM;
6568 if (snd_BUG_ON(size % 8))
6669 return -ENXIO;
6770 size /= 8;
....@@ -196,102 +199,78 @@
196199 return 0;
197200 }
198201
199
-static snd_pcm_sframes_t plug_client_size(struct snd_pcm_substream *plug,
200
- snd_pcm_uframes_t drv_frames,
201
- bool check_size)
202
-{
203
- struct snd_pcm_plugin *plugin, *plugin_prev, *plugin_next;
204
- int stream;
205
-
206
- if (snd_BUG_ON(!plug))
207
- return -ENXIO;
208
- if (drv_frames == 0)
209
- return 0;
210
- stream = snd_pcm_plug_stream(plug);
211
- if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
212
- plugin = snd_pcm_plug_last(plug);
213
- while (plugin && drv_frames > 0) {
214
- plugin_prev = plugin->prev;
215
- if (plugin->src_frames)
216
- drv_frames = plugin->src_frames(plugin, drv_frames);
217
- if (check_size && plugin->buf_frames &&
218
- drv_frames > plugin->buf_frames)
219
- drv_frames = plugin->buf_frames;
220
- plugin = plugin_prev;
221
- }
222
- } else if (stream == SNDRV_PCM_STREAM_CAPTURE) {
223
- plugin = snd_pcm_plug_first(plug);
224
- while (plugin && drv_frames > 0) {
225
- plugin_next = plugin->next;
226
- if (check_size && plugin->buf_frames &&
227
- drv_frames > plugin->buf_frames)
228
- drv_frames = plugin->buf_frames;
229
- if (plugin->dst_frames)
230
- drv_frames = plugin->dst_frames(plugin, drv_frames);
231
- plugin = plugin_next;
232
- }
233
- } else
234
- snd_BUG();
235
- return drv_frames;
236
-}
237
-
238
-static snd_pcm_sframes_t plug_slave_size(struct snd_pcm_substream *plug,
239
- snd_pcm_uframes_t clt_frames,
202
+static snd_pcm_sframes_t calc_dst_frames(struct snd_pcm_substream *plug,
203
+ snd_pcm_sframes_t frames,
240204 bool check_size)
241205 {
242
- struct snd_pcm_plugin *plugin, *plugin_prev, *plugin_next;
243
- snd_pcm_sframes_t frames;
244
- int stream;
245
-
246
- if (snd_BUG_ON(!plug))
247
- return -ENXIO;
248
- if (clt_frames == 0)
249
- return 0;
250
- frames = clt_frames;
251
- stream = snd_pcm_plug_stream(plug);
252
- if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
253
- plugin = snd_pcm_plug_first(plug);
254
- while (plugin && frames > 0) {
255
- plugin_next = plugin->next;
256
- if (check_size && plugin->buf_frames &&
257
- frames > plugin->buf_frames)
258
- frames = plugin->buf_frames;
259
- if (plugin->dst_frames) {
260
- frames = plugin->dst_frames(plugin, frames);
261
- if (frames < 0)
262
- return frames;
263
- }
264
- plugin = plugin_next;
206
+ struct snd_pcm_plugin *plugin, *plugin_next;
207
+
208
+ plugin = snd_pcm_plug_first(plug);
209
+ while (plugin && frames > 0) {
210
+ plugin_next = plugin->next;
211
+ if (check_size && plugin->buf_frames &&
212
+ frames > plugin->buf_frames)
213
+ frames = plugin->buf_frames;
214
+ if (plugin->dst_frames) {
215
+ frames = plugin->dst_frames(plugin, frames);
216
+ if (frames < 0)
217
+ return frames;
265218 }
266
- } else if (stream == SNDRV_PCM_STREAM_CAPTURE) {
267
- plugin = snd_pcm_plug_last(plug);
268
- while (plugin) {
269
- plugin_prev = plugin->prev;
270
- if (plugin->src_frames) {
271
- frames = plugin->src_frames(plugin, frames);
272
- if (frames < 0)
273
- return frames;
274
- }
275
- if (check_size && plugin->buf_frames &&
276
- frames > plugin->buf_frames)
277
- frames = plugin->buf_frames;
278
- plugin = plugin_prev;
279
- }
280
- } else
281
- snd_BUG();
219
+ plugin = plugin_next;
220
+ }
282221 return frames;
283222 }
284223
285
-snd_pcm_sframes_t snd_pcm_plug_client_size(struct snd_pcm_substream *plug,
286
- snd_pcm_uframes_t drv_frames)
224
+static snd_pcm_sframes_t calc_src_frames(struct snd_pcm_substream *plug,
225
+ snd_pcm_sframes_t frames,
226
+ bool check_size)
287227 {
288
- return plug_client_size(plug, drv_frames, false);
228
+ struct snd_pcm_plugin *plugin, *plugin_prev;
229
+
230
+ plugin = snd_pcm_plug_last(plug);
231
+ while (plugin && frames > 0) {
232
+ plugin_prev = plugin->prev;
233
+ if (plugin->src_frames) {
234
+ frames = plugin->src_frames(plugin, frames);
235
+ if (frames < 0)
236
+ return frames;
237
+ }
238
+ if (check_size && plugin->buf_frames &&
239
+ frames > plugin->buf_frames)
240
+ frames = plugin->buf_frames;
241
+ plugin = plugin_prev;
242
+ }
243
+ return frames;
289244 }
290245
291
-snd_pcm_sframes_t snd_pcm_plug_slave_size(struct snd_pcm_substream *plug,
292
- snd_pcm_uframes_t clt_frames)
246
+snd_pcm_sframes_t snd_pcm_plug_client_size(struct snd_pcm_substream *plug, snd_pcm_uframes_t drv_frames)
293247 {
294
- return plug_slave_size(plug, clt_frames, false);
248
+ if (snd_BUG_ON(!plug))
249
+ return -ENXIO;
250
+ switch (snd_pcm_plug_stream(plug)) {
251
+ case SNDRV_PCM_STREAM_PLAYBACK:
252
+ return calc_src_frames(plug, drv_frames, false);
253
+ case SNDRV_PCM_STREAM_CAPTURE:
254
+ return calc_dst_frames(plug, drv_frames, false);
255
+ default:
256
+ snd_BUG();
257
+ return -EINVAL;
258
+ }
259
+}
260
+
261
+snd_pcm_sframes_t snd_pcm_plug_slave_size(struct snd_pcm_substream *plug, snd_pcm_uframes_t clt_frames)
262
+{
263
+ if (snd_BUG_ON(!plug))
264
+ return -ENXIO;
265
+ switch (snd_pcm_plug_stream(plug)) {
266
+ case SNDRV_PCM_STREAM_PLAYBACK:
267
+ return calc_dst_frames(plug, clt_frames, false);
268
+ case SNDRV_PCM_STREAM_CAPTURE:
269
+ return calc_src_frames(plug, clt_frames, false);
270
+ default:
271
+ snd_BUG();
272
+ return -EINVAL;
273
+ }
295274 }
296275
297276 static int snd_pcm_plug_formats(const struct snd_mask *mask,
....@@ -316,7 +295,7 @@
316295 return snd_mask_test(&formats, (__force int)format);
317296 }
318297
319
-static snd_pcm_format_t preferred_formats[] = {
298
+static const snd_pcm_format_t preferred_formats[] = {
320299 SNDRV_PCM_FORMAT_S16_LE,
321300 SNDRV_PCM_FORMAT_S16_BE,
322301 SNDRV_PCM_FORMAT_U16_LE,
....@@ -381,7 +360,7 @@
381360 if (snd_mask_test(format_mask, (__force int)format1))
382361 return format1;
383362 }
384
- /* fall through */
363
+ fallthrough;
385364 default:
386365 return (__force snd_pcm_format_t)-EINVAL;
387366 }
....@@ -650,7 +629,7 @@
650629 src_channels = dst_channels;
651630 plugin = next;
652631 }
653
- return plug_client_size(plug, frames, true);
632
+ return calc_src_frames(plug, frames, true);
654633 }
655634
656635 snd_pcm_sframes_t snd_pcm_plug_read_transfer(struct snd_pcm_substream *plug, struct snd_pcm_plugin_channel *dst_channels_final, snd_pcm_uframes_t size)
....@@ -660,7 +639,7 @@
660639 snd_pcm_sframes_t frames = size;
661640 int err;
662641
663
- frames = plug_slave_size(plug, frames, true);
642
+ frames = calc_src_frames(plug, frames, true);
664643 if (frames < 0)
665644 return frames;
666645