tmux(1) allows keyboard interrupt to unlock a "locked" session

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

tmux(1) allows keyboard interrupt to unlock a "locked" session

Eldritch
>Synopsis: Locked tmux session can be escaped from by using ctrl+\
>Category: user
>Environment:
        System      : OpenBSD 6.7
        Details     : OpenBSD 6.7-current (GENERIC.MP) #1: Mon Aug  3 14:30:52 MDT 2020
                         [hidden email]:/usr/src/sys/arch/amd64/compile/GENERIC.MP

        Architecture: OpenBSD.amd64
        Machine     : amd64
>Description:
        After pressing ^\ inside a locked tmux session, tmux dumps core
        but doesn't exit, instead detaching from the terminal. After
        reattaching, the session will not be locked anymore.

        If using the default "lock-command" which is lock(1), shortly
        afterwards the screen will be flooded with lock(1)'s prompts,
        but you can enter commands in the parent shell and kill the
        lock process.

        When ran normally (even inside tmux), lock(1) ignores the
        SIGQUIT from ^\, therefore this bug only affects tmux's
        "locked" state. I tested this with an empty ~/.tmux.conf.

        Also reproduced on OpenBSD-stable 6.7 (GENERIC.MP) #5 amd64, and
        tmux 3.1b on Linux.
       
        gdb(1) backtrace of the tmux core dump (on -current):

        #0  _thread_sys_wait4 () at /tmp/-:3
        #1  0x000006a794ac582e in _libc_wait4_cancel (wpid=Variable "wpid" is not available.) at /usr/src/lib/libc/sys/w_wait4.c:27
        #2  0x000006a794b2e00d in _libc_system (command=Variable "command" is not available.) at /usr/src/lib/libc/stdlib/system.c:69
        #3  0x000006a4caac7a00 in client_dispatch_attached (imsg=0x7f7ffffd3c70) at client.c:1006
        #4  0x000006a4caac7270 in client_dispatch (imsg=0x7f7ffffd3c70, arg=0x0) at client.c:807
        #5  0x000006a4cab1dc66 in proc_event_cb (fd=6, events=2, arg=0x6a7ac809000) at proc.c:95
        #6  0x000006a75cf3f0cf in event_base_loop (base=0x6a7a516a000, flags=Variable "flags" is not available.) at /usr/src/lib/libevent/event.c:333
        #7  0x000006a4cab1e093 in proc_loop (tp=0x6a775441000, loopcb=0) at proc.c:202
        #8  0x000006a4caac6130 in client_main (base=0x6a7a516a000, argc=0, argv=0x7f7ffffd3f90, flags=402718720, feat=0) at client.c:385
        #9  0x000006a4cab3ec48 in main (argc=0, argv=0x7f7ffffd3f90) at tmux.c:502

>How-To-Repeat:
        1. Launch tmux
        2. Lock the tmux session using ctrl+b :lock
        3. Press ctrl+\
        4. Blindly run "pkill lock" to stop the flood of text
>Fix:
        The following patch seems to fix it. The server correctly shuts
        down if it receives a SIGQUIT while not locked, or after lock(1)
        exits if it was locked when the signal arrived, the latter being
        the same behavior as other terminating signals.

Index: proc.c
===================================================================
RCS file: /cvs/src/usr.bin/tmux/proc.c,v
retrieving revision 1.17
diff -u -p -r1.17 proc.c
--- proc.c 16 May 2020 16:07:55 -0000 1.17
+++ proc.c 3 Aug 2020 22:15:46 -0000
@@ -42,6 +42,7 @@ struct tmuxproc {
  struct event  ev_sigchld;
  struct event  ev_sigcont;
  struct event  ev_sigterm;
+ struct event  ev_sigquit;
  struct event  ev_sigusr1;
  struct event  ev_sigusr2;
  struct event  ev_sigwinch;
@@ -237,6 +238,8 @@ proc_set_signals(struct tmuxproc *tp, vo
  signal_add(&tp->ev_sigcont, NULL);
  signal_set(&tp->ev_sigterm, SIGTERM, proc_signal_cb, tp);
  signal_add(&tp->ev_sigterm, NULL);
+ signal_set(&tp->ev_sigquit, SIGQUIT, proc_signal_cb, tp);
+ signal_add(&tp->ev_sigquit, NULL);
  signal_set(&tp->ev_sigusr1, SIGUSR1, proc_signal_cb, tp);
  signal_add(&tp->ev_sigusr1, NULL);
  signal_set(&tp->ev_sigusr2, SIGUSR2, proc_signal_cb, tp);
Index: server.c
===================================================================
RCS file: /cvs/src/usr.bin/tmux/server.c,v
retrieving revision 1.194
diff -u -p -r1.194 server.c
--- server.c 18 Jun 2020 08:34:22 -0000 1.194
+++ server.c 3 Aug 2020 22:15:46 -0000
@@ -407,6 +407,7 @@ server_signal(int sig)
  switch (sig) {
  case SIGINT:
  case SIGTERM:
+ case SIGQUIT:
  server_exit = 1;
  server_send_exit();
  break;

Reply | Threaded
Open this post in threaded view
|

Re: tmux(1) allows keyboard interrupt to unlock a "locked" session

Nicholas Marriott-2
I made it just ignore SIGQUIT entirely, there is no reason it needs to
do anything. Please try now with proc.c r1.18.

Thanks!


On Mon, Aug 03, 2020 at 11:33:29PM +0000, Eldritch wrote:

> >Synopsis: Locked tmux session can be escaped from by using ctrl+\
> >Category: user
> >Environment:
> System      : OpenBSD 6.7
> Details     : OpenBSD 6.7-current (GENERIC.MP) #1: Mon Aug  3 14:30:52 MDT 2020
> [hidden email]:/usr/src/sys/arch/amd64/compile/GENERIC.MP
>
> Architecture: OpenBSD.amd64
> Machine     : amd64
> >Description:
> After pressing ^\ inside a locked tmux session, tmux dumps core
> but doesn't exit, instead detaching from the terminal. After
> reattaching, the session will not be locked anymore.
>
> If using the default "lock-command" which is lock(1), shortly
> afterwards the screen will be flooded with lock(1)'s prompts,
> but you can enter commands in the parent shell and kill the
> lock process.
>
> When ran normally (even inside tmux), lock(1) ignores the
> SIGQUIT from ^\, therefore this bug only affects tmux's
> "locked" state. I tested this with an empty ~/.tmux.conf.
>
> Also reproduced on OpenBSD-stable 6.7 (GENERIC.MP) #5 amd64, and
> tmux 3.1b on Linux.
>
> gdb(1) backtrace of the tmux core dump (on -current):
>
> #0  _thread_sys_wait4 () at /tmp/-:3
> #1  0x000006a794ac582e in _libc_wait4_cancel (wpid=Variable "wpid" is not available.) at /usr/src/lib/libc/sys/w_wait4.c:27
> #2  0x000006a794b2e00d in _libc_system (command=Variable "command" is not available.) at /usr/src/lib/libc/stdlib/system.c:69
> #3  0x000006a4caac7a00 in client_dispatch_attached (imsg=0x7f7ffffd3c70) at client.c:1006
> #4  0x000006a4caac7270 in client_dispatch (imsg=0x7f7ffffd3c70, arg=0x0) at client.c:807
> #5  0x000006a4cab1dc66 in proc_event_cb (fd=6, events=2, arg=0x6a7ac809000) at proc.c:95
> #6  0x000006a75cf3f0cf in event_base_loop (base=0x6a7a516a000, flags=Variable "flags" is not available.) at /usr/src/lib/libevent/event.c:333
> #7  0x000006a4cab1e093 in proc_loop (tp=0x6a775441000, loopcb=0) at proc.c:202
> #8  0x000006a4caac6130 in client_main (base=0x6a7a516a000, argc=0, argv=0x7f7ffffd3f90, flags=402718720, feat=0) at client.c:385
> #9  0x000006a4cab3ec48 in main (argc=0, argv=0x7f7ffffd3f90) at tmux.c:502
>
> >How-To-Repeat:
> 1. Launch tmux
> 2. Lock the tmux session using ctrl+b :lock
> 3. Press ctrl+\
> 4. Blindly run "pkill lock" to stop the flood of text
> >Fix:
> The following patch seems to fix it. The server correctly shuts
> down if it receives a SIGQUIT while not locked, or after lock(1)
> exits if it was locked when the signal arrived, the latter being
> the same behavior as other terminating signals.
>
> Index: proc.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/tmux/proc.c,v
> retrieving revision 1.17
> diff -u -p -r1.17 proc.c
> --- proc.c 16 May 2020 16:07:55 -0000 1.17
> +++ proc.c 3 Aug 2020 22:15:46 -0000
> @@ -42,6 +42,7 @@ struct tmuxproc {
>   struct event  ev_sigchld;
>   struct event  ev_sigcont;
>   struct event  ev_sigterm;
> + struct event  ev_sigquit;
>   struct event  ev_sigusr1;
>   struct event  ev_sigusr2;
>   struct event  ev_sigwinch;
> @@ -237,6 +238,8 @@ proc_set_signals(struct tmuxproc *tp, vo
>   signal_add(&tp->ev_sigcont, NULL);
>   signal_set(&tp->ev_sigterm, SIGTERM, proc_signal_cb, tp);
>   signal_add(&tp->ev_sigterm, NULL);
> + signal_set(&tp->ev_sigquit, SIGQUIT, proc_signal_cb, tp);
> + signal_add(&tp->ev_sigquit, NULL);
>   signal_set(&tp->ev_sigusr1, SIGUSR1, proc_signal_cb, tp);
>   signal_add(&tp->ev_sigusr1, NULL);
>   signal_set(&tp->ev_sigusr2, SIGUSR2, proc_signal_cb, tp);
> Index: server.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/tmux/server.c,v
> retrieving revision 1.194
> diff -u -p -r1.194 server.c
> --- server.c 18 Jun 2020 08:34:22 -0000 1.194
> +++ server.c 3 Aug 2020 22:15:46 -0000
> @@ -407,6 +407,7 @@ server_signal(int sig)
>   switch (sig) {
>   case SIGINT:
>   case SIGTERM:
> + case SIGQUIT:
>   server_exit = 1;
>   server_send_exit();
>   break;
>

Reply | Threaded
Open this post in threaded view
|

Re: tmux(1) allows keyboard interrupt to unlock a "locked" session

Eldritch
The new revision also fixes it, thank you for the quick response.

On Tue, Aug 04, 2020 at 09:51:24AM +0100, Nicholas Marriott wrote:

> I made it just ignore SIGQUIT entirely, there is no reason it needs to
> do anything. Please try now with proc.c r1.18.
>
> Thanks!
>
>
> On Mon, Aug 03, 2020 at 11:33:29PM +0000, Eldritch wrote:
> > >Synopsis: Locked tmux session can be escaped from by using ctrl+\
> > >Category: user
> > >Environment:
> > System      : OpenBSD 6.7
> > Details     : OpenBSD 6.7-current (GENERIC.MP) #1: Mon Aug  3 14:30:52 MDT 2020
> > [hidden email]:/usr/src/sys/arch/amd64/compile/GENERIC.MP
> >
> > Architecture: OpenBSD.amd64
> > Machine     : amd64
> > >Description:
> > After pressing ^\ inside a locked tmux session, tmux dumps core
> > but doesn't exit, instead detaching from the terminal. After
> > reattaching, the session will not be locked anymore.
> >
> > If using the default "lock-command" which is lock(1), shortly
> > afterwards the screen will be flooded with lock(1)'s prompts,
> > but you can enter commands in the parent shell and kill the
> > lock process.
> >
> > When ran normally (even inside tmux), lock(1) ignores the
> > SIGQUIT from ^\, therefore this bug only affects tmux's
> > "locked" state. I tested this with an empty ~/.tmux.conf.
> >
> > Also reproduced on OpenBSD-stable 6.7 (GENERIC.MP) #5 amd64, and
> > tmux 3.1b on Linux.
> >
> > gdb(1) backtrace of the tmux core dump (on -current):
> >
> > #0  _thread_sys_wait4 () at /tmp/-:3
> > #1  0x000006a794ac582e in _libc_wait4_cancel (wpid=Variable "wpid" is not available.) at /usr/src/lib/libc/sys/w_wait4.c:27
> > #2  0x000006a794b2e00d in _libc_system (command=Variable "command" is not available.) at /usr/src/lib/libc/stdlib/system.c:69
> > #3  0x000006a4caac7a00 in client_dispatch_attached (imsg=0x7f7ffffd3c70) at client.c:1006
> > #4  0x000006a4caac7270 in client_dispatch (imsg=0x7f7ffffd3c70, arg=0x0) at client.c:807
> > #5  0x000006a4cab1dc66 in proc_event_cb (fd=6, events=2, arg=0x6a7ac809000) at proc.c:95
> > #6  0x000006a75cf3f0cf in event_base_loop (base=0x6a7a516a000, flags=Variable "flags" is not available.) at /usr/src/lib/libevent/event.c:333
> > #7  0x000006a4cab1e093 in proc_loop (tp=0x6a775441000, loopcb=0) at proc.c:202
> > #8  0x000006a4caac6130 in client_main (base=0x6a7a516a000, argc=0, argv=0x7f7ffffd3f90, flags=402718720, feat=0) at client.c:385
> > #9  0x000006a4cab3ec48 in main (argc=0, argv=0x7f7ffffd3f90) at tmux.c:502
> >
> > >How-To-Repeat:
> > 1. Launch tmux
> > 2. Lock the tmux session using ctrl+b :lock
> > 3. Press ctrl+\
> > 4. Blindly run "pkill lock" to stop the flood of text
> > >Fix:
> > The following patch seems to fix it. The server correctly shuts
> > down if it receives a SIGQUIT while not locked, or after lock(1)
> > exits if it was locked when the signal arrived, the latter being
> > the same behavior as other terminating signals.
> >
> > Index: proc.c
> > ===================================================================
> > RCS file: /cvs/src/usr.bin/tmux/proc.c,v
> > retrieving revision 1.17
> > diff -u -p -r1.17 proc.c
> > --- proc.c 16 May 2020 16:07:55 -0000 1.17
> > +++ proc.c 3 Aug 2020 22:15:46 -0000
> > @@ -42,6 +42,7 @@ struct tmuxproc {
> >   struct event  ev_sigchld;
> >   struct event  ev_sigcont;
> >   struct event  ev_sigterm;
> > + struct event  ev_sigquit;
> >   struct event  ev_sigusr1;
> >   struct event  ev_sigusr2;
> >   struct event  ev_sigwinch;
> > @@ -237,6 +238,8 @@ proc_set_signals(struct tmuxproc *tp, vo
> >   signal_add(&tp->ev_sigcont, NULL);
> >   signal_set(&tp->ev_sigterm, SIGTERM, proc_signal_cb, tp);
> >   signal_add(&tp->ev_sigterm, NULL);
> > + signal_set(&tp->ev_sigquit, SIGQUIT, proc_signal_cb, tp);
> > + signal_add(&tp->ev_sigquit, NULL);
> >   signal_set(&tp->ev_sigusr1, SIGUSR1, proc_signal_cb, tp);
> >   signal_add(&tp->ev_sigusr1, NULL);
> >   signal_set(&tp->ev_sigusr2, SIGUSR2, proc_signal_cb, tp);
> > Index: server.c
> > ===================================================================
> > RCS file: /cvs/src/usr.bin/tmux/server.c,v
> > retrieving revision 1.194
> > diff -u -p -r1.194 server.c
> > --- server.c 18 Jun 2020 08:34:22 -0000 1.194
> > +++ server.c 3 Aug 2020 22:15:46 -0000
> > @@ -407,6 +407,7 @@ server_signal(int sig)
> >   switch (sig) {
> >   case SIGINT:
> >   case SIGTERM:
> > + case SIGQUIT:
> >   server_exit = 1;
> >   server_send_exit();
> >   break;
> >