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