@@ -482,7 +482,8 @@ enum binder_deferred_state {
482
482
* @tsk task_struct for group_leader of process
483
483
* (invariant after initialized)
484
484
* @files files_struct for process
485
- * (invariant after initialized)
485
+ * (protected by @files_lock)
486
+ * @files_lock mutex to protect @files
486
487
* @deferred_work_node: element for binder_deferred_list
487
488
* (protected by binder_deferred_lock)
488
489
* @deferred_work: bitmap of deferred work to perform
@@ -530,6 +531,7 @@ struct binder_proc {
530
531
int pid ;
531
532
struct task_struct * tsk ;
532
533
struct files_struct * files ;
534
+ struct mutex files_lock ;
533
535
struct hlist_node deferred_work_node ;
534
536
int deferred_work ;
535
537
bool is_dead ;
@@ -877,20 +879,26 @@ static void binder_inc_node_tmpref_ilocked(struct binder_node *node);
877
879
878
880
static int task_get_unused_fd_flags (struct binder_proc * proc , int flags )
879
881
{
880
- struct files_struct * files = proc -> files ;
881
882
unsigned long rlim_cur ;
882
883
unsigned long irqs ;
884
+ int ret ;
883
885
884
- if (files == NULL )
885
- return - ESRCH ;
886
-
887
- if (!lock_task_sighand (proc -> tsk , & irqs ))
888
- return - EMFILE ;
889
-
886
+ mutex_lock (& proc -> files_lock );
887
+ if (proc -> files == NULL ) {
888
+ ret = - ESRCH ;
889
+ goto err ;
890
+ }
891
+ if (!lock_task_sighand (proc -> tsk , & irqs )) {
892
+ ret = - EMFILE ;
893
+ goto err ;
894
+ }
890
895
rlim_cur = task_rlimit (proc -> tsk , RLIMIT_NOFILE );
891
896
unlock_task_sighand (proc -> tsk , & irqs );
892
897
893
- return __alloc_fd (files , 0 , rlim_cur , flags );
898
+ ret = __alloc_fd (proc -> files , 0 , rlim_cur , flags );
899
+ err :
900
+ mutex_unlock (& proc -> files_lock );
901
+ return ret ;
894
902
}
895
903
896
904
/*
@@ -899,8 +907,10 @@ static int task_get_unused_fd_flags(struct binder_proc *proc, int flags)
899
907
static void task_fd_install (
900
908
struct binder_proc * proc , unsigned int fd , struct file * file )
901
909
{
910
+ mutex_lock (& proc -> files_lock );
902
911
if (proc -> files )
903
912
__fd_install (proc -> files , fd , file );
913
+ mutex_unlock (& proc -> files_lock );
904
914
}
905
915
906
916
/*
@@ -910,17 +920,20 @@ static long task_close_fd(struct binder_proc *proc, unsigned int fd)
910
920
{
911
921
int retval ;
912
922
913
- if (proc -> files == NULL )
914
- return - ESRCH ;
915
-
923
+ mutex_lock (& proc -> files_lock );
924
+ if (proc -> files == NULL ) {
925
+ retval = - ESRCH ;
926
+ goto err ;
927
+ }
916
928
retval = __close_fd (proc -> files , fd );
917
929
/* can't restart close syscall because file table entry was cleared */
918
930
if (unlikely (retval == - ERESTARTSYS ||
919
931
retval == - ERESTARTNOINTR ||
920
932
retval == - ERESTARTNOHAND ||
921
933
retval == - ERESTART_RESTARTBLOCK ))
922
934
retval = - EINTR ;
923
-
935
+ err :
936
+ mutex_unlock (& proc -> files_lock );
924
937
return retval ;
925
938
}
926
939
@@ -4627,7 +4640,9 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
4627
4640
ret = binder_alloc_mmap_handler (& proc -> alloc , vma );
4628
4641
if (ret )
4629
4642
return ret ;
4643
+ mutex_lock (& proc -> files_lock );
4630
4644
proc -> files = get_files_struct (current );
4645
+ mutex_unlock (& proc -> files_lock );
4631
4646
return 0 ;
4632
4647
4633
4648
err_bad_arg :
@@ -4651,6 +4666,7 @@ static int binder_open(struct inode *nodp, struct file *filp)
4651
4666
spin_lock_init (& proc -> outer_lock );
4652
4667
get_task_struct (current -> group_leader );
4653
4668
proc -> tsk = current -> group_leader ;
4669
+ mutex_init (& proc -> files_lock );
4654
4670
INIT_LIST_HEAD (& proc -> todo );
4655
4671
proc -> default_priority = task_nice (current );
4656
4672
binder_dev = container_of (filp -> private_data , struct binder_device ,
@@ -4903,9 +4919,11 @@ static void binder_deferred_func(struct work_struct *work)
4903
4919
4904
4920
files = NULL ;
4905
4921
if (defer & BINDER_DEFERRED_PUT_FILES ) {
4922
+ mutex_lock (& proc -> files_lock );
4906
4923
files = proc -> files ;
4907
4924
if (files )
4908
4925
proc -> files = NULL ;
4926
+ mutex_unlock (& proc -> files_lock );
4909
4927
}
4910
4928
4911
4929
if (defer & BINDER_DEFERRED_FLUSH )
0 commit comments