Commit 0c7ba7bc authored by Jaroslav Kysela's avatar Jaroslav Kysela

[ALSA] [SPARSE] Fix __user pointers

PCM Midlevel,RawMidi Midlevel,ALSA<-OSS emulation,ALSA sequencer
Fixed __user pointers including other misc fixes:
 - replaced the obsolete CONFIG_SND_IOCTL32_EMUL.
 - added the proper segment change before passing the kernel pointer
   as the user pointer in PCM code.
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent f951b386
...@@ -636,10 +636,10 @@ snd_pcm_sframes_t snd_pcm_oss_write3(snd_pcm_substream_t *substream, const char ...@@ -636,10 +636,10 @@ snd_pcm_sframes_t snd_pcm_oss_write3(snd_pcm_substream_t *substream, const char
if (in_kernel) { if (in_kernel) {
mm_segment_t fs; mm_segment_t fs;
fs = snd_enter_user(); fs = snd_enter_user();
ret = snd_pcm_lib_write(substream, ptr, frames); ret = snd_pcm_lib_write(substream, (void __user *)ptr, frames);
snd_leave_user(fs); snd_leave_user(fs);
} else { } else {
ret = snd_pcm_lib_write(substream, ptr, frames); ret = snd_pcm_lib_write(substream, (void __user *)ptr, frames);
} }
if (ret != -EPIPE && ret != -ESTRPIPE) if (ret != -EPIPE && ret != -ESTRPIPE)
break; break;
...@@ -679,10 +679,10 @@ snd_pcm_sframes_t snd_pcm_oss_read3(snd_pcm_substream_t *substream, char *ptr, s ...@@ -679,10 +679,10 @@ snd_pcm_sframes_t snd_pcm_oss_read3(snd_pcm_substream_t *substream, char *ptr, s
if (in_kernel) { if (in_kernel) {
mm_segment_t fs; mm_segment_t fs;
fs = snd_enter_user(); fs = snd_enter_user();
ret = snd_pcm_lib_read(substream, ptr, frames); ret = snd_pcm_lib_read(substream, (void __user *)ptr, frames);
snd_leave_user(fs); snd_leave_user(fs);
} else { } else {
ret = snd_pcm_lib_read(substream, ptr, frames); ret = snd_pcm_lib_read(substream, (void __user *)ptr, frames);
} }
if (ret == -EPIPE) { if (ret == -EPIPE) {
if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) { if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) {
...@@ -718,10 +718,10 @@ snd_pcm_sframes_t snd_pcm_oss_writev3(snd_pcm_substream_t *substream, void **buf ...@@ -718,10 +718,10 @@ snd_pcm_sframes_t snd_pcm_oss_writev3(snd_pcm_substream_t *substream, void **buf
if (in_kernel) { if (in_kernel) {
mm_segment_t fs; mm_segment_t fs;
fs = snd_enter_user(); fs = snd_enter_user();
ret = snd_pcm_lib_writev(substream, bufs, frames); ret = snd_pcm_lib_writev(substream, (void __user **)bufs, frames);
snd_leave_user(fs); snd_leave_user(fs);
} else { } else {
ret = snd_pcm_lib_writev(substream, bufs, frames); ret = snd_pcm_lib_writev(substream, (void __user **)bufs, frames);
} }
if (ret != -EPIPE && ret != -ESTRPIPE) if (ret != -EPIPE && ret != -ESTRPIPE)
break; break;
...@@ -758,10 +758,10 @@ snd_pcm_sframes_t snd_pcm_oss_readv3(snd_pcm_substream_t *substream, void **bufs ...@@ -758,10 +758,10 @@ snd_pcm_sframes_t snd_pcm_oss_readv3(snd_pcm_substream_t *substream, void **bufs
if (in_kernel) { if (in_kernel) {
mm_segment_t fs; mm_segment_t fs;
fs = snd_enter_user(); fs = snd_enter_user();
ret = snd_pcm_lib_readv(substream, bufs, frames); ret = snd_pcm_lib_readv(substream, (void __user **)bufs, frames);
snd_leave_user(fs); snd_leave_user(fs);
} else { } else {
ret = snd_pcm_lib_readv(substream, bufs, frames); ret = snd_pcm_lib_readv(substream, (void __user **)bufs, frames);
} }
if (ret != -EPIPE && ret != -ESTRPIPE) if (ret != -EPIPE && ret != -ESTRPIPE)
break; break;
...@@ -777,7 +777,7 @@ static ssize_t snd_pcm_oss_write2(snd_pcm_substream_t *substream, const char *bu ...@@ -777,7 +777,7 @@ static ssize_t snd_pcm_oss_write2(snd_pcm_substream_t *substream, const char *bu
snd_pcm_plugin_channel_t *channels; snd_pcm_plugin_channel_t *channels;
size_t oss_frame_bytes = (runtime->oss.plugin_first->src_width * runtime->oss.plugin_first->src_format.channels) / 8; size_t oss_frame_bytes = (runtime->oss.plugin_first->src_width * runtime->oss.plugin_first->src_format.channels) / 8;
if (!in_kernel) { if (!in_kernel) {
if (copy_from_user(runtime->oss.buffer, buf, bytes)) if (copy_from_user(runtime->oss.buffer, (const char __user *)buf, bytes))
return -EFAULT; return -EFAULT;
buf = runtime->oss.buffer; buf = runtime->oss.buffer;
} }
...@@ -839,7 +839,7 @@ static ssize_t snd_pcm_oss_write1(snd_pcm_substream_t *substream, const char __u ...@@ -839,7 +839,7 @@ static ssize_t snd_pcm_oss_write1(snd_pcm_substream_t *substream, const char __u
return xfer > 0 ? xfer : -EAGAIN; return xfer > 0 ? xfer : -EAGAIN;
} }
} else { } else {
tmp = snd_pcm_oss_write2(substream, (char *)buf, runtime->oss.period_bytes, 0); tmp = snd_pcm_oss_write2(substream, (const char *)buf, runtime->oss.period_bytes, 0);
if (tmp <= 0) if (tmp <= 0)
return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp; return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
runtime->oss.bytes += tmp; runtime->oss.bytes += tmp;
...@@ -858,7 +858,7 @@ static ssize_t snd_pcm_oss_read2(snd_pcm_substream_t *substream, char *buf, size ...@@ -858,7 +858,7 @@ static ssize_t snd_pcm_oss_read2(snd_pcm_substream_t *substream, char *buf, size
{ {
snd_pcm_runtime_t *runtime = substream->runtime; snd_pcm_runtime_t *runtime = substream->runtime;
snd_pcm_sframes_t frames, frames1; snd_pcm_sframes_t frames, frames1;
char *final_dst = buf; char __user *final_dst = (char __user *)buf;
if (runtime->oss.plugin_first) { if (runtime->oss.plugin_first) {
snd_pcm_plugin_channel_t *channels; snd_pcm_plugin_channel_t *channels;
size_t oss_frame_bytes = (runtime->oss.plugin_last->dst_width * runtime->oss.plugin_last->dst_format.channels) / 8; size_t oss_frame_bytes = (runtime->oss.plugin_last->dst_width * runtime->oss.plugin_last->dst_format.channels) / 8;
...@@ -1058,6 +1058,7 @@ static int snd_pcm_oss_sync(snd_pcm_oss_file_t *pcm_oss_file) ...@@ -1058,6 +1058,7 @@ static int snd_pcm_oss_sync(snd_pcm_oss_file_t *pcm_oss_file)
if (runtime->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED) { if (runtime->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED) {
size = (runtime->frame_bits * size) / 8; size = (runtime->frame_bits * size) / 8;
while (size > 0) { while (size > 0) {
mm_segment_t fs;
size_t size1 = size < runtime->oss.period_bytes ? size : runtime->oss.period_bytes; size_t size1 = size < runtime->oss.period_bytes ? size : runtime->oss.period_bytes;
size -= size1; size -= size1;
size1 *= 8; size1 *= 8;
...@@ -1065,7 +1066,9 @@ static int snd_pcm_oss_sync(snd_pcm_oss_file_t *pcm_oss_file) ...@@ -1065,7 +1066,9 @@ static int snd_pcm_oss_sync(snd_pcm_oss_file_t *pcm_oss_file)
snd_pcm_format_set_silence(runtime->format, snd_pcm_format_set_silence(runtime->format,
runtime->oss.buffer, runtime->oss.buffer,
size1); size1);
snd_pcm_lib_write(substream, runtime->oss.buffer, size1); fs = snd_enter_user();
snd_pcm_lib_write(substream, (void __user *)runtime->oss.buffer, size1);
snd_leave_user(fs);
} }
} else if (runtime->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) { } else if (runtime->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) {
void __user *buffers[runtime->channels]; void __user *buffers[runtime->channels];
......
...@@ -2677,7 +2677,7 @@ int snd_pcm_kernel_playback_ioctl(snd_pcm_substream_t *substream, ...@@ -2677,7 +2677,7 @@ int snd_pcm_kernel_playback_ioctl(snd_pcm_substream_t *substream,
int result; int result;
fs = snd_enter_user(); fs = snd_enter_user();
result = snd_pcm_playback_ioctl1(substream, cmd, arg); result = snd_pcm_playback_ioctl1(substream, cmd, (void __user *)arg);
snd_leave_user(fs); snd_leave_user(fs);
return result; return result;
} }
...@@ -2689,7 +2689,7 @@ int snd_pcm_kernel_capture_ioctl(snd_pcm_substream_t *substream, ...@@ -2689,7 +2689,7 @@ int snd_pcm_kernel_capture_ioctl(snd_pcm_substream_t *substream,
int result; int result;
fs = snd_enter_user(); fs = snd_enter_user();
result = snd_pcm_capture_ioctl1(substream, cmd, arg); result = snd_pcm_capture_ioctl1(substream, cmd, (void __user *)arg);
snd_leave_user(fs); snd_leave_user(fs);
return result; return result;
} }
......
...@@ -910,7 +910,8 @@ static long snd_rawmidi_kernel_read1(snd_rawmidi_substream_t *substream, ...@@ -910,7 +910,8 @@ static long snd_rawmidi_kernel_read1(snd_rawmidi_substream_t *substream,
memcpy(buf + result, runtime->buffer + runtime->appl_ptr, count1); memcpy(buf + result, runtime->buffer + runtime->appl_ptr, count1);
} else { } else {
spin_unlock_irqrestore(&runtime->lock, flags); spin_unlock_irqrestore(&runtime->lock, flags);
if (copy_to_user(buf + result, runtime->buffer + runtime->appl_ptr, count1)) { if (copy_to_user((char __user *)buf + result,
runtime->buffer + runtime->appl_ptr, count1)) {
return result > 0 ? result : -EFAULT; return result > 0 ? result : -EFAULT;
} }
spin_lock_irqsave(&runtime->lock, flags); spin_lock_irqsave(&runtime->lock, flags);
...@@ -969,7 +970,7 @@ static ssize_t snd_rawmidi_read(struct file *file, char __user *buf, size_t coun ...@@ -969,7 +970,7 @@ static ssize_t snd_rawmidi_read(struct file *file, char __user *buf, size_t coun
spin_lock_irq(&runtime->lock); spin_lock_irq(&runtime->lock);
} }
spin_unlock_irq(&runtime->lock); spin_unlock_irq(&runtime->lock);
count1 = snd_rawmidi_kernel_read1(substream, buf, count, 0); count1 = snd_rawmidi_kernel_read1(substream, (unsigned char *)buf, count, 0);
if (count1 < 0) if (count1 < 0)
return result > 0 ? result : count1; return result > 0 ? result : count1;
result += count1; result += count1;
...@@ -1137,7 +1138,8 @@ static long snd_rawmidi_kernel_write1(snd_rawmidi_substream_t * substream, const ...@@ -1137,7 +1138,8 @@ static long snd_rawmidi_kernel_write1(snd_rawmidi_substream_t * substream, const
memcpy(runtime->buffer + runtime->appl_ptr, buf, count1); memcpy(runtime->buffer + runtime->appl_ptr, buf, count1);
} else { } else {
spin_unlock_irqrestore(&runtime->lock, flags); spin_unlock_irqrestore(&runtime->lock, flags);
if (copy_from_user(runtime->buffer + runtime->appl_ptr, buf, count1)) { if (copy_from_user(runtime->buffer + runtime->appl_ptr,
(char __user *)buf, count1)) {
spin_lock_irqsave(&runtime->lock, flags); spin_lock_irqsave(&runtime->lock, flags);
result = result > 0 ? result : -EFAULT; result = result > 0 ? result : -EFAULT;
goto __end; goto __end;
...@@ -1202,7 +1204,7 @@ static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf, size ...@@ -1202,7 +1204,7 @@ static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf, size
spin_lock_irq(&runtime->lock); spin_lock_irq(&runtime->lock);
} }
spin_unlock_irq(&runtime->lock); spin_unlock_irq(&runtime->lock);
count1 = snd_rawmidi_kernel_write1(substream, buf, count, 0); count1 = snd_rawmidi_kernel_write1(substream, (unsigned char *)buf, count, 0);
if (count1 < 0) if (count1 < 0)
return result > 0 ? result : count1; return result > 0 ? result : count1;
result += count1; result += count1;
......
...@@ -413,7 +413,7 @@ static ssize_t snd_seq_read(struct file *file, char __user *buf, size_t count, l ...@@ -413,7 +413,7 @@ static ssize_t snd_seq_read(struct file *file, char __user *buf, size_t count, l
} }
count -= sizeof(snd_seq_event_t); count -= sizeof(snd_seq_event_t);
buf += sizeof(snd_seq_event_t); buf += sizeof(snd_seq_event_t);
err = snd_seq_expand_var_event(&cell->event, count, buf, 0, sizeof(snd_seq_event_t)); err = snd_seq_expand_var_event(&cell->event, count, (char *)buf, 0, sizeof(snd_seq_event_t));
if (err < 0) if (err < 0)
break; break;
result += err; result += err;
...@@ -1012,7 +1012,7 @@ static ssize_t snd_seq_write(struct file *file, const char __user *buf, size_t c ...@@ -1012,7 +1012,7 @@ static ssize_t snd_seq_write(struct file *file, const char __user *buf, size_t c
event.data.ext.ptr = (char*)buf + sizeof(snd_seq_event_t); event.data.ext.ptr = (char*)buf + sizeof(snd_seq_event_t);
len += extlen; /* increment data length */ len += extlen; /* increment data length */
} else { } else {
#if defined(CONFIG_SND_BIT32_EMUL) || defined(CONFIG_SND_BIT32_EMUL_MODULE) #ifdef CONFIG_COMPAT
if (client->convert32 && snd_seq_ev_is_varusr(&event)) { if (client->convert32 && snd_seq_ev_is_varusr(&event)) {
void *ptr = compat_ptr(event.data.raw32.d[1]); void *ptr = compat_ptr(event.data.raw32.d[1]);
event.data.ext.ptr = ptr; event.data.ext.ptr = ptr;
...@@ -2320,7 +2320,7 @@ int snd_seq_kernel_client_ctl(int clientid, unsigned int cmd, void *arg) ...@@ -2320,7 +2320,7 @@ int snd_seq_kernel_client_ctl(int clientid, unsigned int cmd, void *arg)
if (client == NULL) if (client == NULL)
return -ENXIO; return -ENXIO;
fs = snd_enter_user(); fs = snd_enter_user();
result = snd_seq_do_ioctl(client, cmd, arg); result = snd_seq_do_ioctl(client, cmd, (void __user *)arg);
snd_leave_user(fs); snd_leave_user(fs);
return result; return result;
} }
......
...@@ -430,7 +430,7 @@ static int instr_put(snd_seq_kinstr_ops_t *ops, ...@@ -430,7 +430,7 @@ static int instr_put(snd_seq_kinstr_ops_t *ops,
if (ev->data.ext.len < sizeof(snd_seq_instr_header_t)) if (ev->data.ext.len < sizeof(snd_seq_instr_header_t))
goto __return; goto __return;
if (copy_from_user(&put, ev->data.ext.ptr, sizeof(snd_seq_instr_header_t))) { if (copy_from_user(&put, (void __user *)ev->data.ext.ptr, sizeof(snd_seq_instr_header_t))) {
result = -EFAULT; result = -EFAULT;
goto __return; goto __return;
} }
...@@ -466,7 +466,7 @@ static int instr_put(snd_seq_kinstr_ops_t *ops, ...@@ -466,7 +466,7 @@ static int instr_put(snd_seq_kinstr_ops_t *ops,
if (instr->type == SNDRV_SEQ_INSTR_ATYPE_DATA) { if (instr->type == SNDRV_SEQ_INSTR_ATYPE_DATA) {
result = ops->put(ops->private_data, result = ops->put(ops->private_data,
instr, instr,
ev->data.ext.ptr + sizeof(snd_seq_instr_header_t), (void __user *)ev->data.ext.ptr + sizeof(snd_seq_instr_header_t),
ev->data.ext.len - sizeof(snd_seq_instr_header_t), ev->data.ext.len - sizeof(snd_seq_instr_header_t),
atomic, atomic,
put.cmd); put.cmd);
...@@ -513,7 +513,7 @@ static int instr_free(snd_seq_kinstr_ops_t *ops, ...@@ -513,7 +513,7 @@ static int instr_free(snd_seq_kinstr_ops_t *ops,
if (ev->data.ext.len < sizeof(snd_seq_instr_header_t)) if (ev->data.ext.len < sizeof(snd_seq_instr_header_t))
goto __return; goto __return;
if (copy_from_user(&ifree, ev->data.ext.ptr, sizeof(snd_seq_instr_header_t))) { if (copy_from_user(&ifree, (void __user *)ev->data.ext.ptr, sizeof(snd_seq_instr_header_t))) {
result = -EFAULT; result = -EFAULT;
goto __return; goto __return;
} }
......
...@@ -90,7 +90,7 @@ int snd_seq_dump_var_event(const snd_seq_event_t *event, snd_seq_dump_func_t fun ...@@ -90,7 +90,7 @@ int snd_seq_dump_var_event(const snd_seq_event_t *event, snd_seq_dump_func_t fun
if (event->data.ext.len & SNDRV_SEQ_EXT_USRPTR) { if (event->data.ext.len & SNDRV_SEQ_EXT_USRPTR) {
char buf[32]; char buf[32];
char __user *curptr = event->data.ext.ptr; char __user *curptr = (char __user *)event->data.ext.ptr;
while (len > 0) { while (len > 0) {
int size = sizeof(buf); int size = sizeof(buf);
if (len < size) if (len < size)
...@@ -134,7 +134,7 @@ static int seq_copy_in_kernel(char **bufptr, const void *src, int size) ...@@ -134,7 +134,7 @@ static int seq_copy_in_kernel(char **bufptr, const void *src, int size)
return 0; return 0;
} }
static int seq_copy_in_user(char **bufptr, const void *src, int size) static int seq_copy_in_user(char __user **bufptr, const void *src, int size)
{ {
if (copy_to_user(*bufptr, src, size)) if (copy_to_user(*bufptr, src, size))
return -EFAULT; return -EFAULT;
...@@ -158,7 +158,7 @@ int snd_seq_expand_var_event(const snd_seq_event_t *event, int count, char *buf, ...@@ -158,7 +158,7 @@ int snd_seq_expand_var_event(const snd_seq_event_t *event, int count, char *buf,
if (event->data.ext.len & SNDRV_SEQ_EXT_USRPTR) { if (event->data.ext.len & SNDRV_SEQ_EXT_USRPTR) {
if (! in_kernel) if (! in_kernel)
return -EINVAL; return -EINVAL;
if (copy_from_user(buf, event->data.ext.ptr, len)) if (copy_from_user(buf, (void __user *)event->data.ext.ptr, len))
return -EFAULT; return -EFAULT;
return newlen; return newlen;
} }
...@@ -336,7 +336,7 @@ int snd_seq_event_dup(pool_t *pool, snd_seq_event_t *event, snd_seq_event_cell_t ...@@ -336,7 +336,7 @@ int snd_seq_event_dup(pool_t *pool, snd_seq_event_t *event, snd_seq_event_cell_t
tmp->event = src->event; tmp->event = src->event;
src = src->next; src = src->next;
} else if (is_usrptr) { } else if (is_usrptr) {
if (copy_from_user(&tmp->event, buf, size)) { if (copy_from_user(&tmp->event, (char __user *)buf, size)) {
err = -EFAULT; err = -EFAULT;
goto __error; goto __error;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment