From: Oleg Nesterov <oleg@redhat.com>
To: Kirill Tkhai <ktkhai@virtuozzo.com>
Cc: linux-kernel@vger.kernel.org, gregkh@linuxfoundation.org,
jslaby@suse.com, viro@zeniv.linux.org.uk, keescook@chromium.org,
serge@hallyn.com, james.l.morris@oracle.com, luto@kernel.org,
john.johansen@canonical.com, mingo@kernel.org,
akpm@linux-foundation.org, mhocko@suse.com, peterz@infradead.org
Subject: Re: [PATCH 3/4] tty: Iterate only thread group leaders in __do_SAK()
Date: Fri, 12 Jan 2018 17:42:34 +0100 [thread overview]
Message-ID: <20180112164234.GA21532@redhat.com> (raw)
In-Reply-To: <50c23f46-f4ad-b6c8-b7bc-0a8d8449c62f@virtuozzo.com>
On 01/12, Kirill Tkhai wrote:
>
> How about this patch instead of the whole set? I left thread iterations
> and added sighand locking for visability.
Kirill, I didn't really read this series so I don't quite understand what
are you actually trying to do...
__do_SAK() is racy anyway, a process can open tty right after it was checked,
and I do not understand why should we care about races with execve.
IOW, I do not understand why we can't simply use rcu_read_lock() after
do_each_pid_task/while_each_pid_task. Yes we can miss the new process/thread,
but if the creator process had this tty opened it should be killed by us so
fork/clone can't succeed: both do_fork() and send_sig() take the same lock
and do_fork() checks signal_pending() under ->siglock.
No?
And whatever we do, I think you are right and for_each_process() makes more
sense, and in the likely case all sub-threads should share the same file_struct.
So perhaps we should start with the simple cleanup? Say,
for_each_process(p) {
if (p->signal->tty == tty) {
tty_notice(tty, "SAK: killed process %d (%s): by controlling tty\n",
task_pid_nr(p), p->comm);
goto kill;
}
files = NULL;
for_each_thread(p, t) {
if (t->files == files) /* racy but we do not care */
continue;
task_lock(t);
files = t->files;
i = iterate_fd(files, 0, this_tty, tty);
task_unlock(t);
if (i != 0) {
tty_notice(tty, "SAK: killed process %d (%s): by fd#%d\n",
task_pid_nr(p), p->comm, i - 1);
goto kill;
}
}
continue;
kill:
force_sig(SIGKILL, p);
}
(see the uncompiled/untested patch below), then make another change to avoid
tasklist_lock?
Oleg.
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -2704,7 +2704,8 @@ void __do_SAK(struct tty_struct *tty)
#ifdef TTY_SOFT_SAK
tty_hangup(tty);
#else
- struct task_struct *g, *p;
+ struct task_struct *p, *t;
+ struct files_struct files;
struct pid *session;
int i;
@@ -2725,22 +2726,34 @@ void __do_SAK(struct tty_struct *tty)
} while_each_pid_task(session, PIDTYPE_SID, p);
/* Now kill any processes that happen to have the tty open */
- do_each_thread(g, p) {
+ for_each_process(p) {
if (p->signal->tty == tty) {
tty_notice(tty, "SAK: killed process %d (%s): by controlling tty\n",
task_pid_nr(p), p->comm);
- send_sig(SIGKILL, p, 1);
- continue;
+ goto kill;
}
- task_lock(p);
- i = iterate_fd(p->files, 0, this_tty, tty);
- if (i != 0) {
- tty_notice(tty, "SAK: killed process %d (%s): by fd#%d\n",
- task_pid_nr(p), p->comm, i - 1);
- force_sig(SIGKILL, p);
+
+ files = NULL;
+ for_each_thread(p, t) {
+ if (t->files == files) /* racy but we do not care */
+ continue;
+
+ task_lock(t);
+ files = t->files;
+ i = iterate_fd(files, 0, this_tty, tty);
+ task_unlock(t);
+
+ if (i != 0) {
+ tty_notice(tty, "SAK: killed process %d (%s): by fd#%d\n",
+ task_pid_nr(p), p->comm, i - 1);
+ goto kill;
+ }
}
- task_unlock(p);
- } while_each_thread(g, p);
+
+ continue;
+kill:
+ force_sig(SIGKILL, p);
+ }
read_unlock(&tasklist_lock);
#endif
}
next prev parent reply other threads:[~2018-01-12 16:42 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-01-11 15:49 [PATCH 0/4] fs, tty: Make __do_SAK() less greedy in regard to tasklist_lock Kirill Tkhai
2018-01-11 15:50 ` [PATCH 1/4] exec: Pass unshared files_struct to load_binary() Kirill Tkhai
2018-01-11 15:50 ` [PATCH 2/4] exec: Assign unshared files after there is no way back Kirill Tkhai
2018-01-11 15:50 ` [PATCH 3/4] tty: Iterate only thread group leaders in __do_SAK() Kirill Tkhai
2018-01-11 18:34 ` Oleg Nesterov
2018-01-12 8:42 ` Kirill Tkhai
2018-01-12 10:05 ` Kirill Tkhai
2018-01-12 16:42 ` Oleg Nesterov [this message]
2018-01-15 9:32 ` Kirill Tkhai
2018-01-15 20:51 ` Oleg Nesterov
2018-01-16 11:33 ` Kirill Tkhai
2018-01-16 21:13 ` Oleg Nesterov
2018-01-17 12:47 ` Kirill Tkhai
2018-01-11 15:50 ` [PATCH 4/4] tty: Use RCU read lock to iterate tasks " Kirill Tkhai
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180112164234.GA21532@redhat.com \
--to=oleg@redhat.com \
--cc=akpm@linux-foundation.org \
--cc=gregkh@linuxfoundation.org \
--cc=james.l.morris@oracle.com \
--cc=john.johansen@canonical.com \
--cc=jslaby@suse.com \
--cc=keescook@chromium.org \
--cc=ktkhai@virtuozzo.com \
--cc=linux-kernel@vger.kernel.org \
--cc=luto@kernel.org \
--cc=mhocko@suse.com \
--cc=mingo@kernel.org \
--cc=peterz@infradead.org \
--cc=serge@hallyn.com \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.