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

Joe MacDonald Joe_MacDonald at mentor.com
Thu Jul 16 13:52:06 UTC 2015


[Re: [oe] [PATCH][meta-networking] inetutils: Fix deadlock in telnetd when cleanup] On 15.07.16 (Thu 10:41) Rongqing Li wrote:

> 
> 
> On 2015年07月16日 00:06, Joe MacDonald wrote:
> >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.
> 
> 
> Ok, please drop it;
> 
> Our customer reported a telnetd deadlock issue on our old product,
> And Wang fixed it by porting this patch; but I can not reproduce it
> whether in old or new product.

Dropped, thanks for the clarification, Roy.

-J.

> 
> -Roy
> 
> >
> >[[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/20150716/cfe59171/attachment-0002.sig>


More information about the Openembedded-devel mailing list