Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 28 May 2026 08:27:30 +0000
From:      Dag-Erling=?utf-8?Q? Sm=C3=B8rg?=rav <des@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 7c11b5f0ecdb - stable/14 - lpd: Avoid buffer overflow when sending a job
Message-ID:  <6a17fc72.22c33.503ccaae@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch stable/14 has been updated by des:

URL: https://cgit.FreeBSD.org/src/commit/?id=7c11b5f0ecdb6e543882fb54ca81da6bc3ac3ebb

commit 7c11b5f0ecdb6e543882fb54ca81da6bc3ac3ebb
Author:     Dag-Erling Smørgrav <des@FreeBSD.org>
AuthorDate: 2026-05-25 16:51:48 +0000
Commit:     Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2026-05-28 08:27:12 +0000

    lpd: Avoid buffer overflow when sending a job
    
    When forwarding a print job to a remote server, we could overflow the
    command buffer if a control or data file had a very long name.
    
    MFC after:      1 week
    Reported by:    Joshua Rogers <joshua@joshua.hu>
    Reviewed by:    markj
    Differential Revision:  https://reviews.freebsd.org/D57184
    
    (cherry picked from commit f2c7c5f94803b67a9a6af625d4fc8882d2afda6c)
---
 usr.sbin/lpr/lpd/printjob.c | 31 ++++++++++++++++++++-----------
 1 file changed, 20 insertions(+), 11 deletions(-)

diff --git a/usr.sbin/lpr/lpd/printjob.c b/usr.sbin/lpr/lpd/printjob.c
index 79bc36aef13d..63d0101f6ff0 100644
--- a/usr.sbin/lpr/lpd/printjob.c
+++ b/usr.sbin/lpr/lpd/printjob.c
@@ -80,8 +80,12 @@ static char sccsid[] = "@(#)printjob.c	8.7 (Berkeley) 5/10/95";
 
 /*
  * The buffer size to use when reading/writing spool files.
+ * This is also used to compose commands for remote servers and therefore
+ * needs to be able to fit the longest command we could possibly send.
  */
-#define	SPL_BUFSIZ	BUFSIZ
+#define	SPL_BUFSIZ	(BUFSIZ * 2)
+_Static_assert(SPL_BUFSIZ > sizeof("x18446744073709551615 ") + PATH_MAX +
+    sizeof("_c2147483647 "), "SPL_BUFSIZ is too short");
 
 /*
  * Error tokens
@@ -652,7 +656,7 @@ print(struct printer *pp, int format, char *file)
 	if (pp->filters[LPF_INPUT] == NULL
 	    && (format == 'f' || format == 'l' || format == 'o')) {
 		pp->tof = 0;
-		while ((n = read(fi, buf, SPL_BUFSIZ)) > 0)
+		while ((n = read(fi, buf, sizeof(buf))) > 0)
 			if (write(ofd, buf, n) != n) {
 				(void) close(fi);
 				return (REPRINT);
@@ -1139,13 +1143,18 @@ sendfile(struct printer *pp, int type, char *file, char format, int copyreq)
 sendagain:
 	copycnt++;
 
-	if (copycnt < 2)
-		(void) sprintf(buf, "%c%" PRId64 " %s\n", type, stb.st_size,
-		    file);
-	else
-		(void) sprintf(buf, "%c%" PRId64 " %s_c%d\n", type, stb.st_size,
-		    file, copycnt);
-	amt = strlen(buf);
+	if (copycnt < 2) {
+		amt = snprintf(buf, sizeof(buf), "%c%" PRId64 " %s\n",
+		    type, stb.st_size, file);
+	} else {
+		amt = snprintf(buf, sizeof(buf), "%c%" PRId64 " %s_c%d\n",
+		    type, stb.st_size, file, copycnt);
+	}
+	if (amt >= sizeof(buf)) {
+		syslog(LOG_ERR, "%s: file name too long", file);
+		sfres = ERROR;
+		goto return_sfres;
+	}
 	for (i = 0;  ; i++) {
 		if (write(pfd, buf, amt) != amt ||
 		    (resp = response(pp)) < 0 || resp == '\1') {
@@ -1169,8 +1178,8 @@ sendagain:
 	 */
 	if (type == '\3')
 		trstat_init(pp, file, job_dfcnt);
-	for (i = 0; i < stb.st_size; i += SPL_BUFSIZ) {
-		amt = SPL_BUFSIZ;
+	for (i = 0; i < stb.st_size; i += sizeof(buf)) {
+		amt = sizeof(buf);
 		if (i + amt > stb.st_size)
 			amt = stb.st_size - i;
 		if (sizerr == 0 && read(sfd, buf, amt) != amt)


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a17fc72.22c33.503ccaae>