@@ -1025,7 +1025,7 @@ static u64 snd_compr_seqno_next(struct snd_compr_stream *stream)
10251025static int snd_compr_task_new (struct snd_compr_stream * stream , struct snd_compr_task * utask )
10261026{
10271027 struct snd_compr_task_runtime * task ;
1028- int retval ;
1028+ int retval , fd_i , fd_o ;
10291029
10301030 if (stream -> runtime -> total_tasks >= stream -> runtime -> fragments )
10311031 return - EBUSY ;
@@ -1039,19 +1039,27 @@ static int snd_compr_task_new(struct snd_compr_stream *stream, struct snd_compr_
10391039 retval = stream -> ops -> task_create (stream , task );
10401040 if (retval < 0 )
10411041 goto cleanup ;
1042- utask -> input_fd = dma_buf_fd (task -> input , O_WRONLY |O_CLOEXEC );
1043- if (utask -> input_fd < 0 ) {
1044- retval = utask -> input_fd ;
1042+ /* similar functionality as in dma_buf_fd(), but ensure that both
1043+ file descriptors are allocated before fd_install() */
1044+ if (!task -> input || !task -> input -> file || !task -> output || !task -> output -> file ) {
1045+ retval = - EINVAL ;
10451046 goto cleanup ;
10461047 }
1047- utask -> output_fd = dma_buf_fd (task -> output , O_RDONLY |O_CLOEXEC );
1048- if (utask -> output_fd < 0 ) {
1049- retval = utask -> output_fd ;
1048+ fd_i = get_unused_fd_flags (O_WRONLY |O_CLOEXEC );
1049+ if (fd_i < 0 )
1050+ goto cleanup ;
1051+ fd_o = get_unused_fd_flags (O_RDONLY |O_CLOEXEC );
1052+ if (fd_o < 0 ) {
1053+ put_unused_fd (fd_i );
10501054 goto cleanup ;
10511055 }
10521056 /* keep dmabuf reference until freed with task free ioctl */
1053- dma_buf_get (utask -> input_fd );
1054- dma_buf_get (utask -> output_fd );
1057+ get_dma_buf (task -> input );
1058+ get_dma_buf (task -> output );
1059+ fd_install (fd_i , task -> input -> file );
1060+ fd_install (fd_o , task -> output -> file );
1061+ utask -> input_fd = fd_i ;
1062+ utask -> output_fd = fd_o ;
10551063 list_add_tail (& task -> list , & stream -> runtime -> tasks );
10561064 stream -> runtime -> total_tasks ++ ;
10571065 return 0 ;
@@ -1069,7 +1077,7 @@ static int snd_compr_task_create(struct snd_compr_stream *stream, unsigned long
10691077 return - EPERM ;
10701078 task = memdup_user ((void __user * )arg , sizeof (* task ));
10711079 if (IS_ERR (task ))
1072- return PTR_ERR (no_free_ptr ( task ) );
1080+ return PTR_ERR (task );
10731081 retval = snd_compr_task_new (stream , task );
10741082 if (retval >= 0 )
10751083 if (copy_to_user ((void __user * )arg , task , sizeof (* task )))
@@ -1130,7 +1138,7 @@ static int snd_compr_task_start_ioctl(struct snd_compr_stream *stream, unsigned
11301138 return - EPERM ;
11311139 task = memdup_user ((void __user * )arg , sizeof (* task ));
11321140 if (IS_ERR (task ))
1133- return PTR_ERR (no_free_ptr ( task ) );
1141+ return PTR_ERR (task );
11341142 retval = snd_compr_task_start (stream , task );
11351143 if (retval >= 0 )
11361144 if (copy_to_user ((void __user * )arg , task , sizeof (* task )))
@@ -1174,18 +1182,18 @@ typedef void (*snd_compr_seq_func_t)(struct snd_compr_stream *stream,
11741182static int snd_compr_task_seq (struct snd_compr_stream * stream , unsigned long arg ,
11751183 snd_compr_seq_func_t fcn )
11761184{
1177- struct snd_compr_task_runtime * task ;
1185+ struct snd_compr_task_runtime * task , * temp ;
11781186 __u64 seqno ;
11791187 int retval ;
11801188
11811189 if (stream -> runtime -> state != SNDRV_PCM_STATE_SETUP )
11821190 return - EPERM ;
1183- retval = get_user ( seqno , (__u64 __user * )arg );
1184- if (retval < 0 )
1185- return retval ;
1191+ retval = copy_from_user ( & seqno , (__u64 __user * )arg , sizeof ( seqno ) );
1192+ if (retval )
1193+ return - EFAULT ;
11861194 retval = 0 ;
11871195 if (seqno == 0 ) {
1188- list_for_each_entry_reverse (task , & stream -> runtime -> tasks , list )
1196+ list_for_each_entry_safe_reverse (task , temp , & stream -> runtime -> tasks , list )
11891197 fcn (stream , task );
11901198 } else {
11911199 task = snd_compr_find_task (stream , seqno );
@@ -1221,7 +1229,7 @@ static int snd_compr_task_status_ioctl(struct snd_compr_stream *stream, unsigned
12211229 return - EPERM ;
12221230 status = memdup_user ((void __user * )arg , sizeof (* status ));
12231231 if (IS_ERR (status ))
1224- return PTR_ERR (no_free_ptr ( status ) );
1232+ return PTR_ERR (status );
12251233 retval = snd_compr_task_status (stream , status );
12261234 if (retval >= 0 )
12271235 if (copy_to_user ((void __user * )arg , status , sizeof (* status )))
@@ -1247,6 +1255,7 @@ void snd_compr_task_finished(struct snd_compr_stream *stream,
12471255}
12481256EXPORT_SYMBOL_GPL (snd_compr_task_finished );
12491257
1258+ MODULE_IMPORT_NS ("DMA_BUF" );
12501259#endif /* CONFIG_SND_COMPRESS_ACCEL */
12511260
12521261static long snd_compr_ioctl (struct file * f , unsigned int cmd , unsigned long arg )
0 commit comments