summaryrefslogtreecommitdiff
path: root/usr.sbin/lpr
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2002-06-13 06:48:41 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2002-06-13 06:48:41 +0000
commit07ad6ff1c450d29d89afb16eadc39ecbf842365e (patch)
tree7216a440404f1eafa0ed541f72d8e30b975759d5 /usr.sbin/lpr
parenta965e01bad29a9ba78e1b2d29a39b46bd2d8a3b4 (diff)
Fixed some lpd bugs while on the plane from Calgary:
o mark fatal() as __dead o add SIGINT to the signal mask when installing abort() as a handler. We can end up in abortpr() due to several different signals and since abortpr() kill()s itself with SIGINT we need to explicately protect against the current process receiving SIGINT while in abortpr() o Don't leak the lock fd to children spawned by lpd o Close the lock file (and thus unlocke immediately in abortpr(). Otherwise, if there is an output filter the lock file only gets closed after we finish waiting for the output filter to die. This causes a race condition in lprm such that the per-printer daemon does not get restarted when lprm kills the active job (noticed during c2k2 with the mp3 printer spool ;-) o Open the printcap file with privs raised just in case it is not world-readable.
Diffstat (limited to 'usr.sbin/lpr')
-rw-r--r--usr.sbin/lpr/common_source/common.c6
-rw-r--r--usr.sbin/lpr/common_source/lp.h4
-rw-r--r--usr.sbin/lpr/lpd/printjob.c46
3 files changed, 37 insertions, 19 deletions
diff --git a/usr.sbin/lpr/common_source/common.c b/usr.sbin/lpr/common_source/common.c
index 5f6576627d6..a0723a429bf 100644
--- a/usr.sbin/lpr/common_source/common.c
+++ b/usr.sbin/lpr/common_source/common.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: common.c,v 1.22 2002/06/09 03:56:28 millert Exp $ */
+/* $OpenBSD: common.c,v 1.23 2002/06/13 06:48:40 millert Exp $ */
/* $NetBSD: common.c,v 1.21 2000/08/09 14:28:50 itojun Exp $ */
/*
@@ -43,7 +43,7 @@
#if 0
static const char sccsid[] = "@(#)common.c 8.5 (Berkeley) 4/28/95";
#else
-static const char rcsid[] = "$OpenBSD: common.c,v 1.22 2002/06/09 03:56:28 millert Exp $";
+static const char rcsid[] = "$OpenBSD: common.c,v 1.23 2002/06/13 06:48:40 millert Exp $";
#endif
#endif /* not lint */
@@ -434,7 +434,7 @@ delay(int n)
(void) select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &tdelay);
}
-void
+__dead void
fatal(const char *msg, ...)
{
extern char *__progname;
diff --git a/usr.sbin/lpr/common_source/lp.h b/usr.sbin/lpr/common_source/lp.h
index 98ffc67cca8..3c117b3566a 100644
--- a/usr.sbin/lpr/common_source/lp.h
+++ b/usr.sbin/lpr/common_source/lp.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: lp.h,v 1.12 2002/06/09 03:56:28 millert Exp $ */
+/* $OpenBSD: lp.h,v 1.13 2002/06/13 06:48:40 millert Exp $ */
/* $NetBSD: lp.h,v 1.14 2000/04/16 14:43:58 mrg Exp $ */
/*
@@ -132,7 +132,7 @@ char *checkremote(void);
int chk(char *);
void displayq(int);
void dump(char *, char *, int);
-void fatal(const char *, ...)
+__dead void fatal(const char *, ...)
__attribute__((__format__(__printf__, 1, 2)));
int getline(FILE *);
int getport(char *, int);
diff --git a/usr.sbin/lpr/lpd/printjob.c b/usr.sbin/lpr/lpd/printjob.c
index 6efe8e00006..306eba7dd37 100644
--- a/usr.sbin/lpr/lpd/printjob.c
+++ b/usr.sbin/lpr/lpd/printjob.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: printjob.c,v 1.34 2002/06/08 23:23:24 millert Exp $ */
+/* $OpenBSD: printjob.c,v 1.35 2002/06/13 06:48:40 millert Exp $ */
/* $NetBSD: printjob.c,v 1.31 2002/01/21 14:42:30 wiz Exp $ */
/*
@@ -145,6 +145,7 @@ printjob(void)
struct stat stb;
struct queue *q, **qp;
struct queue **queue;
+ struct sigaction sa;
int i, fd, nitems;
off_t pidoff;
int errcnt, count = 0;
@@ -164,14 +165,21 @@ printjob(void)
syslog(LOG_ERR, "dup2: %m");
exit(1);
}
- close(fd);
+ (void)close(fd);
}
pid = getpid(); /* for use with lprm */
setpgrp(0, pid);
- signal(SIGHUP, abortpr);
- signal(SIGINT, abortpr);
- signal(SIGQUIT, abortpr);
- signal(SIGTERM, abortpr);
+
+ /* we add SIGINT to the mask so abortpr() doesn't kill itself */
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = abortpr;
+ sa.sa_flags = SA_RESTART;
+ sigemptyset(&sa.sa_mask);
+ sigaddset(&sa.sa_mask, SIGINT);
+ sigaction(SIGHUP, &sa, NULL);
+ sigaction(SIGINT, &sa, NULL);
+ sigaction(SIGQUIT, &sa, NULL);
+ sigaction(SIGTERM, &sa, NULL);
/* so we can use short form file names */
if (chdir(SD) < 0) {
@@ -348,7 +356,7 @@ printit(char *file)
if (fd < 0 || (cfp = fdopen(fd, "r")) == NULL) {
syslog(LOG_INFO, "%s: %s: %m", printer, file);
if (fd >= 0)
- close(fd);
+ (void)close(fd);
return(OK);
}
/*
@@ -755,7 +763,7 @@ start:
if (fd >= 0) {
while ((nread = read(fd, buf, sizeof(buf))) > 0)
(void)write(STDERR_FILENO, buf, nread);
- close(fd);
+ (void)close(fd);
}
if (!WIFEXITED(status)) {
@@ -1182,6 +1190,7 @@ dofork(int action)
* Child should run as daemon instead of root
*/
if (pid == 0) {
+ (void)close(lfd);
PRIV_START;
pw = getpwuid(DU);
if (pw == 0) {
@@ -1216,8 +1225,9 @@ dofork(int action)
static void
abortpr(int signo)
{
+ (void)close(lfd);
(void)unlink(tempfile);
- kill(0, SIGINT);
+ (void)kill(0, SIGINT);
if (ofilter > 0)
kill(ofilter, SIGCONT);
while (wait(NULL) > 0)
@@ -1231,14 +1241,22 @@ init(void)
int status;
char *s;
- if ((status = cgetent(&bp, printcapdb, printer)) == -2) {
- syslog(LOG_ERR, "can't open printer description file");
- exit(1);
- } else if (status == -1) {
+ PRIV_START;
+ status = cgetent(&bp, printcapdb, printer);
+ PRIV_END;
+
+ switch (status) {
+ case -1:
syslog(LOG_ERR, "unknown printer: %s", printer);
exit(1);
- } else if (status == -3)
+ case -2:
+ syslog(LOG_ERR, "can't open printer description file");
+ exit(1);
+ case -3:
fatal("potential reference loop detected in printcap file");
+ default:
+ break;
+ }
if (cgetstr(bp, DEFLP, &LP) == -1)
LP = _PATH_DEFDEVLP;