* [PATCH] telnetd: Fix deadlock on cleanup
@ 2018-06-08 4:42 Seiichi Ishitsuka
0 siblings, 0 replies; 8+ messages in thread
From: Seiichi Ishitsuka @ 2018-06-08 4:42 UTC (permalink / raw)
To: openembedded-devel
The cleanup function in telnetd is called both directly and on SIGCHLD signals.
This triggered a deadlock in glibc and was reproduced in glibc 2.27 while
running on a 4.14.30 kernel.
Signed-off-by: Seiichi Ishitsuka <ishitsuka.sc@ncos.nec.co.jp>
---
...01-telnet-telnetd-Fix-deadlock-on-cleanup.patch | 114 +++++++++++++++++++++
.../netkit-telnet/netkit-telnet_0.17.bb | 1 +
2 files changed, 115 insertions(+)
create mode 100644 meta-networking/recipes-netkit/netkit-telnet/files/0001-telnet-telnetd-Fix-deadlock-on-cleanup.patch
diff --git a/meta-networking/recipes-netkit/netkit-telnet/files/0001-telnet-telnetd-Fix-deadlock-on-cleanup.patch b/meta-networking/recipes-netkit/netkit-telnet/files/0001-telnet-telnetd-Fix-deadlock-on-cleanup.patch
new file mode 100644
index 0000000..945785d
--- /dev/null
+++ b/meta-networking/recipes-netkit/netkit-telnet/files/0001-telnet-telnetd-Fix-deadlock-on-cleanup.patch
@@ -0,0 +1,114 @@
+From 06ed6a6bf25a22902846097d6b6c97e070c2c326 Mon Sep 17 00:00:00 2001
+From: Seiichi Ishitsuka <ishitsuka.sc@ncos.nec.co.jp>
+Date: Fri, 1 Jun 2018 14:27:35 +0900
+Subject: [PATCH] telnetd: Fix deadlock on cleanup
+
+The cleanup function in telnetd is called both directly and on SIGCHLD
+signals. This, unfortunately, triggered a deadlock in eglibc 2.9 while
+running on a 2.6.31.11 kernel.
+
+What we were seeing is hangs like these:
+
+ (gdb) bt
+ #0 0xb7702424 in __kernel_vsyscall ()
+ #1 0xb7658e61 in __lll_lock_wait_private () from ./lib/libc.so.6
+ #2 0xb767e7b5 in _L_lock_15 () from ./lib/libc.so.6
+ #3 0xb767e6e0 in utmpname () from ./lib/libc.so.6
+ #4 0xb76bcde7 in logout () from ./lib/libutil.so.1
+ #5 0x0804c827 in cleanup ()
+ #6 <signal handler called>
+ #7 0xb7702424 in __kernel_vsyscall ()
+ #8 0xb7641003 in __fcntl_nocancel () from ./lib/libc.so.6
+ #9 0xb767e0c3 in getutline_r_file () from ./lib/libc.so.6
+ #10 0xb767d675 in getutline_r () from ./lib/libc.so.6
+ #11 0xb76bce42 in logout () from ./lib/libutil.so.1
+ #12 0x0804c827 in cleanup ()
+ #13 0x0804a0b5 in telnet ()
+ #14 0x0804a9c3 in main ()
+
+and what has happened here is that the user closes the telnet session
+via the escape character. This causes telnetd to call cleanup in frame
+the SIGCHLD signal is delivered while telnetd is executing cleanup.
+
+Telnetd then calls the signal handler for SIGCHLD, which is cleanup().
+Ouch. The actual deadlock is in libc. getutline_r in frame #10 gets the
+__libc_utmp_lock lock, and utmpname above does the same thing in frame
+
+The fix registers the SIGCHLD handler as cleanup_sighandler, and makes
+cleanup disable the SIGCHLD signal before calling cleanup_sighandler.
+
+Signed-off-by: Simon Kagstrom <simon.kagstrom@netinsight.net>
+
+The patch was imported from the Ubuntu netkit-telnet package.
+(https://bugs.launchpad.net/ubuntu/+source/netkit-telnet/+bug/507455)
+
+A previous patch declaring attributes of functions, but it is not used
+in upstream.
+
+Signed-off-by: Seiichi Ishitsuka <ishitsuka.sc@ncos.nec.co.jp>
+---
+ telnetd/ext.h | 1 +
+ telnetd/sys_term.c | 17 ++++++++++++++++-
+ telnetd/telnetd.c | 2 +-
+ 3 files changed, 18 insertions(+), 2 deletions(-)
+
+diff --git a/telnetd/ext.h b/telnetd/ext.h
+index b98d6ec..08f9d07 100644
+--- a/telnetd/ext.h
++++ b/telnetd/ext.h
+@@ -97,6 +97,7 @@ void add_slc(int, int, int);
+ void check_slc(void);
+ void change_slc(int, int, int);
+ void cleanup(int);
++void cleanup_sighandler(int);
+ void clientstat(int, int, int);
+ void copy_termbuf(char *, int);
+ void deferslc(void);
+diff --git a/telnetd/sys_term.c b/telnetd/sys_term.c
+index 5b4aa84..c4fb0f7 100644
+--- a/telnetd/sys_term.c
++++ b/telnetd/sys_term.c
+@@ -719,7 +719,7 @@ static void addarg(struct argv_stuff *avs, const char *val) {
+ * This is the routine to call when we are all through, to
+ * clean up anything that needs to be cleaned up.
+ */
+-void cleanup(int sig) {
++void cleanup_sighandler(int sig) {
+ char *p;
+ (void)sig;
+
+@@ -742,3 +742,18 @@ void cleanup(int sig) {
+ shutdown(net, 2);
+ exit(0);
+ }
++
++void cleanup(int sig) {
++ sigset_t mask, oldmask;
++
++ /* Set up the mask of signals to temporarily block. */
++ sigemptyset (&mask);
++ sigaddset (&mask, SIGCHLD);
++
++ /* Block SIGCHLD while running cleanup */
++ sigprocmask (SIG_BLOCK, &mask, &oldmask);
++
++ cleanup_sighandler(sig);
++ /* Technically not needed since cleanup_sighandler exits */
++ sigprocmask (SIG_UNBLOCK, &mask, NULL);
++}
+diff --git a/telnetd/telnetd.c b/telnetd/telnetd.c
+index 9ace838..788919c 100644
+--- a/telnetd/telnetd.c
++++ b/telnetd/telnetd.c
+@@ -833,7 +833,7 @@ void telnet(int f, int p)
+ signal(SIGTTOU, SIG_IGN);
+ #endif
+
+- signal(SIGCHLD, cleanup);
++ signal(SIGCHLD, cleanup_sighandler);
+
+ #ifdef TIOCNOTTY
+ {
+--
+2.7.4
+
diff --git a/meta-networking/recipes-netkit/netkit-telnet/netkit-telnet_0.17.bb b/meta-networking/recipes-netkit/netkit-telnet/netkit-telnet_0.17.bb
index 28ef36b..c03b8d9 100644
--- a/meta-networking/recipes-netkit/netkit-telnet/netkit-telnet_0.17.bb
+++ b/meta-networking/recipes-netkit/netkit-telnet/netkit-telnet_0.17.bb
@@ -11,6 +11,7 @@ SRC_URI = "ftp://ftp.uk.linux.org/pub/linux/Networking/netkit/${BP}.tar.gz \
file://telnet-xinetd \
file://cross-compile.patch \
file://0001-telnet-telnetd-Fix-print-format-strings.patch \
+ file://0001-telnet-telnetd-Fix-deadlock-on-cleanup.patch \
"
UPSTREAM_CHECK_URI = "${DEBIAN_MIRROR}/main/n/netkit-telnet/"
--
2.7.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH] telnetd: Fix deadlock on cleanup
@ 2018-06-06 9:12 Seiichi Ishitsuka
0 siblings, 0 replies; 8+ messages in thread
From: Seiichi Ishitsuka @ 2018-06-06 9:12 UTC (permalink / raw)
To: openembedded-devel
The cleanup function in telnetd is called both directly and on SIGCHLD signals.
This triggered a deadlock in glibc and was reproduced in glibc 2.27 while
running on a 4.14.30 kernel.
Signed-off-by: Seiichi Ishitsuka <ishitsuka.sc@ncos.nec.co.jp>
---
...01-telnet-telnetd-Fix-deadlock-on-cleanup.patch | 114 +++++++++++++++++++++
.../netkit-telnet/netkit-telnet_0.17.bb | 1 +
2 files changed, 115 insertions(+)
create mode 100644 meta-networking/recipes-netkit/netkit-telnet/files/0001-telnet-telnetd-Fix-deadlock-on-cleanup.patch
diff --git a/meta-networking/recipes-netkit/netkit-telnet/files/0001-telnet-telnetd-Fix-deadlock-on-cleanup.patch b/meta-networking/recipes-netkit/netkit-telnet/files/0001-telnet-telnetd-Fix-deadlock-on-cleanup.patch
new file mode 100644
index 0000000..945785d
--- /dev/null
+++ b/meta-networking/recipes-netkit/netkit-telnet/files/0001-telnet-telnetd-Fix-deadlock-on-cleanup.patch
@@ -0,0 +1,114 @@
+From 06ed6a6bf25a22902846097d6b6c97e070c2c326 Mon Sep 17 00:00:00 2001
+From: Seiichi Ishitsuka <ishitsuka.sc@ncos.nec.co.jp>
+Date: Fri, 1 Jun 2018 14:27:35 +0900
+Subject: [PATCH] telnetd: Fix deadlock on cleanup
+
+The cleanup function in telnetd is called both directly and on SIGCHLD
+signals. This, unfortunately, triggered a deadlock in eglibc 2.9 while
+running on a 2.6.31.11 kernel.
+
+What we were seeing is hangs like these:
+
+ (gdb) bt
+ #0 0xb7702424 in __kernel_vsyscall ()
+ #1 0xb7658e61 in __lll_lock_wait_private () from ./lib/libc.so.6
+ #2 0xb767e7b5 in _L_lock_15 () from ./lib/libc.so.6
+ #3 0xb767e6e0 in utmpname () from ./lib/libc.so.6
+ #4 0xb76bcde7 in logout () from ./lib/libutil.so.1
+ #5 0x0804c827 in cleanup ()
+ #6 <signal handler called>
+ #7 0xb7702424 in __kernel_vsyscall ()
+ #8 0xb7641003 in __fcntl_nocancel () from ./lib/libc.so.6
+ #9 0xb767e0c3 in getutline_r_file () from ./lib/libc.so.6
+ #10 0xb767d675 in getutline_r () from ./lib/libc.so.6
+ #11 0xb76bce42 in logout () from ./lib/libutil.so.1
+ #12 0x0804c827 in cleanup ()
+ #13 0x0804a0b5 in telnet ()
+ #14 0x0804a9c3 in main ()
+
+and what has happened here is that the user closes the telnet session
+via the escape character. This causes telnetd to call cleanup in frame
+the SIGCHLD signal is delivered while telnetd is executing cleanup.
+
+Telnetd then calls the signal handler for SIGCHLD, which is cleanup().
+Ouch. The actual deadlock is in libc. getutline_r in frame #10 gets the
+__libc_utmp_lock lock, and utmpname above does the same thing in frame
+
+The fix registers the SIGCHLD handler as cleanup_sighandler, and makes
+cleanup disable the SIGCHLD signal before calling cleanup_sighandler.
+
+Signed-off-by: Simon Kagstrom <simon.kagstrom@netinsight.net>
+
+The patch was imported from the Ubuntu netkit-telnet package.
+(https://bugs.launchpad.net/ubuntu/+source/netkit-telnet/+bug/507455)
+
+A previous patch declaring attributes of functions, but it is not used
+in upstream.
+
+Signed-off-by: Seiichi Ishitsuka <ishitsuka.sc@ncos.nec.co.jp>
+---
+ telnetd/ext.h | 1 +
+ telnetd/sys_term.c | 17 ++++++++++++++++-
+ telnetd/telnetd.c | 2 +-
+ 3 files changed, 18 insertions(+), 2 deletions(-)
+
+diff --git a/telnetd/ext.h b/telnetd/ext.h
+index b98d6ec..08f9d07 100644
+--- a/telnetd/ext.h
++++ b/telnetd/ext.h
+@@ -97,6 +97,7 @@ void add_slc(int, int, int);
+ void check_slc(void);
+ void change_slc(int, int, int);
+ void cleanup(int);
++void cleanup_sighandler(int);
+ void clientstat(int, int, int);
+ void copy_termbuf(char *, int);
+ void deferslc(void);
+diff --git a/telnetd/sys_term.c b/telnetd/sys_term.c
+index 5b4aa84..c4fb0f7 100644
+--- a/telnetd/sys_term.c
++++ b/telnetd/sys_term.c
+@@ -719,7 +719,7 @@ static void addarg(struct argv_stuff *avs, const char *val) {
+ * This is the routine to call when we are all through, to
+ * clean up anything that needs to be cleaned up.
+ */
+-void cleanup(int sig) {
++void cleanup_sighandler(int sig) {
+ char *p;
+ (void)sig;
+
+@@ -742,3 +742,18 @@ void cleanup(int sig) {
+ shutdown(net, 2);
+ exit(0);
+ }
++
++void cleanup(int sig) {
++ sigset_t mask, oldmask;
++
++ /* Set up the mask of signals to temporarily block. */
++ sigemptyset (&mask);
++ sigaddset (&mask, SIGCHLD);
++
++ /* Block SIGCHLD while running cleanup */
++ sigprocmask (SIG_BLOCK, &mask, &oldmask);
++
++ cleanup_sighandler(sig);
++ /* Technically not needed since cleanup_sighandler exits */
++ sigprocmask (SIG_UNBLOCK, &mask, NULL);
++}
+diff --git a/telnetd/telnetd.c b/telnetd/telnetd.c
+index 9ace838..788919c 100644
+--- a/telnetd/telnetd.c
++++ b/telnetd/telnetd.c
+@@ -833,7 +833,7 @@ void telnet(int f, int p)
+ signal(SIGTTOU, SIG_IGN);
+ #endif
+
+- signal(SIGCHLD, cleanup);
++ signal(SIGCHLD, cleanup_sighandler);
+
+ #ifdef TIOCNOTTY
+ {
+--
+2.7.4
+
diff --git a/meta-networking/recipes-netkit/netkit-telnet/netkit-telnet_0.17.bb b/meta-networking/recipes-netkit/netkit-telnet/netkit-telnet_0.17.bb
index 28ef36b..c03b8d9 100644
--- a/meta-networking/recipes-netkit/netkit-telnet/netkit-telnet_0.17.bb
+++ b/meta-networking/recipes-netkit/netkit-telnet/netkit-telnet_0.17.bb
@@ -11,6 +11,7 @@ SRC_URI = "ftp://ftp.uk.linux.org/pub/linux/Networking/netkit/${BP}.tar.gz \
file://telnet-xinetd \
file://cross-compile.patch \
file://0001-telnet-telnetd-Fix-print-format-strings.patch \
+ file://0001-telnet-telnetd-Fix-deadlock-on-cleanup.patch \
"
UPSTREAM_CHECK_URI = "${DEBIAN_MIRROR}/main/n/netkit-telnet/"
--
2.7.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH] telnetd: Fix deadlock on cleanup
2018-06-03 6:42 Seiichi Ishitsuka
@ 2018-06-05 16:58 ` Khem Raj
0 siblings, 0 replies; 8+ messages in thread
From: Khem Raj @ 2018-06-05 16:58 UTC (permalink / raw)
To: Seiichi Ishitsuka; +Cc: openembeded-devel
can you rebase it on top of master-next and resend ?
On Sat, Jun 2, 2018 at 11:42 PM, Seiichi Ishitsuka
<ishitsuka.sc@gmail.com> wrote:
> The cleanup function in telnetd is called both directly and on SIGCHLD signals.
> This triggered a deadlock in glibc and was reproduced in glibc 2.27 while
> running on a 4.14.30 kernel.
>
> Signed-off-by: Seiichi Ishitsuka <ishitsuka.sc@ncos.nec.co.jp>
> ---
> ...01-telnet-telnetd-Fix-deadlock-on-cleanup.patch | 114 +++++++++++++++++++++
> .../netkit-telnet/netkit-telnet_0.17.bb | 1 +
> 2 files changed, 115 insertions(+)
> create mode 100644 meta-networking/recipes-netkit/netkit-telnet/files/0001-telnet-telnetd-Fix-deadlock-on-cleanup.patch
>
> diff --git a/meta-networking/recipes-netkit/netkit-telnet/files/0001-telnet-telnetd-Fix-deadlock-on-cleanup.patch b/meta-networking/recipes-netkit/netkit-telnet/files/0001-telnet-telnetd-Fix-deadlock-on-cleanup.patch
> new file mode 100644
> index 0000000..945785d
> --- /dev/null
> +++ b/meta-networking/recipes-netkit/netkit-telnet/files/0001-telnet-telnetd-Fix-deadlock-on-cleanup.patch
> @@ -0,0 +1,114 @@
> +From 06ed6a6bf25a22902846097d6b6c97e070c2c326 Mon Sep 17 00:00:00 2001
> +From: Seiichi Ishitsuka <ishitsuka.sc@ncos.nec.co.jp>
> +Date: Fri, 1 Jun 2018 14:27:35 +0900
> +Subject: [PATCH] telnetd: Fix deadlock on cleanup
> +
> +The cleanup function in telnetd is called both directly and on SIGCHLD
> +signals. This, unfortunately, triggered a deadlock in eglibc 2.9 while
> +running on a 2.6.31.11 kernel.
> +
> +What we were seeing is hangs like these:
> +
> + (gdb) bt
> + #0 0xb7702424 in __kernel_vsyscall ()
> + #1 0xb7658e61 in __lll_lock_wait_private () from ./lib/libc.so.6
> + #2 0xb767e7b5 in _L_lock_15 () from ./lib/libc.so.6
> + #3 0xb767e6e0 in utmpname () from ./lib/libc.so.6
> + #4 0xb76bcde7 in logout () from ./lib/libutil.so.1
> + #5 0x0804c827 in cleanup ()
> + #6 <signal handler called>
> + #7 0xb7702424 in __kernel_vsyscall ()
> + #8 0xb7641003 in __fcntl_nocancel () from ./lib/libc.so.6
> + #9 0xb767e0c3 in getutline_r_file () from ./lib/libc.so.6
> + #10 0xb767d675 in getutline_r () from ./lib/libc.so.6
> + #11 0xb76bce42 in logout () from ./lib/libutil.so.1
> + #12 0x0804c827 in cleanup ()
> + #13 0x0804a0b5 in telnet ()
> + #14 0x0804a9c3 in main ()
> +
> +and what has happened here is that the user closes the telnet session
> +via the escape character. This causes telnetd to call cleanup in frame
> +the SIGCHLD signal is delivered while telnetd is executing cleanup.
> +
> +Telnetd then calls the signal handler for SIGCHLD, which is cleanup().
> +Ouch. The actual deadlock is in libc. getutline_r in frame #10 gets the
> +__libc_utmp_lock lock, and utmpname above does the same thing in frame
> +
> +The fix registers the SIGCHLD handler as cleanup_sighandler, and makes
> +cleanup disable the SIGCHLD signal before calling cleanup_sighandler.
> +
> +Signed-off-by: Simon Kagstrom <simon.kagstrom@netinsight.net>
> +
> +The patch was imported from the Ubuntu netkit-telnet package.
> +(https://bugs.launchpad.net/ubuntu/+source/netkit-telnet/+bug/507455)
> +
> +A previous patch declaring attributes of functions, but it is not used
> +in upstream.
> +
> +Signed-off-by: Seiichi Ishitsuka <ishitsuka.sc@ncos.nec.co.jp>
> +---
> + telnetd/ext.h | 1 +
> + telnetd/sys_term.c | 17 ++++++++++++++++-
> + telnetd/telnetd.c | 2 +-
> + 3 files changed, 18 insertions(+), 2 deletions(-)
> +
> +diff --git a/telnetd/ext.h b/telnetd/ext.h
> +index b98d6ec..08f9d07 100644
> +--- a/telnetd/ext.h
> ++++ b/telnetd/ext.h
> +@@ -97,6 +97,7 @@ void add_slc(int, int, int);
> + void check_slc(void);
> + void change_slc(int, int, int);
> + void cleanup(int);
> ++void cleanup_sighandler(int);
> + void clientstat(int, int, int);
> + void copy_termbuf(char *, int);
> + void deferslc(void);
> +diff --git a/telnetd/sys_term.c b/telnetd/sys_term.c
> +index 5b4aa84..c4fb0f7 100644
> +--- a/telnetd/sys_term.c
> ++++ b/telnetd/sys_term.c
> +@@ -719,7 +719,7 @@ static void addarg(struct argv_stuff *avs, const char *val) {
> + * This is the routine to call when we are all through, to
> + * clean up anything that needs to be cleaned up.
> + */
> +-void cleanup(int sig) {
> ++void cleanup_sighandler(int sig) {
> + char *p;
> + (void)sig;
> +
> +@@ -742,3 +742,18 @@ void cleanup(int sig) {
> + shutdown(net, 2);
> + exit(0);
> + }
> ++
> ++void cleanup(int sig) {
> ++ sigset_t mask, oldmask;
> ++
> ++ /* Set up the mask of signals to temporarily block. */
> ++ sigemptyset (&mask);
> ++ sigaddset (&mask, SIGCHLD);
> ++
> ++ /* Block SIGCHLD while running cleanup */
> ++ sigprocmask (SIG_BLOCK, &mask, &oldmask);
> ++
> ++ cleanup_sighandler(sig);
> ++ /* Technically not needed since cleanup_sighandler exits */
> ++ sigprocmask (SIG_UNBLOCK, &mask, NULL);
> ++}
> +diff --git a/telnetd/telnetd.c b/telnetd/telnetd.c
> +index 9ace838..788919c 100644
> +--- a/telnetd/telnetd.c
> ++++ b/telnetd/telnetd.c
> +@@ -833,7 +833,7 @@ void telnet(int f, int p)
> + signal(SIGTTOU, SIG_IGN);
> + #endif
> +
> +- signal(SIGCHLD, cleanup);
> ++ signal(SIGCHLD, cleanup_sighandler);
> +
> + #ifdef TIOCNOTTY
> + {
> +--
> +2.7.4
> +
> diff --git a/meta-networking/recipes-netkit/netkit-telnet/netkit-telnet_0.17.bb b/meta-networking/recipes-netkit/netkit-telnet/netkit-telnet_0.17.bb
> index 807b566..743cf26 100644
> --- a/meta-networking/recipes-netkit/netkit-telnet/netkit-telnet_0.17.bb
> +++ b/meta-networking/recipes-netkit/netkit-telnet/netkit-telnet_0.17.bb
> @@ -11,6 +11,7 @@ SRC_URI = "ftp://ftp.uk.linux.org/pub/linux/Networking/netkit/${BP}.tar.gz \
> file://telnet-xinetd \
> file://cross-compile.patch \
> file://0001-telnet-telnetd-Fix-print-format-strings.patch \
> + file://0001-telnet-telnetd-Fix-deadlock-on-cleanup.patch \
> "
>
> EXTRA_OEMAKE = "INSTALLROOT=${D} SBINDIR=${sbindir} DAEMONMODE=755 \
> --
> 2.7.4
>
> --
> _______________________________________________
> Openembedded-devel mailing list
> Openembedded-devel@lists.openembedded.org
> http://lists.openembedded.org/mailman/listinfo/openembedded-devel
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH] telnetd: Fix deadlock on cleanup
@ 2018-06-03 6:42 Seiichi Ishitsuka
2018-06-05 16:58 ` Khem Raj
0 siblings, 1 reply; 8+ messages in thread
From: Seiichi Ishitsuka @ 2018-06-03 6:42 UTC (permalink / raw)
To: openembedded-devel
The cleanup function in telnetd is called both directly and on SIGCHLD signals.
This triggered a deadlock in glibc and was reproduced in glibc 2.27 while
running on a 4.14.30 kernel.
Signed-off-by: Seiichi Ishitsuka <ishitsuka.sc@ncos.nec.co.jp>
---
...01-telnet-telnetd-Fix-deadlock-on-cleanup.patch | 114 +++++++++++++++++++++
.../netkit-telnet/netkit-telnet_0.17.bb | 1 +
2 files changed, 115 insertions(+)
create mode 100644 meta-networking/recipes-netkit/netkit-telnet/files/0001-telnet-telnetd-Fix-deadlock-on-cleanup.patch
diff --git a/meta-networking/recipes-netkit/netkit-telnet/files/0001-telnet-telnetd-Fix-deadlock-on-cleanup.patch b/meta-networking/recipes-netkit/netkit-telnet/files/0001-telnet-telnetd-Fix-deadlock-on-cleanup.patch
new file mode 100644
index 0000000..945785d
--- /dev/null
+++ b/meta-networking/recipes-netkit/netkit-telnet/files/0001-telnet-telnetd-Fix-deadlock-on-cleanup.patch
@@ -0,0 +1,114 @@
+From 06ed6a6bf25a22902846097d6b6c97e070c2c326 Mon Sep 17 00:00:00 2001
+From: Seiichi Ishitsuka <ishitsuka.sc@ncos.nec.co.jp>
+Date: Fri, 1 Jun 2018 14:27:35 +0900
+Subject: [PATCH] telnetd: Fix deadlock on cleanup
+
+The cleanup function in telnetd is called both directly and on SIGCHLD
+signals. This, unfortunately, triggered a deadlock in eglibc 2.9 while
+running on a 2.6.31.11 kernel.
+
+What we were seeing is hangs like these:
+
+ (gdb) bt
+ #0 0xb7702424 in __kernel_vsyscall ()
+ #1 0xb7658e61 in __lll_lock_wait_private () from ./lib/libc.so.6
+ #2 0xb767e7b5 in _L_lock_15 () from ./lib/libc.so.6
+ #3 0xb767e6e0 in utmpname () from ./lib/libc.so.6
+ #4 0xb76bcde7 in logout () from ./lib/libutil.so.1
+ #5 0x0804c827 in cleanup ()
+ #6 <signal handler called>
+ #7 0xb7702424 in __kernel_vsyscall ()
+ #8 0xb7641003 in __fcntl_nocancel () from ./lib/libc.so.6
+ #9 0xb767e0c3 in getutline_r_file () from ./lib/libc.so.6
+ #10 0xb767d675 in getutline_r () from ./lib/libc.so.6
+ #11 0xb76bce42 in logout () from ./lib/libutil.so.1
+ #12 0x0804c827 in cleanup ()
+ #13 0x0804a0b5 in telnet ()
+ #14 0x0804a9c3 in main ()
+
+and what has happened here is that the user closes the telnet session
+via the escape character. This causes telnetd to call cleanup in frame
+the SIGCHLD signal is delivered while telnetd is executing cleanup.
+
+Telnetd then calls the signal handler for SIGCHLD, which is cleanup().
+Ouch. The actual deadlock is in libc. getutline_r in frame #10 gets the
+__libc_utmp_lock lock, and utmpname above does the same thing in frame
+
+The fix registers the SIGCHLD handler as cleanup_sighandler, and makes
+cleanup disable the SIGCHLD signal before calling cleanup_sighandler.
+
+Signed-off-by: Simon Kagstrom <simon.kagstrom@netinsight.net>
+
+The patch was imported from the Ubuntu netkit-telnet package.
+(https://bugs.launchpad.net/ubuntu/+source/netkit-telnet/+bug/507455)
+
+A previous patch declaring attributes of functions, but it is not used
+in upstream.
+
+Signed-off-by: Seiichi Ishitsuka <ishitsuka.sc@ncos.nec.co.jp>
+---
+ telnetd/ext.h | 1 +
+ telnetd/sys_term.c | 17 ++++++++++++++++-
+ telnetd/telnetd.c | 2 +-
+ 3 files changed, 18 insertions(+), 2 deletions(-)
+
+diff --git a/telnetd/ext.h b/telnetd/ext.h
+index b98d6ec..08f9d07 100644
+--- a/telnetd/ext.h
++++ b/telnetd/ext.h
+@@ -97,6 +97,7 @@ void add_slc(int, int, int);
+ void check_slc(void);
+ void change_slc(int, int, int);
+ void cleanup(int);
++void cleanup_sighandler(int);
+ void clientstat(int, int, int);
+ void copy_termbuf(char *, int);
+ void deferslc(void);
+diff --git a/telnetd/sys_term.c b/telnetd/sys_term.c
+index 5b4aa84..c4fb0f7 100644
+--- a/telnetd/sys_term.c
++++ b/telnetd/sys_term.c
+@@ -719,7 +719,7 @@ static void addarg(struct argv_stuff *avs, const char *val) {
+ * This is the routine to call when we are all through, to
+ * clean up anything that needs to be cleaned up.
+ */
+-void cleanup(int sig) {
++void cleanup_sighandler(int sig) {
+ char *p;
+ (void)sig;
+
+@@ -742,3 +742,18 @@ void cleanup(int sig) {
+ shutdown(net, 2);
+ exit(0);
+ }
++
++void cleanup(int sig) {
++ sigset_t mask, oldmask;
++
++ /* Set up the mask of signals to temporarily block. */
++ sigemptyset (&mask);
++ sigaddset (&mask, SIGCHLD);
++
++ /* Block SIGCHLD while running cleanup */
++ sigprocmask (SIG_BLOCK, &mask, &oldmask);
++
++ cleanup_sighandler(sig);
++ /* Technically not needed since cleanup_sighandler exits */
++ sigprocmask (SIG_UNBLOCK, &mask, NULL);
++}
+diff --git a/telnetd/telnetd.c b/telnetd/telnetd.c
+index 9ace838..788919c 100644
+--- a/telnetd/telnetd.c
++++ b/telnetd/telnetd.c
+@@ -833,7 +833,7 @@ void telnet(int f, int p)
+ signal(SIGTTOU, SIG_IGN);
+ #endif
+
+- signal(SIGCHLD, cleanup);
++ signal(SIGCHLD, cleanup_sighandler);
+
+ #ifdef TIOCNOTTY
+ {
+--
+2.7.4
+
diff --git a/meta-networking/recipes-netkit/netkit-telnet/netkit-telnet_0.17.bb b/meta-networking/recipes-netkit/netkit-telnet/netkit-telnet_0.17.bb
index 807b566..743cf26 100644
--- a/meta-networking/recipes-netkit/netkit-telnet/netkit-telnet_0.17.bb
+++ b/meta-networking/recipes-netkit/netkit-telnet/netkit-telnet_0.17.bb
@@ -11,6 +11,7 @@ SRC_URI = "ftp://ftp.uk.linux.org/pub/linux/Networking/netkit/${BP}.tar.gz \
file://telnet-xinetd \
file://cross-compile.patch \
file://0001-telnet-telnetd-Fix-print-format-strings.patch \
+ file://0001-telnet-telnetd-Fix-deadlock-on-cleanup.patch \
"
EXTRA_OEMAKE = "INSTALLROOT=${D} SBINDIR=${sbindir} DAEMONMODE=755 \
--
2.7.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH] telnetd:Fix deadlock on cleanup
2018-05-29 5:44 ` Seiichi Ishitsuka
@ 2018-05-29 13:21 ` Alexander Kanavin
0 siblings, 0 replies; 8+ messages in thread
From: Alexander Kanavin @ 2018-05-29 13:21 UTC (permalink / raw)
To: Seiichi Ishitsuka; +Cc: Openembedded-core
2018-05-29 8:44 GMT+03:00 Seiichi Ishitsuka <ishitsuka.sc@ncos.nec.co.jp>:
> Dear Alex,
>
>> The patch should go to meta-openembedded list, and it should be created against the layer source tree, not against the component source
>> tree.
>
> Thank you for all your kindness.
> I have created a patch for meta-networking/recipes-netkit/netkit-telnet.
> Please refer to the attached patch.
I must clarify: the patch should be sent to the openembedded-devel
mailing list, not to openembedded-core list. Only patches for the
oe-core layer should be sent here; patches for the meta-oe layers go
to oe-devel list.
Also, please use 'git send-email' for sending patches.
Thank you,
Alex
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] telnetd:Fix deadlock on cleanup
2018-05-28 8:39 ` Alexander Kanavin
@ 2018-05-29 5:44 ` Seiichi Ishitsuka
2018-05-29 13:21 ` Alexander Kanavin
0 siblings, 1 reply; 8+ messages in thread
From: Seiichi Ishitsuka @ 2018-05-29 5:44 UTC (permalink / raw)
To: Alexander Kanavin, Openembedded-core
[-- Attachment #1: Type: text/plain, Size: 345 bytes --]
Dear Alex,
> The patch should go to meta-openembedded list, and it should be created against the layer source tree, not against the component source
> tree.
Thank you for all your kindness.
I have created a patch for meta-networking/recipes-netkit/netkit-telnet.
Please refer to the attached patch.
Best regards,
Seiichi Ishitsuka
[-- Attachment #2: 0001-netkit-telnet-Fix-deadlock-on-cleanup.patch --]
[-- Type: application/octet-stream, Size: 4752 bytes --]
From 59e038c9d15770323be23f4f12087bdf43db7a7b Mon Sep 17 00:00:00 2001
From: Seiichi Ishitsuka <ishitsuka.sc@ncos.nec.co.jp>
Date: Tue, 29 May 2018 11:43:25 +0900
Subject: [PATCH] netkit-telnet: Fix deadlock on cleanup
Signed-off-by: Seiichi Ishitsuka <ishitsuka.sc@ncos.nec.co.jp>
---
.../0001-telnetd-Fix-deadlock-on-cleanup.patch | 107 +++++++++++++++++++++
.../netkit-telnet/netkit-telnet_0.17.bb | 1 +
2 files changed, 108 insertions(+)
create mode 100644 meta-networking/recipes-netkit/netkit-telnet/files/0001-telnetd-Fix-deadlock-on-cleanup.patch
diff --git a/meta-networking/recipes-netkit/netkit-telnet/files/0001-telnetd-Fix-deadlock-on-cleanup.patch b/meta-networking/recipes-netkit/netkit-telnet/files/0001-telnetd-Fix-deadlock-on-cleanup.patch
new file mode 100644
index 0000000..d6873a5
--- /dev/null
+++ b/meta-networking/recipes-netkit/netkit-telnet/files/0001-telnetd-Fix-deadlock-on-cleanup.patch
@@ -0,0 +1,107 @@
+From cdf8829f743adb3ec72c231ee5843dabed91b30f Mon Sep 17 00:00:00 2001
+From: Seiichi Ishitsuka <ishitsuka.sc@ncos.nec.co.jp>
+Date: Tue, 8 May 2018 09:53:34 +0900
+Subject: [PATCH] telnetd:Fix deadlock on cleanup
+
+the patch comes from:
+https://launchpadlibrarian.net/37882973/0001-telnetd-Fix-deadlock-on-cleanup.patch
+
+The cleanup function in telnetd is called both directly and on SIGCHLD
+signals. This, unfortunately, triggered a deadlock in glibc 2.2 while
+running on a 4.4.32 kernel.
+
+What we were seeing is hangs like these:
+
+(gdb) bt
+ #0 0x489fee6c in __lll_lock_wait_private (futex=0x48a5e9a4 <__libc_utmp_lock>) at ./lowlevellock.c:33
+ #1 0x48a27934 in __utmpname (file=0x48ac1278 "/var/run/utmp") at utmpname.c:42
+ #2 0x48ac0ec0 in logout (line=0x27e9d "pts/11") at logout.c:32
+
+How to reproduce:
+
+Run the script more than once in the background.
+
+ #!/bin/sh
+
+ HOST="host.target"
+ USER="root"
+ PASS="password"
+
+ while :
+ do
+ expect -c "
+ set timeout 10
+ spawn telnet $HOST
+ expect login:\ ; send \"$USER\r\"
+ expect sword:\ ; send \"$PASS\r\"
+ expect \"# \" ; send \"exit\r\"
+ " > /dev/null
+ done
+
+Signed-off-by: Seiichi Ishitsuka <ishitsuka.sc@ncos.nec.co.jp>
+---
+ telnetd/ext.h | 1 +
+ telnetd/sys_term.c | 17 ++++++++++++++++-
+ telnetd/telnetd.c | 2 +-
+ 3 files changed, 18 insertions(+), 2 deletions(-)
+
+diff --git a/telnetd/ext.h b/telnetd/ext.h
+index b98d6ec..08f9d07 100644
+--- a/telnetd/ext.h
++++ b/telnetd/ext.h
+@@ -97,6 +97,7 @@ void add_slc(int, int, int);
+ void check_slc(void);
+ void change_slc(int, int, int);
+ void cleanup(int);
++void cleanup_sighandler(int);
+ void clientstat(int, int, int);
+ void copy_termbuf(char *, int);
+ void deferslc(void);
+diff --git a/telnetd/sys_term.c b/telnetd/sys_term.c
+index 5b4aa84..c4fb0f7 100644
+--- a/telnetd/sys_term.c
++++ b/telnetd/sys_term.c
+@@ -719,7 +719,7 @@ static void addarg(struct argv_stuff *avs, const char *val) {
+ * This is the routine to call when we are all through, to
+ * clean up anything that needs to be cleaned up.
+ */
+-void cleanup(int sig) {
++void cleanup_sighandler(int sig) {
+ char *p;
+ (void)sig;
+
+@@ -742,3 +742,18 @@ void cleanup(int sig) {
+ shutdown(net, 2);
+ exit(0);
+ }
++
++void cleanup(int sig) {
++ sigset_t mask, oldmask;
++
++ /* Set up the mask of signals to temporarily block. */
++ sigemptyset (&mask);
++ sigaddset (&mask, SIGCHLD);
++
++ /* Block SIGCHLD while running cleanup */
++ sigprocmask (SIG_BLOCK, &mask, &oldmask);
++
++ cleanup_sighandler(sig);
++ /* Technically not needed since cleanup_sighandler exits */
++ sigprocmask (SIG_UNBLOCK, &mask, NULL);
++}
+diff --git a/telnetd/telnetd.c b/telnetd/telnetd.c
+index 9ace838..788919c 100644
+--- a/telnetd/telnetd.c
++++ b/telnetd/telnetd.c
+@@ -833,7 +833,7 @@ void telnet(int f, int p)
+ signal(SIGTTOU, SIG_IGN);
+ #endif
+
+- signal(SIGCHLD, cleanup);
++ signal(SIGCHLD, cleanup_sighandler);
+
+ #ifdef TIOCNOTTY
+ {
+--
+2.6.4
+
diff --git a/meta-networking/recipes-netkit/netkit-telnet/netkit-telnet_0.17.bb b/meta-networking/recipes-netkit/netkit-telnet/netkit-telnet_0.17.bb
index 807b566..e1566f8 100644
--- a/meta-networking/recipes-netkit/netkit-telnet/netkit-telnet_0.17.bb
+++ b/meta-networking/recipes-netkit/netkit-telnet/netkit-telnet_0.17.bb
@@ -11,6 +11,7 @@ SRC_URI = "ftp://ftp.uk.linux.org/pub/linux/Networking/netkit/${BP}.tar.gz \
file://telnet-xinetd \
file://cross-compile.patch \
file://0001-telnet-telnetd-Fix-print-format-strings.patch \
+ file://0001-telnetd-Fix-deadlock-on-cleanup.patch \
"
EXTRA_OEMAKE = "INSTALLROOT=${D} SBINDIR=${sbindir} DAEMONMODE=755 \
--
1.8.3.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH] telnetd:Fix deadlock on cleanup
2018-05-28 6:27 [PATCH] telnetd:Fix " Seiichi Ishitsuka
@ 2018-05-28 8:39 ` Alexander Kanavin
2018-05-29 5:44 ` Seiichi Ishitsuka
0 siblings, 1 reply; 8+ messages in thread
From: Alexander Kanavin @ 2018-05-28 8:39 UTC (permalink / raw)
To: Seiichi Ishitsuka, Openembedded-core
On 05/28/2018 09:27 AM, Seiichi Ishitsuka wrote:
> I was able to reproduce the old problems shown below with netkit-telnet_0.17.bb.
>
> https://patchwork.openembedded.org/patch/96727/
> https://bugs.launchpad.net/ubuntu/+source/netkit-telnet/+bug/507455
The patch should go to meta-openembedded list, and it should be created
against the layer source tree, not against the component source tree.
Alex
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH] telnetd:Fix deadlock on cleanup
@ 2018-05-28 6:27 Seiichi Ishitsuka
2018-05-28 8:39 ` Alexander Kanavin
0 siblings, 1 reply; 8+ messages in thread
From: Seiichi Ishitsuka @ 2018-05-28 6:27 UTC (permalink / raw)
To: Openembedded-core
[-- Attachment #1: Type: text/plain, Size: 700 bytes --]
Hi all,
I was able to reproduce the old problems shown below with netkit-telnet_0.17.bb.
https://patchwork.openembedded.org/patch/96727/
https://bugs.launchpad.net/ubuntu/+source/netkit-telnet/+bug/507455
The evaluated environment is,
glibc :2.2
kernel :4.4.32
How to reproduce:
Run the script more than once in the background, and
please adjust CPU usage to 100%.
#!/bin/sh
HOST="host.target"
USER="root"
PASS="password"
while :
do
expect -c "
set timeout 10
spawn telnet $HOST
expect login:\ ; send \"$USER\r\"
expect sword:\ ; send \"$PASS\r\"
expect \"# \" ; send \"exit\r\"
" > /dev/null
done
Best regards,
Seiichi Ishitsuka
[-- Attachment #2: 0001-telnetd-Fix-deadlock-on-cleanup.patch --]
[-- Type: application/octet-stream, Size: 2957 bytes --]
From cdf8829f743adb3ec72c231ee5843dabed91b30f Mon Sep 17 00:00:00 2001
From: Seiichi Ishitsuka <ishitsuka.sc@ncos.nec.co.jp>
Date: Tue, 8 May 2018 09:53:34 +0900
Subject: [PATCH] telnetd:Fix deadlock on cleanup
the patch comes from:
https://launchpadlibrarian.net/37882973/0001-telnetd-Fix-deadlock-on-cleanup.patch
The cleanup function in telnetd is called both directly and on SIGCHLD
signals. This, unfortunately, triggered a deadlock in glibc 2.2 while
running on a 4.4.32 kernel.
What we were seeing is hangs like these:
(gdb) bt
#0 0x489fee6c in __lll_lock_wait_private (futex=0x48a5e9a4 <__libc_utmp_lock>) at ./lowlevellock.c:33
#1 0x48a27934 in __utmpname (file=0x48ac1278 "/var/run/utmp") at utmpname.c:42
#2 0x48ac0ec0 in logout (line=0x27e9d "pts/11") at logout.c:32
How to reproduce:
Run the script more than once in the background.
#!/bin/sh
HOST="host.target"
USER="root"
PASS="password"
while :
do
expect -c "
set timeout 10
spawn telnet $HOST
expect login:\ ; send \"$USER\r\"
expect sword:\ ; send \"$PASS\r\"
expect \"# \" ; send \"exit\r\"
" > /dev/null
done
Signed-off-by: Seiichi Ishitsuka <ishitsuka.sc@ncos.nec.co.jp>
---
telnetd/ext.h | 1 +
telnetd/sys_term.c | 17 ++++++++++++++++-
telnetd/telnetd.c | 2 +-
3 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/telnetd/ext.h b/telnetd/ext.h
index b98d6ec..08f9d07 100644
--- a/telnetd/ext.h
+++ b/telnetd/ext.h
@@ -97,6 +97,7 @@ void add_slc(int, int, int);
void check_slc(void);
void change_slc(int, int, int);
void cleanup(int);
+void cleanup_sighandler(int);
void clientstat(int, int, int);
void copy_termbuf(char *, int);
void deferslc(void);
diff --git a/telnetd/sys_term.c b/telnetd/sys_term.c
index 5b4aa84..c4fb0f7 100644
--- a/telnetd/sys_term.c
+++ b/telnetd/sys_term.c
@@ -719,7 +719,7 @@ static void addarg(struct argv_stuff *avs, const char *val) {
* This is the routine to call when we are all through, to
* clean up anything that needs to be cleaned up.
*/
-void cleanup(int sig) {
+void cleanup_sighandler(int sig) {
char *p;
(void)sig;
@@ -742,3 +742,18 @@ void cleanup(int sig) {
shutdown(net, 2);
exit(0);
}
+
+void cleanup(int sig) {
+ sigset_t mask, oldmask;
+
+ /* Set up the mask of signals to temporarily block. */
+ sigemptyset (&mask);
+ sigaddset (&mask, SIGCHLD);
+
+ /* Block SIGCHLD while running cleanup */
+ sigprocmask (SIG_BLOCK, &mask, &oldmask);
+
+ cleanup_sighandler(sig);
+ /* Technically not needed since cleanup_sighandler exits */
+ sigprocmask (SIG_UNBLOCK, &mask, NULL);
+}
diff --git a/telnetd/telnetd.c b/telnetd/telnetd.c
index 9ace838..788919c 100644
--- a/telnetd/telnetd.c
+++ b/telnetd/telnetd.c
@@ -833,7 +833,7 @@ void telnet(int f, int p)
signal(SIGTTOU, SIG_IGN);
#endif
- signal(SIGCHLD, cleanup);
+ signal(SIGCHLD, cleanup_sighandler);
#ifdef TIOCNOTTY
{
--
2.6.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
end of thread, other threads:[~2018-06-08 4:42 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-06-08 4:42 [PATCH] telnetd: Fix deadlock on cleanup Seiichi Ishitsuka
-- strict thread matches above, loose matches on Subject: below --
2018-06-06 9:12 Seiichi Ishitsuka
2018-06-03 6:42 Seiichi Ishitsuka
2018-06-05 16:58 ` Khem Raj
2018-05-28 6:27 [PATCH] telnetd:Fix " Seiichi Ishitsuka
2018-05-28 8:39 ` Alexander Kanavin
2018-05-29 5:44 ` Seiichi Ishitsuka
2018-05-29 13:21 ` Alexander Kanavin
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.