aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging
diff options
context:
space:
mode:
authorDan Carpenter <error27@gmail.com>2010-10-19 01:56:24 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-11-09 16:30:48 -0500
commit3b97eed201376db6c4487fc846022eb4ffa7e1f9 (patch)
treeaaa0ad36af41e9a25562a8e08793265a9c304390 /drivers/staging
parentea07a9f2557b8ea99a0cdd778a5d94a7495bb049 (diff)
Staging: sst: dereferencing user pointers
This code dereferences user supplied pointers directly instead of doing a copy_from_user(). Some kernel configs put user and kernel memory in different address spaces so this code isn't portable. Also the user memory could be swapped out or in this case the pointer could just be NULL leading to an oops. Another thing is that it makes permission tests like this sort of meaningless. if (minor == STREAM_MODULE && rec_mute->stream_id == 0) { retval = -EPERM; break; } The user could set stream_id to 1 for the test and then change it later. Signed-off-by: Dan Carpenter <error27@gmail.com> Acked-by: Vinod Koul <vinod.koul@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/intel_sst/intel_sst_app_interface.c65
1 files changed, 29 insertions, 36 deletions
diff --git a/drivers/staging/intel_sst/intel_sst_app_interface.c b/drivers/staging/intel_sst/intel_sst_app_interface.c
index 463e5cba8307..a0d13ee190e5 100644
--- a/drivers/staging/intel_sst/intel_sst_app_interface.c
+++ b/drivers/staging/intel_sst/intel_sst_app_interface.c
@@ -885,41 +885,39 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg)
885 break; 885 break;
886 } 886 }
887 case _IOC_NR(SNDRV_SST_SET_VOL): { 887 case _IOC_NR(SNDRV_SST_SET_VOL): {
888 struct snd_sst_vol *set_vol; 888 struct snd_sst_vol set_vol;
889 struct snd_sst_vol *rec_vol = (struct snd_sst_vol *)arg; 889
890 if (copy_from_user(&set_vol, (void __user *)arg,
891 sizeof(set_vol))) {
892 pr_debug("sst: copy failed\n");
893 retval = -EFAULT;
894 break;
895 }
890 pr_debug("sst: SET_VOLUME recieved for %d!\n", 896 pr_debug("sst: SET_VOLUME recieved for %d!\n",
891 rec_vol->stream_id); 897 set_vol.stream_id);
892 if (minor == STREAM_MODULE && rec_vol->stream_id == 0) { 898 if (minor == STREAM_MODULE && set_vol.stream_id == 0) {
893 pr_debug("sst: invalid operation!\n"); 899 pr_debug("sst: invalid operation!\n");
894 retval = -EPERM; 900 retval = -EPERM;
895 break; 901 break;
896 } 902 }
897 set_vol = kzalloc(sizeof(*set_vol), GFP_ATOMIC); 903 retval = sst_set_vol(&set_vol);
898 if (!set_vol) {
899 pr_debug("sst: mem allocation failed\n");
900 retval = -ENOMEM;
901 break;
902 }
903 if (copy_from_user(set_vol, rec_vol, sizeof(*set_vol))) {
904 pr_debug("sst: copy failed\n");
905 retval = -EFAULT;
906 break;
907 }
908 retval = sst_set_vol(set_vol);
909 kfree(set_vol);
910 break; 904 break;
911 } 905 }
912 case _IOC_NR(SNDRV_SST_GET_VOL): { 906 case _IOC_NR(SNDRV_SST_GET_VOL): {
913 struct snd_sst_vol *rec_vol = (struct snd_sst_vol *)arg;
914 struct snd_sst_vol get_vol; 907 struct snd_sst_vol get_vol;
908
909 if (copy_from_user(&get_vol, (void __user *)arg,
910 sizeof(get_vol))) {
911 retval = -EFAULT;
912 break;
913 }
915 pr_debug("sst: IOCTL_GET_VOLUME recieved for stream = %d!\n", 914 pr_debug("sst: IOCTL_GET_VOLUME recieved for stream = %d!\n",
916 rec_vol->stream_id); 915 get_vol.stream_id);
917 if (minor == STREAM_MODULE && rec_vol->stream_id == 0) { 916 if (minor == STREAM_MODULE && get_vol.stream_id == 0) {
918 pr_debug("sst: invalid operation!\n"); 917 pr_debug("sst: invalid operation!\n");
919 retval = -EPERM; 918 retval = -EPERM;
920 break; 919 break;
921 } 920 }
922 get_vol.stream_id = rec_vol->stream_id;
923 retval = sst_get_vol(&get_vol); 921 retval = sst_get_vol(&get_vol);
924 if (retval) { 922 if (retval) {
925 retval = -EIO; 923 retval = -EIO;
@@ -938,25 +936,20 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg)
938 } 936 }
939 937
940 case _IOC_NR(SNDRV_SST_MUTE): { 938 case _IOC_NR(SNDRV_SST_MUTE): {
941 struct snd_sst_mute *set_mute; 939 struct snd_sst_mute set_mute;
942 struct snd_sst_vol *rec_mute = (struct snd_sst_vol *)arg; 940
943 pr_debug("sst: SNDRV_SST_SET_VOLUME recieved for %d!\n", 941 if (copy_from_user(&set_mute, (void __user *)arg,
944 rec_mute->stream_id); 942 sizeof(set_mute))) {
945 if (minor == STREAM_MODULE && rec_mute->stream_id == 0) { 943 retval = -EFAULT;
946 retval = -EPERM;
947 break;
948 }
949 set_mute = kzalloc(sizeof(*set_mute), GFP_ATOMIC);
950 if (!set_mute) {
951 retval = -ENOMEM;
952 break; 944 break;
953 } 945 }
954 if (copy_from_user(set_mute, rec_mute, sizeof(*set_mute))) { 946 pr_debug("sst: SNDRV_SST_SET_VOLUME recieved for %d!\n",
955 retval = -EFAULT; 947 set_mute.stream_id);
948 if (minor == STREAM_MODULE && set_mute.stream_id == 0) {
949 retval = -EPERM;
956 break; 950 break;
957 } 951 }
958 retval = sst_set_mute(set_mute); 952 retval = sst_set_mute(&set_mute);
959 kfree(set_mute);
960 break; 953 break;
961 } 954 }
962 case _IOC_NR(SNDRV_SST_STREAM_GET_PARAMS): { 955 case _IOC_NR(SNDRV_SST_STREAM_GET_PARAMS): {