Update of /cvsroot/alsa/alsa-kernel/core/ioctl32 In directory usw-pr-cvs1:/tmp/cvs-serv4129
Modified Files: hwdep32.c ioctl32.c ioctl32.h pcm32.c Log Message: - removed invalid kernel locks. - register ioctls as much as possible even after error is returned at registration. the error is likely duplicated items with others. - fixed duplicated entries. - fixed security holes. move set_fs() around ioctls as minimum as possible. Index: hwdep32.c =================================================================== RCS file: /cvsroot/alsa/alsa-kernel/core/ioctl32/hwdep32.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- hwdep32.c 12 Aug 2002 08:43:45 -0000 1.3 +++ hwdep32.c 29 Aug 2002 16:23:05 -0000 1.4 @@ -28,7 +28,5 @@ struct ioctl32_mapper hwdep_mappers[] = { { SNDRV_HWDEP_IOCTL_PVERSION, NULL }, { SNDRV_HWDEP_IOCTL_INFO, NULL }, - { SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE, NULL }, - { SNDRV_CTL_IOCTL_HWDEP_INFO, NULL }, { 0 }, }; Index: ioctl32.c =================================================================== RCS file: /cvsroot/alsa/alsa-kernel/core/ioctl32/ioctl32.c,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- ioctl32.c 12 Aug 2002 08:43:45 -0000 1.9 +++ ioctl32.c 29 Aug 2002 16:23:05 -0000 1.10 @@ -47,14 +47,10 @@ int err; struct ioctl32_mapper *m; - lock_kernel(); for (m = mappers; m->cmd; m++) { err = register_ioctl32_conversion(m->cmd, m->handler); - if (err < 0) { - unlock_kernel(); - return err; - } - m->registered++; + if (err >= 0) + m->registered++; } return 0; } @@ -63,14 +59,12 @@ { struct ioctl32_mapper *m; - lock_kernel(); for (m = mappers; m->cmd; m++) { if (m->registered) { unregister_ioctl32_conversion(m->cmd); m->registered = 0; } } - unlock_kernel(); } @@ -100,36 +94,32 @@ { struct sndrv_ctl_elem_list32 data32; struct sndrv_ctl_elem_list data; - mm_segment_t oldseg = get_fs(); + mm_segment_t oldseg; int err; - set_fs(KERNEL_DS); - if (copy_from_user(&data32, (void*)arg, sizeof(data32))) { - err = -EFAULT; - goto __err; - } + if (copy_from_user(&data32, (void*)arg, sizeof(data32))) + return -EFAULT; memset(&data, 0, sizeof(data)); data.offset = data32.offset; data.space = data32.space; data.used = data32.used; data.count = data32.count; data.pids = A(data32.pids); + oldseg = get_fs(); + set_fs(KERNEL_DS); err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)&data); + set_fs(oldseg); if (err < 0) - goto __err; + return err; /* copy the result */ data32.offset = data.offset; data32.space = data.space; data32.used = data.used; data32.count = data.count; //data.pids = data.pids; - if (copy_to_user((void*)arg, &data32, sizeof(data32))) { - err = -EFAULT; - goto __err; - } - __err: - set_fs(oldseg); - return err; + if (copy_to_user((void*)arg, &data32, sizeof(data32))) + return -EFAULT; + return 0; } DEFINE_ALSA_IOCTL_ENTRY(ctl_elem_list, ctl_elem_list, SNDRV_CTL_IOCTL_ELEM_LIST); @@ -171,22 +161,22 @@ struct sndrv_ctl_elem_info data; struct sndrv_ctl_elem_info32 data32; int err; - mm_segment_t oldseg = get_fs(); + mm_segment_t oldseg; - set_fs(KERNEL_DS); - if (copy_from_user(&data32, (void*)arg, sizeof(data32))) { - err = -EFAULT; - goto __err; - } + if (copy_from_user(&data32, (void*)arg, sizeof(data32))) + return -EFAULT; memset(&data, 0, sizeof(data)); data.id = data32.id; /* we need to copy the item index. * hope this doesn't break anything.. */ data.value.enumerated.item = data32.value.enumerated.item; + oldseg = get_fs(); + set_fs(KERNEL_DS); err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)&data); + set_fs(oldseg); if (err < 0) - goto __err; + return err; /* restore info to 32bit */ data32.id = data.id; data32.type = data.type; @@ -215,10 +205,8 @@ break; } if (copy_to_user((void*)arg, &data32, sizeof(data32))) - err = -EFAULT; - __err: - set_fs(oldseg); - return err; + return -EFAULT; + return 0; } DEFINE_ALSA_IOCTL_ENTRY(ctl_elem_info, ctl_elem_info, SNDRV_CTL_IOCTL_ELEM_INFO); @@ -281,26 +269,20 @@ struct sndrv_ctl_elem_value32 data32; int err, i; int type; - mm_segment_t oldseg = get_fs(); - - set_fs(KERNEL_DS); + mm_segment_t oldseg; /* FIXME: check the sane ioctl.. */ - if (copy_from_user(&data32, (void*)arg, sizeof(data32))) { - err = -EFAULT; - goto __err; - } + if (copy_from_user(&data32, (void*)arg, sizeof(data32))) + return -EFAULT; memset(&data, 0, sizeof(data)); data.id = data32.id; data.indirect = data32.indirect; if (data.indirect) /* FIXME: this is not correct for long arrays */ data.value.integer.value_ptr = (void*)TO_PTR(data32.value.integer.value_ptr); type = get_ctl_type(file, &data.id); - if (type < 0) { - err = type; - goto __err; - } + if (type < 0) + return type; if (! data.indirect) { switch (type) { case SNDRV_CTL_ELEM_TYPE_BOOLEAN: @@ -329,9 +311,12 @@ } } + oldseg = get_fs(); + set_fs(KERNEL_DS); err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)&data); + set_fs(oldseg); if (err < 0) - goto __err; + return err; /* restore info to 32bit */ if (! data.indirect) { switch (type) { @@ -360,10 +345,8 @@ } } if (copy_to_user((void*)arg, &data32, sizeof(data32))) - err = -EFAULT; - __err: - set_fs(oldseg); - return err; + return -EFAULT; + return 0; } DEFINE_ALSA_IOCTL_ENTRY(ctl_elem_read, ctl_elem_value, SNDRV_CTL_IOCTL_ELEM_READ); @@ -392,6 +375,7 @@ { SNDRV_CTL_IOCTL_ELEM_LOCK, NULL }, { SNDRV_CTL_IOCTL_ELEM_UNLOCK, NULL }, { SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS, NULL }, + { SNDRV_CTL_IOCTL_HWDEP_INFO, NULL }, { SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE, NULL }, { SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE, NULL }, { SNDRV_CTL_IOCTL_PCM_INFO, NULL }, @@ -427,37 +411,13 @@ static int __init snd_ioctl32_init(void) { - int err; - - err = snd_ioctl32_register(control_mappers); - if (err < 0) - return err; - err = snd_ioctl32_register(pcm_mappers); - if (err < 0) { - snd_ioctl32_done(); - return err; - } - err = snd_ioctl32_register(rawmidi_mappers); - if (err < 0) { - snd_ioctl32_done(); - return err; - } - err = snd_ioctl32_register(timer_mappers); - if (err < 0) { - snd_ioctl32_done(); - return err; - } - err = snd_ioctl32_register(hwdep_mappers); - if (err < 0) { - snd_ioctl32_done(); - return err; - } + snd_ioctl32_register(control_mappers); + snd_ioctl32_register(pcm_mappers); + snd_ioctl32_register(rawmidi_mappers); + snd_ioctl32_register(timer_mappers); + snd_ioctl32_register(hwdep_mappers); #ifdef CONFIG_SND_SEQUENCER - err = snd_ioctl32_register(seq_mappers); - if (err < 0) { - snd_ioctl32_done(); - return err; - } + snd_ioctl32_register(seq_mappers); #endif return 0; } Index: ioctl32.h =================================================================== RCS file: /cvsroot/alsa/alsa-kernel/core/ioctl32/ioctl32.h,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- ioctl32.h 6 Aug 2002 07:28:26 -0000 1.5 +++ ioctl32.h 29 Aug 2002 16:23:05 -0000 1.6 @@ -64,27 +64,23 @@ {\ struct sndrv_##type##32 data32;\ struct sndrv_##type data;\ - mm_segment_t oldseg = get_fs();\ + mm_segment_t oldseg;\ int err;\ - set_fs(KERNEL_DS);\ - if (copy_from_user(&data32, (void*)arg, sizeof(data32))) {\ - err = -EFAULT;\ - goto __err;\ - }\ + if (copy_from_user(&data32, (void*)arg, sizeof(data32)))\ + return -EFAULT;\ memset(&data, 0, sizeof(data));\ convert_from_32(type, &data, &data32);\ + oldseg = get_fs();\ + set_fs(KERNEL_DS);\ err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)&data);\ if (err < 0) \ - goto __err;\ + return err;\ if (native_ctl & (_IOC_READ << _IOC_DIRSHIFT)) {\ convert_to_32(type, &data32, &data);\ - if (copy_to_user((void*)arg, &data32, sizeof(data32))) {\ - err = -EFAULT;\ - goto __err;\ - }\ + if (copy_to_user((void*)arg, &data32, sizeof(data32)))\ + return -EFAULT;\ }\ - __err: set_fs(oldseg);\ - return err;\ + return 0;\ } #define DEFINE_ALSA_IOCTL_ENTRY(name,type,native_ctl) \ Index: pcm32.c =================================================================== RCS file: /cvsroot/alsa/alsa-kernel/core/ioctl32/pcm32.c,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- pcm32.c 12 Aug 2002 08:43:45 -0000 1.6 +++ pcm32.c 29 Aug 2002 16:23:05 -0000 1.7 @@ -189,30 +189,26 @@ { struct sndrv_xferi32 data32; struct sndrv_xferi data; - mm_segment_t oldseg = get_fs(); + mm_segment_t oldseg; int err; - set_fs(KERNEL_DS); - if (copy_from_user(&data32, (void*)arg, sizeof(data32))) { - err = -EFAULT; - goto __err; - } + if (copy_from_user(&data32, (void*)arg, sizeof(data32))) + return -EFAULT; memset(&data, 0, sizeof(data)); data.result = data32.result; data.buf = A(data32.buf); data.frames = data32.frames; + oldseg = get_fs(); + set_fs(KERNEL_DS); err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)&data); + set_fs(oldseg); if (err < 0) - goto __err; + return err; /* copy the result */ data32.result = data.result; - if (copy_to_user((void*)arg, &data32, sizeof(data32))) { - err = -EFAULT; - goto __err; - } - __err: - set_fs(oldseg); - return err; + if (copy_to_user((void*)arg, &data32, sizeof(data32))) + return -EFAULT; + return 0; } @@ -237,9 +233,7 @@ void *bufs[128]; int err = 0, ch, i; u32 *bufptr; - mm_segment_t oldseg = get_fs(); - - set_fs(KERNEL_DS); + mm_segment_t oldseg; /* FIXME: need to check whether fop->ioctl is sane */ @@ -250,41 +244,31 @@ /* check validty of the command */ switch (native_ctl) { case SNDRV_PCM_IOCTL_WRITEN_FRAMES: - if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) { - err = -EINVAL; - goto __err; - } - if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) { - err = -EBADFD; - goto __err; - } + if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) + return -EINVAL; + if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) + return -EBADFD; break; case SNDRV_PCM_IOCTL_READN_FRAMES: - if (substream->stream != SNDRV_PCM_STREAM_CAPTURE) { - err = -EINVAL; - goto __err; - } + if (substream->stream != SNDRV_PCM_STREAM_CAPTURE) + return -EINVAL; break; } - if ((ch = substream->runtime->channels) > 128) { - err = -EINVAL; - goto __err; - } - if (get_user(data32.frames, &srcptr->frames)) { - err = -EFAULT; - goto __err; - } + if ((ch = substream->runtime->channels) > 128) + return -EINVAL; + if (get_user(data32.frames, &srcptr->frames)) + return -EFAULT; __get_user(data32.bufs, &srcptr->bufs); bufptr = (u32*)TO_PTR(data32.bufs); for (i = 0; i < ch; i++) { u32 ptr; - if (get_user(ptr, bufptr)) { - err = -EFAULT; - goto __err; - } + if (get_user(ptr, bufptr)) + return -EFAULT; bufs[ch] = (void*)TO_PTR(ptr); bufptr++; } + oldseg = get_fs(); + set_fs(KERNEL_DS); switch (native_ctl) { case SNDRV_PCM_IOCTL_WRITEN_FRAMES: err = snd_pcm_lib_writev(substream, bufs, data32.frames); @@ -293,14 +277,12 @@ err = snd_pcm_lib_readv(substream, bufs, data32.frames); break; } - + set_fs(oldseg); if (err < 0) - goto __err; + return err; if (put_user(err, &srcptr->result)) - err = -EFAULT; - __err: - set_fs(oldseg); - return err < 0 ? err : 0; + return -EFAULT; + return 0; } @@ -363,24 +345,22 @@ { struct sndrv_pcm_hw_params_old32 data32; struct sndrv_pcm_hw_params data; - mm_segment_t oldseg = get_fs(); + mm_segment_t oldseg; int err; - set_fs(KERNEL_DS); - if (copy_from_user(&data32, (void*)arg, sizeof(data32))) { - err = -EFAULT; - goto __err; - } + + if (copy_from_user(&data32, (void*)arg, sizeof(data32))) + return -EFAULT; snd_pcm_hw_convert_from_old_params(&data, &data32); + oldseg = get_fs(); + set_fs(KERNEL_DS); err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)&data); + set_fs(oldseg); if (err < 0) - goto __err; + return err; snd_pcm_hw_convert_to_old_params(&data32, &data); - if (copy_to_user((void*)arg, &data32, sizeof(data32))) { - err = -EFAULT; - goto __err; - } - __err: set_fs(oldseg); - return err; + if (copy_to_user((void*)arg, &data32, sizeof(data32))) + return -EFAULT; + return 0; } @@ -450,10 +430,6 @@ { SNDRV_PCM_IOCTL_READN_FRAMES32, AP(pcm_readn) }, { SNDRV_PCM_IOCTL_LINK, NULL }, { SNDRV_PCM_IOCTL_UNLINK, NULL }, - - { SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE, NULL }, - { SNDRV_CTL_IOCTL_PCM_INFO, NULL }, - { SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE, NULL }, { 0 }, }; ------------------------------------------------------- This sf.net email is sponsored by:ThinkGeek Welcome to geek heaven. http://thinkgeek.com/sf _______________________________________________ Alsa-cvslog mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/alsa-cvslog