Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 25 May 2026 17:03:06 +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-main@FreeBSD.org
Subject:   git: f2c7c5f94803 - main - lpd: Avoid buffer overflow when sending a job
Message-ID:  <6a1480ca.382ec.4d1bc28@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by des:

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

commit f2c7c5f94803b67a9a6af625d4fc8882d2afda6c
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-25 16:52:16 +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
---
 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 1c6736097492..0e86e8de8fb9 100644
--- a/usr.sbin/lpr/lpd/printjob.c
+++ b/usr.sbin/lpr/lpd/printjob.c
@@ -68,8 +68,12 @@
 
 /*
  * 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
@@ -640,7 +644,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);
@@ -1127,13 +1131,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') {
@@ -1157,8 +1166,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?6a1480ca.382ec.4d1bc28>