The branch main has been updated by des:

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

commit f2c7c5f94803b67a9a6af625d4fc8882d2afda6c
Author:     Dag-Erling Smørgrav <[email protected]>
AuthorDate: 2026-05-25 16:51:48 +0000
Commit:     Dag-Erling Smørgrav <[email protected]>
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 <[email protected]>
    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)

Reply via email to