Merge tag 'apparmor-pr-2018-08-23' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / fs / fcntl.c
index 12273b6..4137d96 100644 (file)
@@ -116,7 +116,7 @@ int f_setown(struct file *filp, unsigned long arg, int force)
        struct pid *pid = NULL;
        int who = arg, ret = 0;
 
-       type = PIDTYPE_PID;
+       type = PIDTYPE_TGID;
        if (who < 0) {
                /* avoid overflow below */
                if (who == INT_MIN)
@@ -143,7 +143,7 @@ EXPORT_SYMBOL(f_setown);
 
 void f_delown(struct file *filp)
 {
-       f_modown(filp, NULL, PIDTYPE_PID, 1);
+       f_modown(filp, NULL, PIDTYPE_TGID, 1);
 }
 
 pid_t f_getown(struct file *filp)
@@ -171,11 +171,11 @@ static int f_setown_ex(struct file *filp, unsigned long arg)
 
        switch (owner.type) {
        case F_OWNER_TID:
-               type = PIDTYPE_MAX;
+               type = PIDTYPE_PID;
                break;
 
        case F_OWNER_PID:
-               type = PIDTYPE_PID;
+               type = PIDTYPE_TGID;
                break;
 
        case F_OWNER_PGRP:
@@ -206,11 +206,11 @@ static int f_getown_ex(struct file *filp, unsigned long arg)
        read_lock(&filp->f_owner.lock);
        owner.pid = pid_vnr(filp->f_owner.pid);
        switch (filp->f_owner.pid_type) {
-       case PIDTYPE_MAX:
+       case PIDTYPE_PID:
                owner.type = F_OWNER_TID;
                break;
 
-       case PIDTYPE_PID:
+       case PIDTYPE_TGID:
                owner.type = F_OWNER_PID;
                break;
 
@@ -723,7 +723,7 @@ static inline int sigio_perm(struct task_struct *p,
 
 static void send_sigio_to_task(struct task_struct *p,
                               struct fown_struct *fown,
-                              int fd, int reason, int group)
+                              int fd, int reason, enum pid_type type)
 {
        /*
         * F_SETSIG can change ->signum lockless in parallel, make
@@ -767,11 +767,11 @@ static void send_sigio_to_task(struct task_struct *p,
                        else
                                si.si_band = mangle_poll(band_table[reason - POLL_IN]);
                        si.si_fd    = fd;
-                       if (!do_send_sig_info(signum, &si, p, group))
+                       if (!do_send_sig_info(signum, &si, p, type))
                                break;
                /* fall-through: fall back on the old plain SIGIO signal */
                case 0:
-                       do_send_sig_info(SIGIO, SEND_SIG_PRIV, p, group);
+                       do_send_sig_info(SIGIO, SEND_SIG_PRIV, p, type);
        }
 }
 
@@ -780,34 +780,36 @@ void send_sigio(struct fown_struct *fown, int fd, int band)
        struct task_struct *p;
        enum pid_type type;
        struct pid *pid;
-       int group = 1;
        
        read_lock(&fown->lock);
 
        type = fown->pid_type;
-       if (type == PIDTYPE_MAX) {
-               group = 0;
-               type = PIDTYPE_PID;
-       }
-
        pid = fown->pid;
        if (!pid)
                goto out_unlock_fown;
-       
-       read_lock(&tasklist_lock);
-       do_each_pid_task(pid, type, p) {
-               send_sigio_to_task(p, fown, fd, band, group);
-       } while_each_pid_task(pid, type, p);
-       read_unlock(&tasklist_lock);
+
+       if (type <= PIDTYPE_TGID) {
+               rcu_read_lock();
+               p = pid_task(pid, PIDTYPE_PID);
+               if (p)
+                       send_sigio_to_task(p, fown, fd, band, type);
+               rcu_read_unlock();
+       } else {
+               read_lock(&tasklist_lock);
+               do_each_pid_task(pid, type, p) {
+                       send_sigio_to_task(p, fown, fd, band, type);
+               } while_each_pid_task(pid, type, p);
+               read_unlock(&tasklist_lock);
+       }
  out_unlock_fown:
        read_unlock(&fown->lock);
 }
 
 static void send_sigurg_to_task(struct task_struct *p,
-                               struct fown_struct *fown, int group)
+                               struct fown_struct *fown, enum pid_type type)
 {
        if (sigio_perm(p, fown, SIGURG))
-               do_send_sig_info(SIGURG, SEND_SIG_PRIV, p, group);
+               do_send_sig_info(SIGURG, SEND_SIG_PRIV, p, type);
 }
 
 int send_sigurg(struct fown_struct *fown)
@@ -815,28 +817,30 @@ int send_sigurg(struct fown_struct *fown)
        struct task_struct *p;
        enum pid_type type;
        struct pid *pid;
-       int group = 1;
        int ret = 0;
        
        read_lock(&fown->lock);
 
        type = fown->pid_type;
-       if (type == PIDTYPE_MAX) {
-               group = 0;
-               type = PIDTYPE_PID;
-       }
-
        pid = fown->pid;
        if (!pid)
                goto out_unlock_fown;
 
        ret = 1;
-       
-       read_lock(&tasklist_lock);
-       do_each_pid_task(pid, type, p) {
-               send_sigurg_to_task(p, fown, group);
-       } while_each_pid_task(pid, type, p);
-       read_unlock(&tasklist_lock);
+
+       if (type <= PIDTYPE_TGID) {
+               rcu_read_lock();
+               p = pid_task(pid, PIDTYPE_PID);
+               if (p)
+                       send_sigurg_to_task(p, fown, type);
+               rcu_read_unlock();
+       } else {
+               read_lock(&tasklist_lock);
+               do_each_pid_task(pid, type, p) {
+                       send_sigurg_to_task(p, fown, type);
+               } while_each_pid_task(pid, type, p);
+               read_unlock(&tasklist_lock);
+       }
  out_unlock_fown:
        read_unlock(&fown->lock);
        return ret;