The OpenNET Project
 
Search (keywords):  SOFT ARTICLES TIPS & TRICKS SECURITY
LINKS NEWS MAN DOCUMENTATION


SECURITY: lpr


<< Previous INDEX Search src Set bookmark Go to bookmark Next >>
Date: Fri, 8 Jan 1999 16:57:57 +0000 (GMT)
From: Chris Evans <chris@ferret.lmh.ox.ac.uk>
To: security-audit@ferret.lmh.ox.ac.uk
Subject: SECURITY: lpr


Hi.

Sorry to interrupt your exciting discussions about web pages with a
message discussion auditing.

Anyway appended below is a patch relative to the latest lpr version
shipped by RedHat. The fixes below are largely based upon OpenBSD patches
to lpr.

The patch should hopefully illustrate the mess lpr was in. Overflows a
plenty, but by luck all the serious ones not on the stack.

I post the patch to show that lpr is probably still in need of further
audit. You are invited to give it a prod, especially if your forte is file
handling - lpr is a mess of linking, opening, stating, unlinking... often
with euid==root.

Hopefully the work below will make it into an update soon as a "first
round" of lpr fixes.

Happy hacking
Chris

diff -rubB lpr-rhorig/lpr-0.33/common_source/common.c lpr-chris/lpr-0.33/common_source/common.c
--- lpr-rhorig/lpr-0.33/common_source/common.c	Tue Dec 22 22:30:52 1998
+++ lpr-chris/lpr-0.33/common_source/common.c	Mon Jan  4 21:35:34 1999
@@ -85,7 +85,7 @@
 char	*bp = pbuf;	/* pointer into pbuf for pgetent() */
 char	*name;		/* program name */
 char	*printer;	/* printer name */
-char	host[1024];	/* host machine name */
+char	host[MAXHOSTNAMELEN];	/* host machine name */
 char	*from = host;	/* client's machine name */
 int	sendtorem;	/* are we sending to a remote? */
 
@@ -114,6 +114,9 @@
 	if (sp == NULL)
 		fatal("printer/tcp: unknown service");
 	bzero((char *)&sin, sizeof(sin));
+	if (hp->h_length > sizeof(sin.sin_addr)) {
+		hp->h_length = sizeof(sin.sin_addr);
+	}
 	bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length);
 	sin.sin_family = hp->h_addrtype;
 	sin.sin_port = sp->s_port;
@@ -155,14 +158,14 @@
 	register char *lp = line;
 	register c;
 
-	while ((c = getc(cfp)) != '\n') {
+	while ((c = getc(cfp)) != '\n' && linel+1 < sizeof(line)) {
 		if (c == EOF)
 			return(0);
 		if (c == '\t') {
 			do {
 				*lp++ = ' ';
 				linel++;
-			} while ((linel & 07) != 0);
+			} while ((linel & 07) != 0 && linel+1 < sizeof(line));
 			continue;
 		}
 		*lp++ = c;
@@ -268,7 +271,7 @@
 		name[sizeof(name)-1] = '\0';
 		hp = gethostbyname(name);
 		if (hp == (struct hostent *) NULL) {
-		    (void) sprintf(errbuf,
+		    (void) snprintf(errbuf, sizeof(errbuf),
 			"unable to get official name for local machine %s",
 			name);
 		    return errbuf;
@@ -277,7 +280,7 @@
 		/* get the official name of RM */
 		hp = gethostbyname(RM);
 		if (hp == (struct hostent *) NULL) {
-		    (void) sprintf(errbuf,
+		    (void) snprintf(errbuf, sizeof(errbuf),
 			"unable to get official name for remote machine %s",
 			RM);
 		    return errbuf;
diff -rubB lpr-rhorig/lpr-0.33/common_source/displayq.c lpr-chris/lpr-0.33/common_source/displayq.c
--- lpr-rhorig/lpr-0.33/common_source/displayq.c	Tue Dec 22 22:30:52 1998
+++ lpr-chris/lpr-0.33/common_source/displayq.c	Mon Jan  4 22:12:14 1999
@@ -192,16 +192,25 @@
 	 */
 	if (nitems)
 		putchar('\n');
-	(void) sprintf(line, "%c%s", format + '\3', RP);
+	(void) snprintf(line, sizeof(line), "%c%s", format + '\3', RP);
 	cp = line;
-	for (i = 0; i < requests; i++) {
 		cp += strlen(cp);
-		(void) sprintf(cp, " %d", requ[i]);
+	for (i = 0; i < requests; i++) {
+		char numbuf[32];
+		sprintf(numbuf, " %d\0", requ[i]);
+		if (cp + strlen(numbuf) > line + sizeof(line)-2) {
+			break;
+		}
+		(void) strcpy(cp, numbuf);
+		cp += strlen(numbuf);
 	}
 	for (i = 0; i < users; i++) {
-		cp += strlen(cp);
+		if (cp + strlen(user[i]) > line + sizeof(line)-3) {
+			break;
+		}
 		*cp++ = ' ';
 		(void) strcpy(cp, user[i]);
+		cp += strlen(cp);
 	}
 	strcat(line, "\n");
 	fd = getport(RM);
@@ -286,8 +295,10 @@
 		default: /* some format specifer and file name? */
 			if (line[0] < 'a' || line[0] > 'z')
 				continue;
-			if (j == 0 || strcmp(file, line+1) != 0)
-				(void) strcpy(file, line+1);
+			if (j == 0 || strcmp(file, line+1) != 0) {
+				(void) strncpy(file, line+1, sizeof(file)-1);
+				file[sizeof(file)-1] = '\0';
+			}
 			j++;
 			continue;
 		case 'N':
diff -rubB lpr-rhorig/lpr-0.33/common_source/lp.h lpr-chris/lpr-0.33/common_source/lp.h
--- lpr-rhorig/lpr-0.33/common_source/lp.h	Tue Dec 22 22:30:52 1998
+++ lpr-chris/lpr-0.33/common_source/lp.h	Mon Jan  4 22:17:27 1999
@@ -100,7 +100,7 @@
 extern char	*bp;		/* pointer into ebuf for pgetent() */
 extern char	*name;		/* program name */
 extern char	*printer;	/* printer name */
-extern char	host[1024];	/* host machine name */
+extern char	host[MAXHOSTNAMELEN];	/* host machine name */
 extern char	*from;		/* client's machine name */
 extern int	sendtorem;	/* are we sending to a remote? */
 extern int	errno;
diff -rubB lpr-rhorig/lpr-0.33/common_source/rmjob.c lpr-chris/lpr-0.33/common_source/rmjob.c
--- lpr-rhorig/lpr-0.33/common_source/rmjob.c	Tue Dec 22 22:30:52 1998
+++ lpr-chris/lpr-0.33/common_source/rmjob.c	Fri Jan  8 00:52:07 1999
@@ -329,24 +329,24 @@
 	char *user;
 {
 	struct passwd	*pw;
-	uid_t		euid = geteuid();
-	gid_t		egid = getegid();
+	uid_t		fsuid = geteuid();
+	gid_t		fsgid = getegid();
 	int		ret;
 
-	if (file[0] != '/')
+	if (file[0] != '/' && (strstr(file, "..") == NULL))
 		return unlink(file);	/* unlink file in spool directory */
 
 	if (checkfromremote(host))      /* can't unlink file on remote host! */
 		return 0;
 
-	if (euid || !user[0]
-	 || (pw = getpwnam(user)) == NULL
-	 || setegid(pw->pw_gid) < 0 || seteuid(pw->pw_uid) < 0)
-		return -1;
+	/* Shouldn't really assume success */
+	setfsuid(getuid());
+	setfsgid(getgid());
 
 	ret = unlink(file);
-	if (seteuid(euid) < 0 || setegid(egid) < 0)
-		fatal("Couldn't reset effective uid/gid after unlink()");
+
+	setfsuid(fsuid);
+	setfsgid(fsgid);
 
 	return ret;
 }
diff -rubB lpr-rhorig/lpr-0.33/common_source/startdaemon.c lpr-chris/lpr-0.33/common_source/startdaemon.c
--- lpr-rhorig/lpr-0.33/common_source/startdaemon.c	Tue Dec 22 22:30:52 1998
+++ lpr-chris/lpr-0.33/common_source/startdaemon.c	Thu Jan  7 22:49:09 1999
@@ -64,7 +64,7 @@
 		(void) close(s);
 		return(0);
 	}
-	(void) sprintf(buf, "\1%s\n", printer);
+	snprintf(buf, sizeof(buf), "\1%s\n", printer);
 	n = strlen(buf);
 	if (write(s, buf, n) != n) {
 		perr("write");
diff -rubB lpr-rhorig/lpr-0.33/lpc/cmds.c lpr-chris/lpr-0.33/lpc/cmds.c
--- lpr-rhorig/lpr-0.33/lpc/cmds.c	Tue Dec 22 22:30:52 1998
+++ lpr-chris/lpr-0.33/lpc/cmds.c	Fri Jan  8 00:50:03 1999
@@ -63,7 +63,7 @@
 		while (getprent(line) > 0) {
 			cp1 = prbuf;
 			cp2 = line;
-			while ((c = *cp2++) && c != '|' && c != ':')
+			while ((c = *cp2++) && c != '|' && c != ':' && cp1 - prbuf < sizeof(prbuf))
 				*cp1++ = c;
 			*cp1 = '\0';
 			abortpr(1);
@@ -94,7 +94,7 @@
 		SD = _PATH_DEFSPOOL;
 	if ((LO = pgetstr("lo", &bp)) == NULL)
 		LO = DEFLOCK;
-	(void) sprintf(line, "%s/%s", SD, LO);
+	(void) snprintf(line, sizeof(line), "%s/%s", SD, LO);
 	printf("%s:\n", printer);
 
 	/*
@@ -154,7 +154,7 @@
 	bp = pbuf;
 	if ((ST = pgetstr("st", &bp)) == NULL)
 		ST = DEFSTAT;
-	(void) sprintf(statfile, "%s/%s", SD, ST);
+	(void) snprintf(statfile, sizeof(statfile), "%s/%s", SD, ST);
 	umask(0);
 	fd = open(statfile, O_WRONLY|O_CREAT, 0664);
 	if (fd < 0 || flock(fd, LOCK_EX) < 0) {
@@ -188,7 +188,7 @@
 		while (getprent(line) > 0) {
 			cp1 = prbuf;
 			cp2 = line;
-			while ((c = *cp2++) && c != '|' && c != ':')
+			while ((c = *cp2++) && c != '|' && c != ':' && cp1 - prbuf < sizeof(prbuf))
 				*cp1++ = c;
 			*cp1 = '\0';
 			cleanpr();
@@ -255,7 +255,7 @@
 		SD = _PATH_DEFSPOOL;
 	printf("%s:\n", printer);
 
-	for (lp = line, cp = SD; *lp++ = *cp++; )
+	for (lp = line, cp = SD; (lp-line)<sizeof(line) && (*lp++ = *cp++); )
 		;
 	lp[-1] = '/';
 
@@ -279,7 +279,8 @@
 				n++;
 			}
 			if (n == 0) {
-				strcpy(lp, cp);
+				strncpy(lp, cp, sizeof(line)-strlen(line)-1);
+				line[sizeof(line)-1] = '\0';
 				unlinkf(line);
 			}
 		} else {
@@ -288,7 +289,8 @@
 			 * been skipped above) or a tf file (which can always
 			 * be removed).
 			 */
-			strcpy(lp, cp);
+			strncpy(lp, cp, sizeof(line)-strlen(line)-1);
+			line[sizeof(line)-1] = '\0';
 			unlinkf(line);
 		}
      	} while (++i < nitems);
@@ -322,7 +324,7 @@
 		while (getprent(line) > 0) {
 			cp1 = prbuf;
 			cp2 = line;
-			while ((c = *cp2++) && c != '|' && c != ':')
+			while ((c = *cp2++) && c != '|' && c != ':' && cp1-prbuf < sizeof(prbuf))
 				*cp1++ = c;
 			*cp1 = '\0';
 			enablepr();
@@ -351,7 +353,7 @@
 		SD = _PATH_DEFSPOOL;
 	if ((LO = pgetstr("lo", &bp)) == NULL)
 		LO = DEFLOCK;
-	(void) sprintf(line, "%s/%s", SD, LO);
+	(void) snprintf(line, sizeof(line), "%s/%s", SD, LO);
 	printf("%s:\n", printer);
 
 	/*
@@ -384,7 +386,7 @@
 		while (getprent(line) > 0) {
 			cp1 = prbuf;
 			cp2 = line;
-			while ((c = *cp2++) && c != '|' && c != ':')
+			while ((c = *cp2++) && c != '|' && c != ':' && cp1-prbuf < sizeof(prbuf))
 				*cp1++ = c;
 			*cp1 = '\0';
 			disablepr();
@@ -414,7 +416,7 @@
 		SD = _PATH_DEFSPOOL;
 	if ((LO = pgetstr("lo", &bp)) == NULL)
 		LO = DEFLOCK;
-	(void) sprintf(line, "%s/%s", SD, LO);
+	(void) snprintf(line, sizeof(line), "%s/%s", SD, LO);
 	printf("%s:\n", printer);
 	/*
 	 * Turn on the group execute bit of the lock file to disable queuing.
@@ -456,7 +458,7 @@
 		while (getprent(line) > 0) {
 			cp1 = prbuf;
 			cp2 = line;
-			while ((c = *cp2++) && c != '|' && c != ':')
+			while ((c = *cp2++) && c != '|' && c != ':' && cp1-prbuf < sizeof(prbuf))
 				*cp1++ = c;
 			*cp1 = '\0';
 			putmsg(argc - 2, argv + 2);
@@ -494,7 +496,7 @@
 	 * Turn on the group execute bit of the lock file to disable queuing and
 	 * turn on the owner execute bit of the lock file to disable printing.
 	 */
-	(void) sprintf(line, "%s/%s", SD, LO);
+	(void) snprintf(line, sizeof(line), "%s/%s", SD, LO);
 	if (stat(line, &stbuf) >= 0) {
 		if (chmod(line, (stbuf.st_mode & 0777) | 0110) < 0)
 			printf("\tcannot disable queuing\n");
@@ -513,7 +515,7 @@
 	/*
 	 * Write the message into the status file.
 	 */
-	(void) sprintf(line, "%s/%s", SD, ST);
+	(void) snprintf(line, sizeof(line), "%s/%s", SD, ST);
 	fd = open(line, O_WRONLY|O_CREAT, 0664);
 	if (fd < 0 || flock(fd, LOCK_EX) < 0) {
 		printf("\tcannot create status file\n");
@@ -528,7 +530,7 @@
 	cp1 = buf;
 	while (--argc >= 0) {
 		cp2 = *argv++;
-		while (*cp1++ = *cp2++)
+		while ((cp1-buf) < sizeof(buf) && (*cp1++ = *cp2++))
 			;
 		cp1[-1] = ' ';
 	}
@@ -566,7 +568,7 @@
 		while (getprent(line) > 0) {
 			cp1 = prbuf;
 			cp2 = line;
-			while ((c = *cp2++) && c != '|' && c != ':')
+			while ((c = *cp2++) && c != '|' && c != ':' && cp1-prbuf < sizeof(prbuf))
 				*cp1++ = c;
 			*cp1 = '\0';
 			abortpr(0);
@@ -607,7 +609,7 @@
 		while (getprent(line) > 0) {
 			cp1 = prbuf;
 			cp2 = line;
-			while ((c = *cp2++) && c != '|' && c != ':')
+			while ((c = *cp2++) && c != '|' && c != ':' && cp1-prbuf < sizeof(prbuf))
 				*cp1++ = c;
 			*cp1 = '\0';
 			startpr(1);
@@ -636,7 +638,7 @@
 		SD = _PATH_DEFSPOOL;
 	if ((LO = pgetstr("lo", &bp)) == NULL)
 		LO = DEFLOCK;
-	(void) sprintf(line, "%s/%s", SD, LO);
+	(void) snprintf(line, sizeof(line), "%s/%s", SD, LO);
 	printf("%s:\n", printer);
 
 	/*
@@ -669,7 +671,7 @@
 		while (getprent(line) > 0) {
 			cp1 = prbuf;
 			cp2 = line;
-			while ((c = *cp2++) && c != '|' && c != ':')
+			while ((c = *cp2++) && c != '|' && c != ':' && cp1-prbuf < sizeof(prbuf))
 				*cp1++ = c;
 			*cp1 = '\0';
 			prstat();
@@ -707,7 +709,7 @@
 	if ((ST = pgetstr("st", &bp)) == NULL)
 		ST = DEFSTAT;
 	printf("%s:\n", printer);
-	(void) sprintf(line, "%s/%s", SD, LO);
+	(void) snprintf(line, sizeof(line), "%s/%s", SD, LO);
 	if (stat(line, &stbuf) >= 0) {
 		printf("\tqueuing is %s\n",
 			(stbuf.st_mode & 010) ? "disabled" : "enabled");
@@ -741,7 +743,7 @@
 	}
 	(void) close(fd);
 	putchar('\t');
-	(void) sprintf(line, "%s/%s", SD, ST);
+	(void) snprintf(line, sizeof(line), "%s/%s", SD, ST);
 	fd = open(line, O_RDONLY);
 	if (fd >= 0) {
 		(void) flock(fd, LOCK_SH);
@@ -771,7 +773,7 @@
 		while (getprent(line) > 0) {
 			cp1 = prbuf;
 			cp2 = line;
-			while ((c = *cp2++) && c != '|' && c != ':')
+			while ((c = *cp2++) && c != '|' && c != ':' && cp1-prbuf < sizeof(prbuf))
 				*cp1++ = c;
 			*cp1 = '\0';
 			stoppr();
@@ -801,7 +803,7 @@
 		SD = _PATH_DEFSPOOL;
 	if ((LO = pgetstr("lo", &bp)) == NULL)
 		LO = DEFLOCK;
-	(void) sprintf(line, "%s/%s", SD, LO);
+	(void) snprintf(line, sizeof(line), "%s/%s", SD, LO);
 	printf("%s:\n", printer);
 
 	/*
@@ -996,7 +998,7 @@
 		while (getprent(line) > 0) {
 			cp1 = prbuf;
 			cp2 = line;
-			while ((c = *cp2++) && c != '|' && c != ':')
+			while ((c = *cp2++) && c != '|' && c != ':' && cp1-prbuf < sizeof(prbuf))
 				*cp1++ = c;
 			*cp1 = '\0';
 			startpr(2);
diff -rubB lpr-rhorig/lpr-0.33/lpc/lpc.c lpr-chris/lpr-0.33/lpc/lpc.c
--- lpr-rhorig/lpr-0.33/lpc/lpc.c	Tue Dec 22 22:30:52 1998
+++ lpr-chris/lpr-0.33/lpc/lpc.c	Thu Jan  7 23:21:28 1999
@@ -180,9 +180,10 @@
 {
 	register char *cp;
 	register char **argp = margv;
+	int n;
 
 	margc = 0;
-	for (cp = cmdline; *cp;) {
+	for (cp = cmdline; *cp && (cp - cmdline) < sizeof(cmdline) && n < 20; n++) {
 		while (isspace(*cp))
 			cp++;
 		if (*cp == '\0')
diff -rubB lpr-rhorig/lpr-0.33/lpd/lpd.c lpr-chris/lpr-0.33/lpd/lpd.c
--- lpr-rhorig/lpr-0.33/lpd/lpd.c	Tue Dec 22 22:30:52 1998
+++ lpr-chris/lpr-0.33/lpd/lpd.c	Thu Jan  7 23:28:06 1999
@@ -142,6 +142,7 @@
 	}
 #define	mask(s)	(1 << ((s) - 1))
 	omask = sigblock(mask(SIGHUP)|mask(SIGINT)|mask(SIGQUIT)|mask(SIGTERM));
+	umask(07);
 	signal(SIGHUP, mcleanup);
 	signal(SIGINT, mcleanup);
 	signal(SIGQUIT, mcleanup);
@@ -258,7 +259,7 @@
 int	requests;		/* # of spool requests */
 char	*person;		/* name of person doing lprm */
 
-char	fromb[257];		/* buffer for client's machine name */
+char	fromb[MAXHOSTNAMELEN];		/* buffer for client's machine name */
 char	cbuf[BUFSIZ];		/* command line buffer */
 char	*cmdnames[] = {
 	"null",
@@ -436,7 +437,8 @@
 		fatal("Host name for your address (%s) unknown",
 			inet_ntoa(f->sin_addr));
 
-	strcpy(fromb, hp->h_name);
+	strncpy(fromb, hp->h_name, sizeof(fromb)-1);
+	fromb[sizeof(fromb)-1] = '\0';
 	from = fromb;
 	if (!strcmp(from, host))
 		return;
diff -rubB lpr-rhorig/lpr-0.33/lpd/printjob.c lpr-chris/lpr-0.33/lpd/printjob.c
--- lpr-rhorig/lpr-0.33/lpd/printjob.c	Tue Dec 22 22:30:52 1998
+++ lpr-chris/lpr-0.33/lpd/printjob.c	Fri Jan  8 00:51:10 1999
@@ -73,7 +73,7 @@
 static int	 tof;		/* true if at top of form */
 
 static char	class[32];		/* classification field */
-static char	fromhost[256+1];		/* user's host machine */
+static char	fromhost[MAXHOSTNAMELEN];		/* user's host machine */
 				/* indentation size in static characters */
 static char	indent[10] = "-i0";
 static char	jobname[100];		/* job or file name */
@@ -941,7 +941,7 @@
 	}
 
 	while (getline(cfp))
-		if (line[0] == 'U' && !strchr(line+1, '/'))
+		if (line[0] == 'U' && strchr(line+1, '/') == NULL)
 			(void) unlinkfile(line+1, from, logname);
 	/*
 	 * clean-up in case another control file exists
@@ -980,7 +980,7 @@
 	if ((stb.st_mode & S_IFMT) == S_IFLNK && fstat(f, &stb) == 0 &&
 	    (stb.st_dev != fdev || stb.st_ino != fino))
 		return(ACCESS);
-	(void) sprintf(buf, "%c%d %s\n", type, stb.st_size, file);
+	(void) snprintf(buf, sizeof(buf), "%c%d %s\n", type, stb.st_size, file);
 	amt = strlen(buf);
 	for (i = 0;  ; i++) {
 		if (write(pfd, buf, amt) != amt ||
@@ -1461,7 +1461,7 @@
 			resp = -1;
 			pfd = getport(RM);
 			if (pfd >= 0) {
-				(void) sprintf(line, "\2%s\n", RP);
+				(void) snprintf(line, sizeof(line), "\2%s\n", RP);
 				n = strlen(line);
 				if (write(pfd, line, n) == n &&
 				    (resp = response()) == '\0')
diff -rubB lpr-rhorig/lpr-0.33/lpd/recvjob.c lpr-chris/lpr-0.33/lpd/recvjob.c
--- lpr-rhorig/lpr-0.33/lpd/recvjob.c	Tue Dec 22 22:30:52 1998
+++ lpr-chris/lpr-0.33/lpd/recvjob.c	Fri Jan  8 00:31:12 1999
@@ -120,7 +120,7 @@
 					frecverr("%s: Lost connection",printer);
 				return(nfiles);
 			}
-		} while (*cp++ != '\n');
+		} while (*cp++ != '\n' && (cp - line + 1) < sizeof(line));
 		*--cp = '\0';
 		cp = line;
 		switch (*cp++) {
@@ -140,9 +140,13 @@
 			 * something different than what gethostbyaddr()
 			 * returns
 			 */
-			strcpy(cp + 6, from);
-			strcpy(tfname, cp);
+			strncpy(cp + 6, from, sizeof(line) + line - cp - 7);
+			line[sizeof(line) - 1] = '\0';
+			strncpy(tfname, cp, sizeof(tfname) - 1);
+			tfname[sizeof(tfname)-1] = '\0';
 			tfname[0] = 't';
+			if (strchr(tfname, '/'))
+				frecverr("readjob: %s: illegal path name", tfname);
 			if (!chksize(size)) {
 				(void) write(1, "\2", 1);
 				continue;
@@ -168,7 +172,8 @@
 				(void) write(1, "\2", 1);
 				continue;
 			}
-			(void) strcpy(dfname, cp);
+			(void) strncpy(dfname, cp, sizeof(dfname)-1);
+			dfname[sizeof(dfname)-1] = '\0';
 			if (index(dfname, '/'))
 				frecverr("readjob: %s: illegal path name",
 					dfname);
@@ -220,6 +225,7 @@
 	if (err)
 		frecverr("%s: write error", file);
 	if (noresponse()) {		/* file sent had bad data in it */
+		if (strchr(file, '/') == NULL)
 		(void) unlink(file);
 		return(0);
 	}
@@ -286,15 +292,16 @@
 rcleanup()
 {
 
-	if (tfname[0])
+	if (tfname[0] && strchr(tfname, '/') == NULL)
 		(void) unlink(tfname);
-	if (dfname[0])
+	if (dfname[0] && strchr(dfname, '/') == NULL) {
 		do {
 			do
 				(void) unlink(dfname);
 			while (dfname[2]-- != 'A');
 			dfname[2] = 'z';
 		} while (dfname[0]-- != 'd');
+	}
 	dfname[0] = '\0';
 }
 
diff -rubB lpr-rhorig/lpr-0.33/lpr/lpr.c lpr-chris/lpr-0.33/lpr/lpr.c
--- lpr-rhorig/lpr-0.33/lpr/lpr.c	Tue Dec 22 22:30:52 1998
+++ lpr-chris/lpr-0.33/lpr/lpr.c	Fri Jan  8 00:52:34 1999
@@ -278,7 +278,7 @@
 	/*
 	 * Check to make sure queuing is enabled if userid is not root.
 	 */
-	(void) sprintf(buf, "%s/%s", SD, LO);
+	(void) snprintf(buf, sizeof(buf), "%s/%s", SD, LO);
 	if (userid && stat(buf, &stb) == 0 && (stb.st_mode & 010))
 		fatal("Printer queue is disabled");
 	/*
@@ -450,8 +450,8 @@
 			}
 			break;
 		}
-		strcat(buf, "/");
-		strcat(buf, file);
+		strncat(buf, "/", sizeof(buf) - strlen(buf) - 1);
+		strncat(buf, file, sizeof(buf) - strlen(buf) - 1);
 		file = buf;
 	}
 	return(symlink(file, dfname) ? NULL : file);
@@ -474,7 +474,7 @@
         }
 
 	*p1++ = c;
-	while ((c = *p2++) != '\0') {
+	while ((c = *p2++) != '\0' && len < sizeof(buf)) {
 		*p1++ = (c == '\n') ? ' ' : c;
 		len++;
 	}
@@ -679,7 +679,7 @@
 	register char *cp;
 	char buf[BUFSIZ];
 
-	(void) sprintf(buf, "%s/.seq", SD);
+	(void) snprintf(buf, sizeof(buf), "%s/.seq", SD);
 	if ((fd = open(buf, O_RDWR|O_CREAT, 0661)) < 0) {
 		printf("%s: cannot create %s\n", name, buf);
 		exit(1);

<< Previous INDEX Search src Set bookmark Go to bookmark Next >>



Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру