summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Morton <akpm@digeo.com>2003-06-04 08:32:16 -0700
committerDavid Mosberger <davidm@tiger.hpl.hp.com>2003-06-04 08:32:16 -0700
commitff94d27a35889a938f4a1228b8bf5789d26292ee (patch)
treef7c262ef7c959d77c5ae7b466b2d5ca6c8b4050d
parent2cb28602fb6124ba0b07cd40e95d3fff8cad4330 (diff)
[PATCH] cmpci: fix improper access to userspace
From: Hollis Blanchard <hollisb@us.ibm.com> Fix a direct userspace access, found by the Stanford checker.
-rw-r--r--sound/oss/cmpci.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/sound/oss/cmpci.c b/sound/oss/cmpci.c
index f9d784231635..7a163c32aacb 100644
--- a/sound/oss/cmpci.c
+++ b/sound/oss/cmpci.c
@@ -580,15 +580,17 @@ static void set_ac3(struct cm_state *s, unsigned rate)
spin_unlock_irqrestore(&s->lock, flags);
}
-static void trans_ac3(struct cm_state *s, void *dest, const char *source, int size)
+static int trans_ac3(struct cm_state *s, void *dest, const char *source, int size)
{
int i = size / 2;
+ int err;
unsigned long data;
unsigned long *dst = (unsigned long *) dest;
unsigned short *src = (unsigned short *)source;
do {
- data = (unsigned long) *src++;
+ if ((err = __get_user(data, src++)))
+ return err;
data <<= 12; // ok for 16-bit data
if (s->spdif_counter == 2 || s->spdif_counter == 3)
data |= 0x40000000; // indicate AC-3 raw data
@@ -605,6 +607,8 @@ static void trans_ac3(struct cm_state *s, void *dest, const char *source, int si
if (s->spdif_counter == 384)
s->spdif_counter = 0;
} while (--i);
+
+ return 0;
}
static void set_adc_rate_unlocked(struct cm_state *s, unsigned rate)
@@ -1655,13 +1659,16 @@ static ssize_t cm_write(struct file *file, const char *buffer, size_t count, lof
continue;
}
if (s->status & DO_AC3_SW) {
+ int err;
+
// clip exceeded data, caught by 033 and 037
if (swptr + 2 * cnt > s->dma_dac.dmasize)
cnt = (s->dma_dac.dmasize - swptr) / 2;
- trans_ac3(s, s->dma_dac.rawbuf + swptr, buffer, cnt);
+ if ((err = trans_ac3(s, s->dma_dac.rawbuf + swptr, buffer, cnt)))
+ return err;
swptr = (swptr + 2 * cnt) % s->dma_dac.dmasize;
} else if (s->status & DO_DUAL_DAC) {
- int i;
+ int i, err;
unsigned long *src, *dst0, *dst1;
src = (unsigned long *) buffer;
@@ -1669,8 +1676,10 @@ static ssize_t cm_write(struct file *file, const char *buffer, size_t count, lof
dst1 = (unsigned long *) (s->dma_adc.rawbuf + swptr);
// copy left/right sample at one time
for (i = 0; i <= cnt / 4; i++) {
- *dst0++ = *src++;
- *dst1++ = *src++;
+ if ((err = __get_user(*dst0++, src++)))
+ return err;
+ if ((err = __get_user(*dst1++, src++)))
+ return err;
}
swptr = (swptr + cnt) % s->dma_dac.dmasize;
} else {