diff --git a/csu/init-first.c b/csu/init-first.c index b3bacdd..751fc5a 100644 --- a/csu/init-first.c +++ b/csu/init-first.c @@ -39,6 +39,92 @@ int __libc_argc attribute_hidden; char **__libc_argv attribute_hidden; +#include +#include +#include +#include + +static void +__libc_check_sigpipe (const char *argv0) +{ + static const int sigs[] = { SIGPIPE, SIGTERM, SIGALRM, 9 }; + const int *sigp; + int sig; + struct sigaction sa; + sigset_t mask; + int r; + const char *oddity; + + sig = 0; + r = sigprocmask(SIG_UNBLOCK, 0, &mask); + if (r) { oddity = strerror(errno); goto bad; } + + for (sigp = sigs; (sig = *sigp); sigp++) { + r = sigaction(SIGPIPE, 0, &sa); + if (r) { oddity = strerror(errno); goto bad; } + if (sa.sa_handler == SIG_IGN) { oddity = "SIG_IGN"; goto bad; } + if (sigismember(&mask, sig)) { oddity = "blocked"; goto bad; } + } + return; + + bad:; + int logfd = -1; + FILE *logf = 0; + + logfd = open("/var/log/exec-sigignblock.log", O_APPEND|O_WRONLY); + if (logfd < 0) + if (errno == ENOENT || errno == EACCES || errno == EPERM) + return; + + logf = fdopen(logfd, "a"); + if (!logf) goto fail; + logfd = -1; /* eaten by fdopen */ + + unsigned long ourpid = getpid(); + unsigned long ppid = getppid(); + char parentbuf[100]; + + snprintf(parentbuf, sizeof(parentbuf), "/proc/%lu/exe", ppid); + r = readlink(parentbuf, parentbuf, sizeof(parentbuf)-1); + if (r < 0) { + const char *m = strerror(errno); + strncpy(parentbuf, m, sizeof(parentbuf)-1); + parentbuf[sizeof(parentbuf)-1] = 0; + } else if (r == 0) { + strcpy(parentbuf, "\"\""); + } else { + parentbuf[r] = 0; + } + + time_t now; + now = time(NULL); + if (now == (time_t)-1) { errno = EIO; goto fail; } + + struct tm *gmt = gmtime(&now); + if (!gmt) goto fail; + + r = fprintf(logf, "%04d-%02d-%02d %02d:%02d:%02d UTC:" + "%s[%lu] execd oddly (parent %s[%lu]): %s: %s\n", + gmt->tm_year+1900, gmt->tm_mon, gmt->tm_mday, + gmt->tm_hour, gmt->tm_min, gmt->tm_sec, + argv0, ourpid, + parentbuf, ppid, + sig ? strsignal(sig) : "sigprocmask", oddity); + if (r < 0) goto fail; + + r = fclose(logf); + logf = 0; + if (r) goto fail; + + return; + + fail: + perror("__libc_check_sigpipe report oddity"); + if (logf) fclose(logf); + if (logfd>=0) close(logfd); + return; +} + void __libc_init_first (int argc, char **argv, char **envp) { @@ -96,6 +182,8 @@ _init (int argc, char **argv, char **envp) #if defined SHARED && !defined NO_CTORS_DTORS_SECTIONS __libc_global_ctors (); #endif + + __libc_check_sigpipe (argv[0]); } /* This function is defined here so that if this file ever gets into diff --git a/debian/changelog b/debian/changelog index f552f26..33a6254 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +glibc (2.22-7+iwj) UNRELEASED; urgency=medium + + * SIGPIPE tracking + + -- Ian Jackson Sun, 08 May 2016 12:43:46 +0100 + glibc (2.22-7) unstable; urgency=medium [ Samuel Thibault ] diff --git a/debian/shlibs-add-udebs b/debian/shlibs-add-udebs old mode 100644 new mode 100755