From 80085d470d189362ddb6dda9bba6ee05fe7c84c6 Mon Sep 17 00:00:00 2001 From: "Gabriel M. Beddingfield" Date: Wed, 8 Feb 2012 16:53:32 -0600 Subject: pcm: Fix integer size error. The following code: while (pcm->boundary * 2 <= LONG_MAX - pcm->buffer_size) pcm->boundary *= 2; Creates an infinite loop on systems where LONG_MAX != INT_MAX (e.g. 64-bit systems). pcm->boundary is an unsigned int, and so INT_MAX is the proper value to use. --- pcm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pcm.c b/pcm.c index 2ef7075..fe2a8d6 100644 --- a/pcm.c +++ b/pcm.c @@ -558,7 +558,7 @@ struct pcm *pcm_open(unsigned int card, unsigned int device, sparams.silence_threshold = config->silence_threshold; pcm->boundary = sparams.boundary = pcm->buffer_size; - while (pcm->boundary * 2 <= LONG_MAX - pcm->buffer_size) + while (pcm->boundary * 2 <= INT_MAX - pcm->buffer_size) pcm->boundary *= 2; if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_SW_PARAMS, &sparams)) { -- cgit v1.2.3 From 3e3376a4b73e0475d6e1be9cf533ea4ae0674ee3 Mon Sep 17 00:00:00 2001 From: "Gabriel M. Beddingfield" Date: Mon, 28 Nov 2011 17:17:00 -0600 Subject: tinycap, tinyplay: Check *argv before dereferencing. In several places, argv is incremented and *argv is dereferenced without checking to see if it is valid to do so. This could lead to a buffer overrun if the user provides invalid parameters. This patch generally changes this: if (strcmp(*argv, "-r") == 0) { argv++; rate = atoi(*argv); } argv++; To this: if (strcmp(*argv, "-r") == 0) { argv++; if (*argv) rate = atoi(*argv); } if (*argv) argv++; Signed-off-by: Gabriel M. Beddingfield --- tinycap.c | 15 ++++++++++----- tinyplay.c | 6 ++++-- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/tinycap.c b/tinycap.c index 3eb5c60..586270b 100644 --- a/tinycap.c +++ b/tinycap.c @@ -93,18 +93,23 @@ int main(int argc, char **argv) while (*argv) { if (strcmp(*argv, "-d") == 0) { argv++; - device = atoi(*argv); + if (*argv) + device = atoi(*argv); } else if (strcmp(*argv, "-c") == 0) { argv++; - channels = atoi(*argv); + if (*argv) + channels = atoi(*argv); } else if (strcmp(*argv, "-r") == 0) { argv++; - rate = atoi(*argv); + if (*argv) + rate = atoi(*argv); } else if (strcmp(*argv, "-b") == 0) { argv++; - bits = atoi(*argv); + if (*argv) + bits = atoi(*argv); } - argv++; + if (*argv) + argv++; } header.riff_id = ID_RIFF; diff --git a/tinyplay.c b/tinyplay.c index 915a1ea..20b9ce3 100644 --- a/tinyplay.c +++ b/tinyplay.c @@ -79,9 +79,11 @@ int main(int argc, char **argv) while (*argv) { if (strcmp(*argv, "-d") == 0) { argv++; - device = atoi(*argv); + if (*argv) + device = atoi(*argv); } - argv++; + if (*argv) + argv++; } fread(&header, sizeof(struct wav_header), 1, file); -- cgit v1.2.3 From 9989fc25deb22ba1dde0ad6c30d34e1aff1931ed Mon Sep 17 00:00:00 2001 From: "Gabriel M. Beddingfield" Date: Wed, 8 Feb 2012 16:19:05 -0600 Subject: tinycap, tinyplay, tinymix: Add extra parameters. Command-line arguments are added for: tinyplay and tinycap: -D n -- card number -p n -- period size -n n -- number of periods per buffer tinymix: -D n -- card number Signed-off-by: Gabriel M. Beddingfield --- tinycap.c | 38 ++++++++++++++++++++++++++++---------- tinymix.c | 16 ++++++++++++++-- tinyplay.c | 41 +++++++++++++++++++++++++++++++---------- 3 files changed, 73 insertions(+), 22 deletions(-) diff --git a/tinycap.c b/tinycap.c index 586270b..a50c417 100644 --- a/tinycap.c +++ b/tinycap.c @@ -57,9 +57,10 @@ struct wav_header { int capturing = 1; -unsigned int capture_sample(FILE *file, unsigned int device, +unsigned int capture_sample(FILE *file, unsigned int card, unsigned int device, unsigned int channels, unsigned int rate, - unsigned int bits); + unsigned int bits, unsigned int period_size, + unsigned int period_count); void sigint_handler(int sig) { @@ -70,14 +71,17 @@ int main(int argc, char **argv) { FILE *file; struct wav_header header; + unsigned int card = 0; unsigned int device = 0; unsigned int channels = 2; unsigned int rate = 44100; unsigned int bits = 16; unsigned int frames; + unsigned int period_size = 1024; + unsigned int period_count = 4; if (argc < 2) { - fprintf(stderr, "Usage: %s file.wav [-d device] [-c channels] " + fprintf(stderr, "Usage: %s file.wav [-D card] [-d device] [-c channels] " "[-r rate] [-b bits]\n", argv[0]); return 1; } @@ -107,6 +111,18 @@ int main(int argc, char **argv) argv++; if (*argv) bits = atoi(*argv); + } else if (strcmp(*argv, "-D") == 0) { + argv++; + if (*argv) + card = atoi(*argv); + } else if (strcmp(*argv, "-p") == 0) { + argv++; + if (*argv) + period_size = atoi(*argv); + } else if (strcmp(*argv, "-n") == 0) { + argv++; + if (*argv) + period_count = atoi(*argv); } if (*argv) argv++; @@ -130,8 +146,9 @@ int main(int argc, char **argv) /* install signal handler and begin capturing */ signal(SIGINT, sigint_handler); - frames = capture_sample(file, device, header.num_channels, - header.sample_rate, header.bits_per_sample); + frames = capture_sample(file, card, device, header.num_channels, + header.sample_rate, header.bits_per_sample, + period_size, period_count); printf("Captured %d frames\n", frames); /* write header now all information is known */ @@ -144,9 +161,10 @@ int main(int argc, char **argv) return 0; } -unsigned int capture_sample(FILE *file, unsigned int device, +unsigned int capture_sample(FILE *file, unsigned int card, unsigned int device, unsigned int channels, unsigned int rate, - unsigned int bits) + unsigned int bits, unsigned int period_size, + unsigned int period_count) { struct pcm_config config; struct pcm *pcm; @@ -156,8 +174,8 @@ unsigned int capture_sample(FILE *file, unsigned int device, config.channels = channels; config.rate = rate; - config.period_size = 1024; - config.period_count = 4; + config.period_size = period_size; + config.period_count = period_count; if (bits == 32) config.format = PCM_FORMAT_S32_LE; else if (bits == 16) @@ -166,7 +184,7 @@ unsigned int capture_sample(FILE *file, unsigned int device, config.stop_threshold = 0; config.silence_threshold = 0; - pcm = pcm_open(0, device, PCM_IN, &config); + pcm = pcm_open(card, device, PCM_IN, &config); if (!pcm || !pcm_is_ready(pcm)) { fprintf(stderr, "Unable to open PCM device (%s)\n", pcm_get_error(pcm)); diff --git a/tinymix.c b/tinymix.c index b9c71a4..e7bd276 100644 --- a/tinymix.c +++ b/tinymix.c @@ -41,8 +41,20 @@ static void tinymix_print_enum(struct mixer_ctl *ctl, int print_all); int main(int argc, char **argv) { struct mixer *mixer; + int card = 0; + + if ((argc > 2) && (strcmp(argv[1], "-D") == 0)) { + argv++; + if (argv[1]) { + card = atoi(argv[1]); + argv++; + argc -= 2; + } else { + argc -= 1; + } + } - mixer = mixer_open(0); + mixer = mixer_open(card); if (!mixer) { fprintf(stderr, "Failed to open mixer\n"); return EXIT_FAILURE; @@ -55,7 +67,7 @@ int main(int argc, char **argv) else if (argc == 3) tinymix_set_value(mixer, atoi(argv[1]), argv[2]); else - printf("Usage: tinymix [control id] [value to set]\n"); + printf("Usage: tinymix [-D card] [control id] [value to set]\n"); mixer_close(mixer); diff --git a/tinyplay.c b/tinyplay.c index 20b9ce3..2251cfe 100644 --- a/tinyplay.c +++ b/tinyplay.c @@ -54,17 +54,22 @@ struct wav_header { uint32_t data_sz; }; -void play_sample(FILE *file, unsigned int device, unsigned int channels, - unsigned int rate, unsigned int bits); +void play_sample(FILE *file, unsigned int card, unsigned int device, unsigned int channels, + unsigned int rate, unsigned int bits, unsigned int period_size, + unsigned int period_count); int main(int argc, char **argv) { FILE *file; struct wav_header header; unsigned int device = 0; + unsigned int card = 0; + unsigned int period_size = 1024; + unsigned int period_count = 4; if (argc < 2) { - fprintf(stderr, "Usage: %s file.wav [-d device]\n", argv[0]); + fprintf(stderr, "Usage: %s file.wav [-D card] [-d device] [-p period_size]" + " [-n n_periods] \n", argv[0]); return 1; } @@ -82,6 +87,21 @@ int main(int argc, char **argv) if (*argv) device = atoi(*argv); } + if (strcmp(*argv, "-p") == 0) { + argv++; + if (*argv) + period_size = atoi(*argv); + } + if (strcmp(*argv, "-n") == 0) { + argv++; + if (*argv) + period_count = atoi(*argv); + } + if (strcmp(*argv, "-D") == 0) { + argv++; + if (*argv) + card = atoi(*argv); + } if (*argv) argv++; } @@ -98,16 +118,17 @@ int main(int argc, char **argv) return 1; } - play_sample(file, device, header.num_channels, header.sample_rate, - header.bits_per_sample); + play_sample(file, card, device, header.num_channels, header.sample_rate, + header.bits_per_sample, period_size, period_count); fclose(file); return 0; } -void play_sample(FILE *file, unsigned int device, unsigned int channels, - unsigned int rate, unsigned int bits) +void play_sample(FILE *file, unsigned int card, unsigned int device, unsigned int channels, + unsigned int rate, unsigned int bits, unsigned int period_size, + unsigned int period_count) { struct pcm_config config; struct pcm *pcm; @@ -117,8 +138,8 @@ void play_sample(FILE *file, unsigned int device, unsigned int channels, config.channels = channels; config.rate = rate; - config.period_size = 1024; - config.period_count = 4; + config.period_size = period_size; + config.period_count = period_count; if (bits == 32) config.format = PCM_FORMAT_S32_LE; else if (bits == 16) @@ -127,7 +148,7 @@ void play_sample(FILE *file, unsigned int device, unsigned int channels, config.stop_threshold = 0; config.silence_threshold = 0; - pcm = pcm_open(0, device, PCM_OUT, &config); + pcm = pcm_open(card, device, PCM_OUT, &config); if (!pcm || !pcm_is_ready(pcm)) { fprintf(stderr, "Unable to open PCM device %u (%s)\n", device, pcm_get_error(pcm)); -- cgit v1.2.3