summaryrefslogtreecommitdiffstats
path: root/fs/fcntl.c
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2017-07-16 23:05:57 -0400
committerEric W. Biederman <ebiederm@xmission.com>2018-07-21 11:43:12 -0400
commit019191342fecce4a461978a7191a43f313e19e86 (patch)
treeb256a747d10ad9b2b674a5466f366b5109cc6509 /fs/fcntl.c
parent6883f81aac6f44e7df70a6af189b3689ff52cbfb (diff)
signal: Use PIDTYPE_TGID to clearly store where file signals will be sent
When f_setown is called a pid and a pid type are stored. Replace the use of PIDTYPE_PID with PIDTYPE_TGID as PIDTYPE_TGID goes to the entire thread group. Replace the use of PIDTYPE_MAX with PIDTYPE_PID as PIDTYPE_PID now is only for a thread. Update the users of __f_setown to use PIDTYPE_TGID instead of PIDTYPE_PID. For now the code continues to capture task_pid (when task_tgid would really be appropriate), and iterate on PIDTYPE_PID (even when type == PIDTYPE_TGID) out of an abundance of caution to preserve existing behavior. Oleg Nesterov suggested using the test to ensure we use PIDTYPE_PID for tgid lookup also be used to avoid taking the tasklist lock. Suggested-by: Oleg Nesterov <oleg@redhat.com> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Diffstat (limited to 'fs/fcntl.c')
-rw-r--r--fs/fcntl.c54
1 files changed, 32 insertions, 22 deletions
diff --git a/fs/fcntl.c b/fs/fcntl.c
index 12273b6ea56d..1523588fd759 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -116,7 +116,7 @@ int f_setown(struct file *filp, unsigned long arg, int force)
116 struct pid *pid = NULL; 116 struct pid *pid = NULL;
117 int who = arg, ret = 0; 117 int who = arg, ret = 0;
118 118
119 type = PIDTYPE_PID; 119 type = PIDTYPE_TGID;
120 if (who < 0) { 120 if (who < 0) {
121 /* avoid overflow below */ 121 /* avoid overflow below */
122 if (who == INT_MIN) 122 if (who == INT_MIN)
@@ -143,7 +143,7 @@ EXPORT_SYMBOL(f_setown);
143 143
144void f_delown(struct file *filp) 144void f_delown(struct file *filp)
145{ 145{
146 f_modown(filp, NULL, PIDTYPE_PID, 1); 146 f_modown(filp, NULL, PIDTYPE_TGID, 1);
147} 147}
148 148
149pid_t f_getown(struct file *filp) 149pid_t f_getown(struct file *filp)
@@ -171,11 +171,11 @@ static int f_setown_ex(struct file *filp, unsigned long arg)
171 171
172 switch (owner.type) { 172 switch (owner.type) {
173 case F_OWNER_TID: 173 case F_OWNER_TID:
174 type = PIDTYPE_MAX; 174 type = PIDTYPE_PID;
175 break; 175 break;
176 176
177 case F_OWNER_PID: 177 case F_OWNER_PID:
178 type = PIDTYPE_PID; 178 type = PIDTYPE_TGID;
179 break; 179 break;
180 180
181 case F_OWNER_PGRP: 181 case F_OWNER_PGRP:
@@ -206,11 +206,11 @@ static int f_getown_ex(struct file *filp, unsigned long arg)
206 read_lock(&filp->f_owner.lock); 206 read_lock(&filp->f_owner.lock);
207 owner.pid = pid_vnr(filp->f_owner.pid); 207 owner.pid = pid_vnr(filp->f_owner.pid);
208 switch (filp->f_owner.pid_type) { 208 switch (filp->f_owner.pid_type) {
209 case PIDTYPE_MAX: 209 case PIDTYPE_PID:
210 owner.type = F_OWNER_TID; 210 owner.type = F_OWNER_TID;
211 break; 211 break;
212 212
213 case PIDTYPE_PID: 213 case PIDTYPE_TGID:
214 owner.type = F_OWNER_PID; 214 owner.type = F_OWNER_PID;
215 break; 215 break;
216 216
@@ -785,20 +785,25 @@ void send_sigio(struct fown_struct *fown, int fd, int band)
785 read_lock(&fown->lock); 785 read_lock(&fown->lock);
786 786
787 type = fown->pid_type; 787 type = fown->pid_type;
788 if (type == PIDTYPE_MAX) { 788 if (type == PIDTYPE_PID)
789 group = 0; 789 group = 0;
790 type = PIDTYPE_PID;
791 }
792 790
793 pid = fown->pid; 791 pid = fown->pid;
794 if (!pid) 792 if (!pid)
795 goto out_unlock_fown; 793 goto out_unlock_fown;
796 794
797 read_lock(&tasklist_lock); 795 if (type <= PIDTYPE_TGID) {
798 do_each_pid_task(pid, type, p) { 796 rcu_read_lock();
797 p = pid_task(pid, PIDTYPE_PID);
799 send_sigio_to_task(p, fown, fd, band, group); 798 send_sigio_to_task(p, fown, fd, band, group);
800 } while_each_pid_task(pid, type, p); 799 rcu_read_unlock();
801 read_unlock(&tasklist_lock); 800 } else {
801 read_lock(&tasklist_lock);
802 do_each_pid_task(pid, type, p) {
803 send_sigio_to_task(p, fown, fd, band, group);
804 } while_each_pid_task(pid, type, p);
805 read_unlock(&tasklist_lock);
806 }
802 out_unlock_fown: 807 out_unlock_fown:
803 read_unlock(&fown->lock); 808 read_unlock(&fown->lock);
804} 809}
@@ -821,22 +826,27 @@ int send_sigurg(struct fown_struct *fown)
821 read_lock(&fown->lock); 826 read_lock(&fown->lock);
822 827
823 type = fown->pid_type; 828 type = fown->pid_type;
824 if (type == PIDTYPE_MAX) { 829 if (type == PIDTYPE_PID)
825 group = 0; 830 group = 0;
826 type = PIDTYPE_PID;
827 }
828 831
829 pid = fown->pid; 832 pid = fown->pid;
830 if (!pid) 833 if (!pid)
831 goto out_unlock_fown; 834 goto out_unlock_fown;
832 835
833 ret = 1; 836 ret = 1;
834 837
835 read_lock(&tasklist_lock); 838 if (type <= PIDTYPE_TGID) {
836 do_each_pid_task(pid, type, p) { 839 rcu_read_lock();
840 p = pid_task(pid, PIDTYPE_PID);
837 send_sigurg_to_task(p, fown, group); 841 send_sigurg_to_task(p, fown, group);
838 } while_each_pid_task(pid, type, p); 842 rcu_read_unlock();
839 read_unlock(&tasklist_lock); 843 } else {
844 read_lock(&tasklist_lock);
845 do_each_pid_task(pid, type, p) {
846 send_sigurg_to_task(p, fown, group);
847 } while_each_pid_task(pid, type, p);
848 read_unlock(&tasklist_lock);
849 }
840 out_unlock_fown: 850 out_unlock_fown:
841 read_unlock(&fown->lock); 851 read_unlock(&fown->lock);
842 return ret; 852 return ret;