From c3c9e5634124c50cfdfc5850596e07efbe564473 Mon Sep 17 00:00:00 2001 From: bluhm Date: Fri, 23 Oct 2015 14:06:55 +0000 Subject: [PATCH] Check that syslogd delays a blocking write to tty and that that all messages still appear on the tty. --- regress/usr.sbin/syslogd/args-default.pl | 2 +- .../usr.sbin/syslogd/args-tls-cafile-fake.pl | 2 +- regress/usr.sbin/syslogd/args-ttymsg-delay.pl | 33 +++++++++++++ regress/usr.sbin/syslogd/args-ttymsg-wall.pl | 5 +- regress/usr.sbin/syslogd/funcs.pl | 8 +++- regress/usr.sbin/syslogd/ttylog.c | 47 ++++++++++++++----- 6 files changed, 80 insertions(+), 17 deletions(-) create mode 100644 regress/usr.sbin/syslogd/args-ttymsg-delay.pl diff --git a/regress/usr.sbin/syslogd/args-default.pl b/regress/usr.sbin/syslogd/args-default.pl index ed5af7e6079..5341cda925d 100644 --- a/regress/usr.sbin/syslogd/args-default.pl +++ b/regress/usr.sbin/syslogd/args-default.pl @@ -3,7 +3,7 @@ # The syslogd writes it into a file and through a pipe and to tty. # The syslogd passes it via UDP to the loghost. # The server receives the message on its UDP socket. -# Find the message in client, file, pipe, syslogd, server log. +# Find the message in client, file, pipe, tty, syslogd, server log. use strict; use warnings; diff --git a/regress/usr.sbin/syslogd/args-tls-cafile-fake.pl b/regress/usr.sbin/syslogd/args-tls-cafile-fake.pl index 2c07c199159..53120aa3594 100644 --- a/regress/usr.sbin/syslogd/args-tls-cafile-fake.pl +++ b/regress/usr.sbin/syslogd/args-tls-cafile-fake.pl @@ -17,7 +17,7 @@ our %args = ( qr/Logging to FORWTLS \@tls:\/\/localhost:\d+/ => '>=4', qr/syslogd: loghost .* connection error: /. qr/handshake failed: error:.*/. - qr/RSA_EAY_PUBLIC_DECRYPT:data too large for modulus/ => 2, + qr/RSA_padding_check_PKCS1_type_1:block type is not 01/ => 2, get_testgrep() => 1, }, cacrt => "fake-ca.crt", diff --git a/regress/usr.sbin/syslogd/args-ttymsg-delay.pl b/regress/usr.sbin/syslogd/args-ttymsg-delay.pl new file mode 100644 index 00000000000..383247cf91c --- /dev/null +++ b/regress/usr.sbin/syslogd/args-ttymsg-delay.pl @@ -0,0 +1,33 @@ +# The client writes long messages to Sys::Syslog native method. +# The syslogd writes it into a file and through a pipe and to tty. +# The syslogd passes it via UDP to the loghost. +# The server receives the message on its UDP socket. +# Find the message in client, file, pipe, tty, syslogd, server log. +# Check that syslogd has logged that the tty blocked. + +use strict; +use warnings; +use Sys::Syslog qw(:macros); + +our %args = ( + client => { + func => sub { + my $self = shift; + write_lines($self, 2, 900); + write_log($self); + }, + }, + syslogd => { + loggrep => { + qr/ttymsg delayed write/ => '>=1', + }, + }, + tty => { + loggrep => { + qr/ 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ.* [12]$/ => 2, + get_testgrep() => 1, + }, + }, +); + +1; diff --git a/regress/usr.sbin/syslogd/args-ttymsg-wall.pl b/regress/usr.sbin/syslogd/args-ttymsg-wall.pl index 606d3183704..80b0a235c61 100644 --- a/regress/usr.sbin/syslogd/args-ttymsg-wall.pl +++ b/regress/usr.sbin/syslogd/args-ttymsg-wall.pl @@ -1,8 +1,11 @@ # The client writes a message to Sys::Syslog native method. +# The client writes an additional message with local5 and err. # The syslogd writes it into a file and through a pipe and to tty. +# The special message also goes to all users with wall *. # The syslogd passes it via UDP to the loghost. # The server receives the message on its UDP socket. -# Find the message in client, file, pipe, syslogd, server log. +# Find the message in client, file, pipe, tty, syslogd, server log. +# Check that the special message is in the tty log twice. use strict; use warnings; diff --git a/regress/usr.sbin/syslogd/funcs.pl b/regress/usr.sbin/syslogd/funcs.pl index fc706287c0d..881169eef44 100644 --- a/regress/usr.sbin/syslogd/funcs.pl +++ b/regress/usr.sbin/syslogd/funcs.pl @@ -1,4 +1,4 @@ -# $OpenBSD: funcs.pl,v 1.26 2015/10/19 20:16:09 bluhm Exp $ +# $OpenBSD: funcs.pl,v 1.27 2015/10/23 14:06:55 bluhm Exp $ # Copyright (c) 2010-2015 Alexander Bluhm # @@ -350,6 +350,12 @@ sub check_out { unless ($args{pipe}{nocheck}) { $r->loggrep("bytes transferred", 1) or sleep 1; } + unless ($args{tty}{nocheck}) { + open(my $fh, '<', $r->{outtty}) + or die "Open file $r->{outtty} for reading failed: $!"; + grep { qr/^logout/ } <$fh> or sleep 1; + close($fh); + } foreach my $name (qw(file pipe tty)) { next if $args{$name}{nocheck}; diff --git a/regress/usr.sbin/syslogd/ttylog.c b/regress/usr.sbin/syslogd/ttylog.c index d87d863202a..a099a545ef3 100644 --- a/regress/usr.sbin/syslogd/ttylog.c +++ b/regress/usr.sbin/syslogd/ttylog.c @@ -50,24 +50,35 @@ main(int argc, char *argv[]) { char buf[8192], ptyname[16], *username, *logfile; struct utmp utmp; + struct sigaction act; + sigset_t set; int mfd, sfd; ssize_t n; - int i; if (argc != 3) usage(); username = argv[1]; logfile = argv[2]; + sigemptyset(&set); + sigaddset(&set, SIGTERM); + sigaddset(&set, SIGIO); + if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) + err(1, "sigprocmask block init"); + if ((lg = fopen(logfile, "w")) == NULL) err(1, "fopen %s", logfile); if (setlinebuf(lg) != 0) err(1, "setlinebuf"); - if (signal(SIGTERM, terminate) == SIG_ERR) - err(1, "signal SIGTERM"); - if (signal(SIGINT, terminate) == SIG_ERR) - err(1, "signal SIGINT"); + memset(&act, 0, sizeof(act)); + act.sa_mask = set; + act.sa_flags = SA_RESTART; + act.sa_handler = terminate; + if (sigaction(SIGTERM, &act, NULL) == -1) + err(1, "sigaction SIGTERM"); + if (sigaction(SIGINT, &act, NULL) == -1) + err(1, "sigaction SIGINT"); if (openpty(&mfd, &sfd, ptyname, NULL, NULL) == -1) err(1, "openpty"); @@ -87,31 +98,41 @@ main(int argc, char *argv[]) login(&utmp); fprintf(lg, "login %s %s\n", username, tty); - if (signal(SIGIO, iostdin) == SIG_ERR) - err(1, "signal SIGIO"); + act.sa_handler = iostdin; + if (sigaction(SIGIO, &act, NULL) == -1) + err(1, "sigaction SIGIO"); if (setpgid(0, 0) == -1) err(1, "setpgid"); - i = getpid(); - if (fcntl(0, F_SETOWN, i) == -1 && - ioctl(0, SIOCSPGRP, &i) == -1) /* pipe(2) with F_SETOWN broken */ - err(1, "fcntl F_SETOWN, ioctl SIOCSPGRP"); + if (fcntl(0, F_SETOWN, getpid()) == -1) + err(1, "fcntl F_SETOWN"); if (fcntl(0, F_SETFL, O_ASYNC) == -1) err(1, "fcntl O_ASYNC"); - if (signal(SIGALRM, timeout) == SIG_ERR) - err(1, "signal SIGALRM"); + act.sa_handler = timeout; + if (sigaction(SIGALRM, &act, NULL) == -1) + err(1, "sigaction SIGALRM"); if (alarm(30) == (unsigned int)-1) err(1, "alarm"); fprintf(lg, "%s: started\n", getprogname()); + if (sigprocmask(SIG_UNBLOCK, &set, NULL) == -1) + err(1, "sigprocmask unblock init"); + + /* do not block signals during read, it has to be interrupted */ while ((n = read(mfd, buf, sizeof(buf))) > 0) { + if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) + err(1, "sigprocmask block write"); fprintf(lg, ">>> "); if (fwrite(buf, 1, n, lg) != (size_t)n) err(1, "fwrite %s", logfile); if (buf[n-1] != '\n') fprintf(lg, "\n"); + if (sigprocmask(SIG_UNBLOCK, &set, NULL) == -1) + err(1, "sigprocmask unblock write"); } + if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) + err(1, "sigprocmask block exit"); if (n < 0) err(1, "read %s", ptyname); fprintf(lg, "EOF %s\n", ptyname); -- 2.20.1