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) [email protected] wrote: > From: Li Wang <[email protected]> > > 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 <[email protected]> > Signed-off-by: Li Wang <[email protected]> > --- > .../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 <[email protected]> > +Signed-off-by: Li Wang <[email protected]> > +--- > + 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
signature.asc
Description: Digital signature
-- _______________________________________________ Openembedded-devel mailing list [email protected] http://lists.openembedded.org/mailman/listinfo/openembedded-devel
