[oe] [PATCH][meta-networking] inetutils: Fix deadlock in telnetd when cleanup

Joe MacDonald Joe_MacDonald at mentor.com
Wed Jul 15 16:06:32 UTC 2015


Is this fix even relevant?  Has anyone seen this or able to trigger it
(maybe by using the script in the first link?  I wasn't.)  If someone
thinks this is still required, I'll merge it, but on the surface it's a
five year old patch for a different piece of software (netkit-telnet vs.
inetutils) that causes a deadlock on a much older version of a libc
library and a five-and-a-half-year-old kernel.

-J.

[[oe] [PATCH][meta-networking] inetutils: Fix deadlock in telnetd when cleanup] On 15.07.06 (Mon 17:16) rongqing.li at windriver.com wrote:

> From: Li Wang <li.wang at windriver.com>
> 
> the patch comes from:
> https://bugs.launchpad.net/ubuntu/+source/netkit-telnet/+bug/507455
> 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 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 at netinsight.net>
> Signed-off-by: Li Wang <li.wang at windriver.com>
> ---
>  .../telnetd-Fix-deadlock-on-cleanup.patch          | 108 +++++++++++++++++++++
>  .../inetutils/inetutils_1.9.2.bb                   |   1 +
>  2 files changed, 109 insertions(+)
>  create mode 100644 meta-networking/recipes-connectivity/inetutils/inetutils-1.9.2/telnetd-Fix-deadlock-on-cleanup.patch
> 
> diff --git a/meta-networking/recipes-connectivity/inetutils/inetutils-1.9.2/telnetd-Fix-deadlock-on-cleanup.patch b/meta-networking/recipes-connectivity/inetutils/inetutils-1.9.2/telnetd-Fix-deadlock-on-cleanup.patch
> new file mode 100644
> index 0000000..3ec7613
> --- /dev/null
> +++ b/meta-networking/recipes-connectivity/inetutils/inetutils-1.9.2/telnetd-Fix-deadlock-on-cleanup.patch
> @@ -0,0 +1,108 @@
> +telnetd: Fix deadlock on cleanup
> +
> +the patch comes from:
> +https://bugs.launchpad.net/ubuntu/+source/netkit-telnet/+bug/507455
> +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 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 at netinsight.net>
> +Signed-off-by: Li Wang <li.wang at windriver.com>
> +---
> + telnetd/pty.c     |   17 ++++++++++++++++-
> + telnetd/telnetd.c |    2 +-
> + telnetd/telnetd.h |    1 +
> + 3 files changed, 18 insertions(+), 2 deletions(-)
> +
> +diff --git a/telnetd/pty.c b/telnetd/pty.c
> +index 21b0b69..22a17c5 100644
> +--- a/telnetd/pty.c
> ++++ b/telnetd/pty.c
> +@@ -145,7 +145,7 @@ start_login (char *host, int autologin, char *name)
> +  * reported exit code.
> +  */
> + void
> +-cleanup (int sig)
> ++cleanup_sighandler (int sig)
> + {
> +   int status = EXIT_FAILURE;
> +   char *p;
> +@@ -168,3 +168,18 @@ cleanup (int sig)
> +   shutdown (net, 2);
> +   exit (status);
> + }
> ++
> ++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 cf7ce0f..4fe95b5 100644
> +--- a/telnetd/telnetd.c
> ++++ b/telnetd/telnetd.c
> +@@ -527,7 +527,7 @@ telnetd_setup (int fd)
> +   signal (SIGTTOU, SIG_IGN);
> + #endif
> + 
> +-  signal (SIGCHLD, cleanup);
> ++  signal (SIGCHLD, cleanup_sighandler);
> + }
> + 
> + int
> +diff --git a/telnetd/telnetd.h b/telnetd/telnetd.h
> +index ce90fbc..8bac120 100644
> +--- a/telnetd/telnetd.h
> ++++ b/telnetd/telnetd.h
> +@@ -326,6 +326,7 @@ extern void add_slc (char func, char flag, cc_t val);
> + extern void check_slc (void);
> + extern void change_slc (char func, char flag, cc_t val);
> + 
> ++extern void cleanup_sighandler (int);
> + extern void cleanup (int);
> + extern void clientstat (int, int, int);
> + extern void copy_termbuf ();
> +-- 
> +1.7.9.5
> +
> diff --git a/meta-networking/recipes-connectivity/inetutils/inetutils_1.9.2.bb b/meta-networking/recipes-connectivity/inetutils/inetutils_1.9.2.bb
> index 9bb9fe8..5c5699a 100644
> --- a/meta-networking/recipes-connectivity/inetutils/inetutils_1.9.2.bb
> +++ b/meta-networking/recipes-connectivity/inetutils/inetutils_1.9.2.bb
> @@ -18,6 +18,7 @@ SRC_URI = "${GNU_MIRROR}/inetutils/inetutils-${PV}.tar.gz \
>             file://telnet.xinetd.inetutils \
>             file://tftpd.xinetd.inetutils \
>             file://inetutils-1.9-PATH_PROCNET_DEV.patch \
> +           file://telnetd-Fix-deadlock-on-cleanup.patch \
>  "
>  
>  SRC_URI[md5sum] = "aa1a9a132259db83e66c1f3265065ba2"
> -- 
> 1.9.1
> 
-- 
-Joe MacDonald.
:wq
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.openembedded.org/pipermail/openembedded-devel/attachments/20150715/3026ce81/attachment-0002.sig>


More information about the Openembedded-devel mailing list