]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ncpfs: Use set_current_blocked()
authorMatt Fleming <matt.fleming@intel.com>
Fri, 19 Aug 2011 16:46:59 +0000 (17:46 +0100)
committerOleg Nesterov <oleg@redhat.com>
Fri, 26 Aug 2011 17:15:49 +0000 (19:15 +0200)
As described in e6fa16ab ("signal: sigprocmask() should do
retarget_shared_pending()") the modification of current->blocked is
incorrect as we need to check whether the signal we're about to block
is pending in the shared queue.

Also, there's no need to hold sighand->siglock while reading
sighand->action[] because the lock is dropped across the call to
do_ncp_rpc_call() during which time another thread could modify
->action[].

Note: the current code does the strange things which nobody can
explain, especially the PF_EXITING/SIGKILL thing. The patch does
not try to change this.

Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Petr Vandrovec <petr@vandrovec.name>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
fs/ncpfs/sock.c

index 3a1587222c8a7a3eeea9b2990a3d734d313e767f..850768a4803f10fbb135f6c8aaf63e1447a8afa5 100644 (file)
@@ -749,10 +749,9 @@ static int ncp_do_request(struct ncp_server *server, int size,
                return -EIO;
        }
        {
-               sigset_t old_set;
-               unsigned long mask, flags;
+               sigset_t old_set, blocked;
+               unsigned long mask;
 
-               spin_lock_irqsave(&current->sighand->siglock, flags);
                old_set = current->blocked;
                if (current->flags & PF_EXITING)
                        mask = 0;
@@ -769,16 +768,12 @@ static int ncp_do_request(struct ncp_server *server, int size,
                        if (current->sighand->action[SIGQUIT - 1].sa.sa_handler == SIG_DFL)
                                mask |= sigmask(SIGQUIT);
                }
-               siginitsetinv(&current->blocked, mask);
-               recalc_sigpending();
-               spin_unlock_irqrestore(&current->sighand->siglock, flags);
+               siginitsetinv(&blocked, mask);
+               set_current_blocked(&blocked);
                
                result = do_ncp_rpc_call(server, size, reply, max_reply_size);
 
-               spin_lock_irqsave(&current->sighand->siglock, flags);
-               current->blocked = old_set;
-               recalc_sigpending();
-               spin_unlock_irqrestore(&current->sighand->siglock, flags);
+               set_current_blocked(&old_set);
        }
 
        DDPRINTK("do_ncp_rpc_call returned %d\n", result);