summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSoumya Sambu <soumya.sambu@windriver.com>2024-05-29 06:13:28 +0000
committerSteve Sakoman <steve@sakoman.com>2024-06-01 19:07:52 -0700
commitec87d3ca28273d5bb0d38d82566e4d1bca93e31a (patch)
tree00e54ca636126465d1ebe9408d78cf4237227808
parentb0b5da10e13fe264e34a60e82ab06139f7ba7fd5 (diff)
downloadpoky-ec87d3ca28273d5bb0d38d82566e4d1bca93e31a.tar.gz
util-linux: Fix CVE-2024-28085
wall in util-linux through 2.40, often installed with setgid tty permissions, allows escape sequences to be sent to other users' terminals through argv. (Specifically, escape sequences received from stdin are blocked, but escape sequences received from argv are not blocked.) There may be plausible scenarios where this leads to account takeover. CVE-2024-28085-0005 is the CVE fix and CVE-2024-28085-0001, CVE-2024-28085-0002, CVE-2024-28085-0003, CVE-2024-28085-0004 are dependent commits to fix the CVE. References: https://nvd.nist.gov/vuln/detail/CVE-2024-28085 (From OE-Core rev: 28d9f948536dfee2330e4cfd225c932d20d688f1) Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com> Signed-off-by: Steve Sakoman <steve@sakoman.com>
-rw-r--r--meta/recipes-core/util-linux/util-linux.inc5
-rw-r--r--meta/recipes-core/util-linux/util-linux/CVE-2024-28085-0001.patch202
-rw-r--r--meta/recipes-core/util-linux/util-linux/CVE-2024-28085-0002.patch172
-rw-r--r--meta/recipes-core/util-linux/util-linux/CVE-2024-28085-0003.patch223
-rw-r--r--meta/recipes-core/util-linux/util-linux/CVE-2024-28085-0004.patch36
-rw-r--r--meta/recipes-core/util-linux/util-linux/CVE-2024-28085-0005.patch34
6 files changed, 672 insertions, 0 deletions
diff --git a/meta/recipes-core/util-linux/util-linux.inc b/meta/recipes-core/util-linux/util-linux.inc
index 982ec669a2..f8841e6be0 100644
--- a/meta/recipes-core/util-linux/util-linux.inc
+++ b/meta/recipes-core/util-linux/util-linux.inc
@@ -35,6 +35,11 @@ SRC_URI = "${KERNELORG_MIRROR}/linux/utils/util-linux/v${MAJOR_VERSION}/util-lin
35 file://run-ptest \ 35 file://run-ptest \
36 file://display_testname_for_subtest.patch \ 36 file://display_testname_for_subtest.patch \
37 file://avoid_parallel_tests.patch \ 37 file://avoid_parallel_tests.patch \
38 file://CVE-2024-28085-0001.patch \
39 file://CVE-2024-28085-0002.patch \
40 file://CVE-2024-28085-0003.patch \
41 file://CVE-2024-28085-0004.patch \
42 file://CVE-2024-28085-0005.patch \
38 " 43 "
39 44
40SRC_URI[sha256sum] = "634e6916ad913366c3536b6468e7844769549b99a7b2bf80314de78ab5655b83" 45SRC_URI[sha256sum] = "634e6916ad913366c3536b6468e7844769549b99a7b2bf80314de78ab5655b83"
diff --git a/meta/recipes-core/util-linux/util-linux/CVE-2024-28085-0001.patch b/meta/recipes-core/util-linux/util-linux/CVE-2024-28085-0001.patch
new file mode 100644
index 0000000000..7ce2d6c567
--- /dev/null
+++ b/meta/recipes-core/util-linux/util-linux/CVE-2024-28085-0001.patch
@@ -0,0 +1,202 @@
1From 8a7b8456d1dc0e7ca557d1ac31f638986704757f Mon Sep 17 00:00:00 2001
2From: наб <nabijaczleweli@nabijaczleweli.xyz>
3Date: Wed Mar 15 16:16:31 2023 +0100
4Subject: [PATCH] write: correctly handle wide characters
5
6Do this by replacing fputc_careful() (notice that the description said
7it's locale-aware ‒ it very much is /not/), with a fputs_careful() which
8does the same thing, but if it were to output a byte in the \123 format,
9first it checks whether this byte starts a valid multibyte character.
10
11If it does, and that character is printable, write it verbatim.
12This means that
13 echo 'foo åäö ąęćźżń bar' | write nabijaczleweli pts/4
14instead of
15 foo \303\245\303\244\303\266
16 \304\205\304\231\304\207\305\272\305\274\305\204 bar
17yields
18 foo åäö ąęćźżń bar
19or, more realistically, from a message I got earlier today,
20 Filip powiedzia\305\202 \305\274e zap\305\202aci jutro
21becomes
22 Filip powiedział że zapłaci jutro
23
24Invalid/non-printable sequences get processed as before.
25
26Line reading in write must become getline() to avoid dealing with
27partial characters: for example on input consisting solely of
28ąęćźżń, where every {1} is an instance, the output would be
29 {42}ąęć\305\272żń{84}ąęćź\305\274ń{84}ąęćźż\305\204{39}
30with just fixed-512 fgets()
31
32Bug-Debian: https://bugs.debian.org/826596
33
34CVE: CVE-2024-28085
35
36Upstream-Status: Backport [https://github.com/util-linux/util-linux/commit/8a7b8456d1dc0e7ca557d1ac31f638986704757f]
37
38Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
39---
40 include/carefulputc.h | 62 +++++++++++++++++++++++++++++++------------
41 login-utils/last.c | 4 +--
42 term-utils/write.c | 25 +++++------------
43 3 files changed, 53 insertions(+), 38 deletions(-)
44
45diff --git a/include/carefulputc.h b/include/carefulputc.h
46index 66a0f15..2506614 100644
47--- a/include/carefulputc.h
48+++ b/include/carefulputc.h
49@@ -1,31 +1,59 @@
50 #ifndef UTIL_LINUX_CAREFULPUTC_H
51 #define UTIL_LINUX_CAREFULPUTC_H
52
53-/*
54- * A putc() for use in write and wall (that sometimes are sgid tty).
55- * It avoids control characters in our locale, and also ASCII control
56- * characters. Note that the locale of the recipient is unknown.
57-*/
58 #include <stdio.h>
59 #include <string.h>
60 #include <ctype.h>
61+#ifdef HAVE_WIDECHAR
62+#include <wctype.h>
63+#endif
64+#include <stdbool.h>
65
66 #include "cctype.h"
67
68-static inline int fputc_careful(int c, FILE *fp, const char fail)
69+/*
70+ * A puts() for use in write and wall (that sometimes are sgid tty).
71+ * It avoids control and invalid characters.
72+ * The locale of the recipient is nominally unknown,
73+ * but it's a solid bet that the encoding is compatible with the author's.
74+ */
75+static inline int fputs_careful(const char * s, FILE *fp, const char ctrl, bool cr_lf)
76 {
77- int ret;
78-
79- if (isprint(c) || c == '\a' || c == '\t' || c == '\r' || c == '\n')
80- ret = putc(c, fp);
81- else if (!c_isascii(c))
82- ret = fprintf(fp, "\\%3o", (unsigned char)c);
83- else {
84- ret = putc(fail, fp);
85- if (ret != EOF)
86- ret = putc(c ^ 0x40, fp);
87+ int ret = 0;
88+
89+ for (size_t slen = strlen(s); *s; ++s, --slen) {
90+ if (*s == '\n')
91+ ret = fputs(cr_lf ? "\r\n" : "\n", fp);
92+ else if (isprint(*s) || *s == '\a' || *s == '\t' || *s == '\r')
93+ ret = putc(*s, fp);
94+ else if (!c_isascii(*s)) {
95+#ifdef HAVE_WIDECHAR
96+ wchar_t w;
97+ size_t clen = mbtowc(&w, s, slen);
98+ switch(clen) {
99+ case (size_t)-2: // incomplete
100+ case (size_t)-1: // EILSEQ
101+ mbtowc(NULL, NULL, 0);
102+ nonprint:
103+ ret = fprintf(fp, "\\%3hho", *s);
104+ break;
105+ default:
106+ if(!iswprint(w))
107+ goto nonprint;
108+ ret = fwrite(s, 1, clen, fp);
109+ s += clen - 1;
110+ slen -= clen - 1;
111+ break;
112+ }
113+#else
114+ ret = fprintf(fp, "\\%3hho", *s);
115+#endif
116+ } else
117+ ret = fputs((char[]){ ctrl, *s ^ 0x40, '\0' }, fp);
118+ if (ret < 0)
119+ return EOF;
120 }
121- return (ret < 0) ? EOF : 0;
122+ return 0;
123 }
124
125 static inline void fputs_quoted_case(const char *data, FILE *out, int dir)
126diff --git a/login-utils/last.c b/login-utils/last.c
127index f3272ca..aacd1f6 100644
128--- a/login-utils/last.c
129+++ b/login-utils/last.c
130@@ -403,7 +403,6 @@ static int list(const struct last_control *ctl, struct utmpx *p, time_t logout_t
131 char final[512];
132 char utline[sizeof(p->ut_line) + 1];
133 char domain[256];
134- char *s;
135 int mins, hours, days;
136 int r, len;
137 struct last_timefmt *fmt;
138@@ -559,8 +558,7 @@ static int list(const struct last_control *ctl, struct utmpx *p, time_t logout_t
139 /*
140 * Print out "final" string safely.
141 */
142- for (s = final; *s; s++)
143- fputc_careful(*s, stdout, '*');
144+ fputs_careful(final, stdout, '*', false);
145
146 if (len < 0 || (size_t)len >= sizeof(final))
147 putchar('\n');
148diff --git a/term-utils/write.c b/term-utils/write.c
149index 50f18dc..710a58c 100644
150--- a/term-utils/write.c
151+++ b/term-utils/write.c
152@@ -223,21 +223,6 @@ static void signal_handler(int signo)
153 signal_received = signo;
154 }
155
156-/*
157- * write_line - like fputs(), but makes control characters visible and
158- * turns \n into \r\n.
159- */
160-static void write_line(char *s)
161-{
162- while (*s) {
163- const int c = *s++;
164-
165- if ((c == '\n' && fputc_careful('\r', stdout, '^') == EOF)
166- || fputc_careful(c, stdout, '^') == EOF)
167- err(EXIT_FAILURE, _("carefulputc failed"));
168- }
169-}
170-
171 /*
172 * do_write - actually make the connection
173 */
174@@ -247,7 +232,8 @@ static void do_write(const struct write_control *ctl)
175 struct passwd *pwd;
176 time_t now;
177 struct tm *tm;
178- char *host, line[512];
179+ char *host, *line = NULL;
180+ size_t linelen = 0;
181 struct sigaction sigact;
182
183 /* Determine our login name(s) before the we reopen() stdout */
184@@ -286,11 +272,14 @@ static void do_write(const struct write_control *ctl)
185 free(host);
186 printf("\r\n");
187
188- while (fgets(line, sizeof(line), stdin) != NULL) {
189+ while (getline(&line, &linelen, stdin) >= 0) {
190 if (signal_received)
191 break;
192- write_line(line);
193+
194+ if (fputs_careful(line, stdout, '^', true) == EOF)
195+ err(EXIT_FAILURE, _("carefulputc failed"));
196 }
197+ free(line);
198 printf("EOF\r\n");
199 }
200
201--
2022.40.0
diff --git a/meta/recipes-core/util-linux/util-linux/CVE-2024-28085-0002.patch b/meta/recipes-core/util-linux/util-linux/CVE-2024-28085-0002.patch
new file mode 100644
index 0000000000..1fceebbdb4
--- /dev/null
+++ b/meta/recipes-core/util-linux/util-linux/CVE-2024-28085-0002.patch
@@ -0,0 +1,172 @@
1From 27ee6446503af7ec0c2647704ca47ac4de3852ef Mon Sep 17 00:00:00 2001
2From: наб <nabijaczleweli@nabijaczleweli.xyz>
3Date: Wed, 15 Mar 2023 16:16:43 +0100
4Subject: [PATCH] wall: convert homebrew buffering to open_memstream()
5
6The struct buffer system duplicates a plethora of standard I/O
7functions (including a fork of fputc_careful())
8and adds a lot of complexity ‒ open_memstream() is standard,
9and fits perfectly into this niche
10
11CVE: CVE-2024-28085
12
13Upstream-Status: Backport [https://github.com/util-linux/util-linux/commit/27ee6446503af7ec0c2647704ca47ac4de3852ef]
14
15Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
16---
17 term-utils/wall.c | 95 ++++++++++-------------------------------------
18 1 file changed, 20 insertions(+), 75 deletions(-)
19
20diff --git a/term-utils/wall.c b/term-utils/wall.c
21index c601d3e..a51a928 100644
22--- a/term-utils/wall.c
23+++ b/term-utils/wall.c
24@@ -274,74 +274,22 @@ int main(int argc, char **argv)
25 exit(EXIT_SUCCESS);
26 }
27
28-struct buffer {
29- size_t sz;
30- size_t used;
31- char *data;
32-};
33-
34-static void buf_enlarge(struct buffer *bs, size_t len)
35+static void buf_putc_careful(FILE *fs, int c)
36 {
37- if (bs->sz == 0 || len > bs->sz - bs->used) {
38- bs->sz += len < 128 ? 128 : len;
39- bs->data = xrealloc(bs->data, bs->sz);
40- }
41-}
42-
43-static void buf_puts(struct buffer *bs, const char *s)
44-{
45- size_t len = strlen(s);
46-
47- buf_enlarge(bs, len + 1);
48- memcpy(bs->data + bs->used, s, len + 1);
49- bs->used += len;
50-}
51-
52-static void __attribute__((__format__ (__printf__, 2, 3)))
53- buf_printf(struct buffer *bs, const char *fmt, ...)
54-{
55- int rc;
56- va_list ap;
57- size_t limit;
58-
59- buf_enlarge(bs, 0); /* default size */
60- limit = bs->sz - bs->used;
61-
62- va_start(ap, fmt);
63- rc = vsnprintf(bs->data + bs->used, limit, fmt, ap);
64- va_end(ap);
65-
66- if (rc >= 0 && (size_t) rc >= limit) { /* not enough, enlarge */
67- buf_enlarge(bs, (size_t)rc + 1);
68- limit = bs->sz - bs->used;
69- va_start(ap, fmt);
70- rc = vsnprintf(bs->data + bs->used, limit, fmt, ap);
71- va_end(ap);
72- }
73-
74- if (rc > 0)
75- bs->used += rc;
76-}
77-
78-static void buf_putc_careful(struct buffer *bs, int c)
79-{
80- if (isprint(c) || c == '\a' || c == '\t' || c == '\r' || c == '\n') {
81- buf_enlarge(bs, 1);
82- bs->data[bs->used++] = c;
83- } else if (!c_isascii(c))
84- buf_printf(bs, "\\%3o", (unsigned char)c);
85- else {
86- char tmp[] = { '^', c ^ 0x40, '\0' };
87- buf_puts(bs, tmp);
88- }
89+ if (isprint(c) || c == '\a' || c == '\t' || c == '\r' || c == '\n')
90+ fputc(c, fs);
91+ else if (!c_isascii(c))
92+ fprintf(fs, "\\%3o", (unsigned char)c);
93+ else
94+ fputs((char[]){ '^', c ^ 0x40, '\0' }, fs);
95 }
96
97 static char *makemsg(char *fname, char **mvec, int mvecsz,
98 size_t *mbufsize, int print_banner)
99 {
100- struct buffer _bs = {.used = 0}, *bs = &_bs;
101 register int ch, cnt;
102- char *p, *lbuf;
103+ char *p, *lbuf, *retbuf;
104+ FILE * fs = open_memstream(&retbuf, mbufsize);
105 long line_max;
106
107 line_max = sysconf(_SC_LINE_MAX);
108@@ -379,15 +327,15 @@ static char *makemsg(char *fname, char **mvec, int mvecsz,
109 */
110 /* snprintf is not always available, but the sprintf's here
111 will not overflow as long as %d takes at most 100 chars */
112- buf_printf(bs, "\r%*s\r\n", TERM_WIDTH, " ");
113+ fprintf(fs, "\r%*s\r\n", TERM_WIDTH, " ");
114
115 snprintf(lbuf, line_max,
116 _("Broadcast message from %s@%s (%s) (%s):"),
117 whom, hostname, where, date);
118- buf_printf(bs, "%-*.*s\007\007\r\n", TERM_WIDTH, TERM_WIDTH, lbuf);
119+ fprintf(fs, "%-*.*s\007\007\r\n", TERM_WIDTH, TERM_WIDTH, lbuf);
120 free(hostname);
121 }
122- buf_printf(bs, "%*s\r\n", TERM_WIDTH, " ");
123+ fprintf(fs, "%*s\r\n", TERM_WIDTH, " ");
124
125 if (mvec) {
126 /*
127@@ -396,11 +344,11 @@ static char *makemsg(char *fname, char **mvec, int mvecsz,
128 int i;
129
130 for (i = 0; i < mvecsz; i++) {
131- buf_puts(bs, mvec[i]);
132+ fputs(mvec[i], fs);
133 if (i < mvecsz - 1)
134- buf_puts(bs, " ");
135+ fputc(' ', fs);
136 }
137- buf_puts(bs, "\r\n");
138+ fputs("\r\n", fs);
139 } else {
140 /*
141 * read message from <file>
142@@ -428,23 +376,20 @@ static char *makemsg(char *fname, char **mvec, int mvecsz,
143 while (fgets(lbuf, line_max, stdin)) {
144 for (cnt = 0, p = lbuf; (ch = *p) != '\0'; ++p, ++cnt) {
145 if (cnt == TERM_WIDTH || ch == '\n') {
146- for (; cnt < TERM_WIDTH; ++cnt)
147- buf_puts(bs, " ");
148- buf_puts(bs, "\r\n");
149+ fprintf(fs, "%*s\r\n", TERM_WIDTH - cnt, "");
150 cnt = 0;
151 }
152 if (ch == '\t')
153 cnt += (7 - (cnt % 8));
154 if (ch != '\n')
155- buf_putc_careful(bs, ch);
156+ buf_putc_careful(fs, ch);
157 }
158 }
159 }
160- buf_printf(bs, "%*s\r\n", TERM_WIDTH, " ");
161+ fprintf(fs, "%*s\r\n", TERM_WIDTH, " ");
162
163 free(lbuf);
164
165- bs->data[bs->used] = '\0'; /* be paranoid */
166- *mbufsize = bs->used;
167- return bs->data;
168+ fclose(fs);
169+ return retbuf;
170 }
171--
1722.40.0
diff --git a/meta/recipes-core/util-linux/util-linux/CVE-2024-28085-0003.patch b/meta/recipes-core/util-linux/util-linux/CVE-2024-28085-0003.patch
new file mode 100644
index 0000000000..55eba9cc49
--- /dev/null
+++ b/meta/recipes-core/util-linux/util-linux/CVE-2024-28085-0003.patch
@@ -0,0 +1,223 @@
1From aa13246a1bf1be9e4f6eb331f4d4d2dbc875e22f Mon Sep 17 00:00:00 2001
2From: наб <nabijaczleweli@nabijaczleweli.xyz>
3Date: Wed, 15 Mar 2023 16:16:48 +0100
4Subject: [PATCH] wall: use fputs_careful()
5
6LINE_MAX only applies to teletypes in canonical mode: when stdin is a
7file, it could still very much tear; start off at 512 for the sprintf(),
8then use getline() like in write.
9
10The line wrapping has one suboptimal edge-case:
11 $ wall < all
12
13 Broadcast message from nabijaczleweli@tarta (pts/4) (Tue Mar 14 22:31:25
14 2023):
15
16 ^N^O^P^Q^R^S^T^U^V^W^X^Y^Z^[^\^]^^^_
17 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJ
18 KLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~^?\200\201\202\203\204\205\206
19 \207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232
20 \233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256
21 \257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302
22 \303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326
23 \327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352
24 \353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376
25 \377
26but that's a pathological input, and the result is still infinitely
27better than it was before, so fixing that is more trouble than it's
28worth.
29
30Bug-Debian: https://bugs.debian.org/826596
31
32CVE: CVE-2024-28085
33
34Upstream-Status: Backport [https://github.com/util-linux/util-linux/commit/aa13246a1bf1be9e4f6eb331f4d4d2dbc875e22f]
35
36Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
37---
38 include/carefulputc.h | 42 +++++++++++++++++++++++++++++++++---------
39 login-utils/last.c | 2 +-
40 term-utils/wall.c | 38 ++++++--------------------------------
41 term-utils/write.c | 2 +-
42 4 files changed, 41 insertions(+), 43 deletions(-)
43
44diff --git a/include/carefulputc.h b/include/carefulputc.h
45index 2506614..89f8a99 100644
46--- a/include/carefulputc.h
47+++ b/include/carefulputc.h
48@@ -6,6 +6,7 @@
49 #include <ctype.h>
50 #ifdef HAVE_WIDECHAR
51 #include <wctype.h>
52+#include <wchar.h>
53 #endif
54 #include <stdbool.h>
55
56@@ -15,18 +16,35 @@
57 * A puts() for use in write and wall (that sometimes are sgid tty).
58 * It avoids control and invalid characters.
59 * The locale of the recipient is nominally unknown,
60- * but it's a solid bet that the encoding is compatible with the author's.
61+ * but it's a solid bet that it's compatible with the author's.
62+ * Use soft_width=0 to disable wrapping.
63 */
64-static inline int fputs_careful(const char * s, FILE *fp, const char ctrl, bool cr_lf)
65+static inline int fputs_careful(const char * s, FILE *fp, const char ctrl, bool cr_lf, int soft_width)
66 {
67- int ret = 0;
68+ int ret = 0, col = 0;
69
70 for (size_t slen = strlen(s); *s; ++s, --slen) {
71- if (*s == '\n')
72+ if (*s == '\t')
73+ col += (7 - (col % 8)) - 1;
74+ else if (*s == '\r')
75+ col = -1;
76+ else if (*s == '\a')
77+ --col;
78+
79+ if ((soft_width && col >= soft_width) || *s == '\n') {
80+ if (soft_width) {
81+ fprintf(fp, "%*s", soft_width - col, "");
82+ col = 0;
83+ }
84 ret = fputs(cr_lf ? "\r\n" : "\n", fp);
85- else if (isprint(*s) || *s == '\a' || *s == '\t' || *s == '\r')
86+ if (*s == '\n' || ret < 0)
87+ goto wrote;
88+ }
89+
90+ if (isprint(*s) || *s == '\a' || *s == '\t' || *s == '\r') {
91 ret = putc(*s, fp);
92- else if (!c_isascii(*s)) {
93+ ++col;
94+ } else if (!c_isascii(*s)) {
95 #ifdef HAVE_WIDECHAR
96 wchar_t w;
97 size_t clen = mbtowc(&w, s, slen);
98@@ -35,21 +53,27 @@ static inline int fputs_careful(const char * s, FILE *fp, const char ctrl, bool
99 case (size_t)-1: // EILSEQ
100 mbtowc(NULL, NULL, 0);
101 nonprint:
102- ret = fprintf(fp, "\\%3hho", *s);
103+ col += ret = fprintf(fp, "\\%3hho", *s);
104 break;
105 default:
106 if(!iswprint(w))
107 goto nonprint;
108 ret = fwrite(s, 1, clen, fp);
109+ if (soft_width)
110+ col += wcwidth(w);
111 s += clen - 1;
112 slen -= clen - 1;
113 break;
114 }
115 #else
116- ret = fprintf(fp, "\\%3hho", *s);
117+ col += ret = fprintf(fp, "\\%3hho", *s);
118 #endif
119- } else
120+ } else {
121 ret = fputs((char[]){ ctrl, *s ^ 0x40, '\0' }, fp);
122+ col += 2;
123+ }
124+
125+ wrote:
126 if (ret < 0)
127 return EOF;
128 }
129diff --git a/login-utils/last.c b/login-utils/last.c
130index aacd1f6..43c5429 100644
131--- a/login-utils/last.c
132+++ b/login-utils/last.c
133@@ -558,7 +558,7 @@ static int list(const struct last_control *ctl, struct utmpx *p, time_t logout_t
134 /*
135 * Print out "final" string safely.
136 */
137- fputs_careful(final, stdout, '*', false);
138+ fputs_careful(final, stdout, '*', false, 0);
139
140 if (len < 0 || (size_t)len >= sizeof(final))
141 putchar('\n');
142diff --git a/term-utils/wall.c b/term-utils/wall.c
143index a51a928..377db45 100644
144--- a/term-utils/wall.c
145+++ b/term-utils/wall.c
146@@ -274,29 +274,13 @@ int main(int argc, char **argv)
147 exit(EXIT_SUCCESS);
148 }
149
150-static void buf_putc_careful(FILE *fs, int c)
151-{
152- if (isprint(c) || c == '\a' || c == '\t' || c == '\r' || c == '\n')
153- fputc(c, fs);
154- else if (!c_isascii(c))
155- fprintf(fs, "\\%3o", (unsigned char)c);
156- else
157- fputs((char[]){ '^', c ^ 0x40, '\0' }, fs);
158-}
159-
160 static char *makemsg(char *fname, char **mvec, int mvecsz,
161 size_t *mbufsize, int print_banner)
162 {
163- register int ch, cnt;
164- char *p, *lbuf, *retbuf;
165+ char *lbuf, *retbuf;
166 FILE * fs = open_memstream(&retbuf, mbufsize);
167- long line_max;
168-
169- line_max = sysconf(_SC_LINE_MAX);
170- if (line_max <= 0)
171- line_max = 512;
172-
173- lbuf = xmalloc(line_max);
174+ size_t lbuflen = 512;
175+ lbuf = xmalloc(lbuflen);
176
177 if (print_banner == TRUE) {
178 char *hostname = xgethostname();
179@@ -329,7 +313,7 @@ static char *makemsg(char *fname, char **mvec, int mvecsz,
180 will not overflow as long as %d takes at most 100 chars */
181 fprintf(fs, "\r%*s\r\n", TERM_WIDTH, " ");
182
183- snprintf(lbuf, line_max,
184+ snprintf(lbuf, lbuflen,
185 _("Broadcast message from %s@%s (%s) (%s):"),
186 whom, hostname, where, date);
187 fprintf(fs, "%-*.*s\007\007\r\n", TERM_WIDTH, TERM_WIDTH, lbuf);
188@@ -373,18 +357,8 @@ static char *makemsg(char *fname, char **mvec, int mvecsz,
189 /*
190 * Read message from stdin.
191 */
192- while (fgets(lbuf, line_max, stdin)) {
193- for (cnt = 0, p = lbuf; (ch = *p) != '\0'; ++p, ++cnt) {
194- if (cnt == TERM_WIDTH || ch == '\n') {
195- fprintf(fs, "%*s\r\n", TERM_WIDTH - cnt, "");
196- cnt = 0;
197- }
198- if (ch == '\t')
199- cnt += (7 - (cnt % 8));
200- if (ch != '\n')
201- buf_putc_careful(fs, ch);
202- }
203- }
204+ while (getline(&lbuf, &lbuflen, stdin) >= 0)
205+ fputs_careful(lbuf, fs, '^', true, TERM_WIDTH);
206 }
207 fprintf(fs, "%*s\r\n", TERM_WIDTH, " ");
208
209diff --git a/term-utils/write.c b/term-utils/write.c
210index 710a58c..1d57fce 100644
211--- a/term-utils/write.c
212+++ b/term-utils/write.c
213@@ -276,7 +276,7 @@ static void do_write(const struct write_control *ctl)
214 if (signal_received)
215 break;
216
217- if (fputs_careful(line, stdout, '^', true) == EOF)
218+ if (fputs_careful(line, stdout, '^', true, 0) == EOF)
219 err(EXIT_FAILURE, _("carefulputc failed"));
220 }
221 free(line);
222--
2232.40.0
diff --git a/meta/recipes-core/util-linux/util-linux/CVE-2024-28085-0004.patch b/meta/recipes-core/util-linux/util-linux/CVE-2024-28085-0004.patch
new file mode 100644
index 0000000000..af39931b3f
--- /dev/null
+++ b/meta/recipes-core/util-linux/util-linux/CVE-2024-28085-0004.patch
@@ -0,0 +1,36 @@
1From 07f0f0f5bd1e5e2268257ae1ff6d76a9b6c6ea8b Mon Sep 17 00:00:00 2001
2From: Karel Zak <kzak@redhat.com>
3Date: Wed, 17 Jan 2024 12:37:08 +0100
4Subject: [PATCH] wall: fix calloc cal [-Werror=calloc-transposed-args]
5
6term-utils/wall.c:143:37: error: xcalloc sizes specified with sizeof in the earlier argument and not in the later argument [-Werror=calloc-transposed-args]
7 143 | buf->groups = xcalloc(sizeof(*buf->groups), buf->ngroups);
8 | ^
9term-utils/wall.c:143:37: note: earlier argument should specify number of elements, later size of each element
10
11Signed-off-by: Karel Zak <kzak@redhat.com>
12
13CVE: CVE-2024-28085
14
15Upstream-Status: Backport [https://github.com/util-linux/util-linux/commit/07f0f0f5bd1e5e2268257ae1ff6d76a9b6c6ea8b]
16
17Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
18---
19 term-utils/wall.c | 2 +-
20 1 file changed, 1 insertion(+), 1 deletion(-)
21
22diff --git a/term-utils/wall.c b/term-utils/wall.c
23index 377db45..85c006a 100644
24--- a/term-utils/wall.c
25+++ b/term-utils/wall.c
26@@ -135,7 +135,7 @@ static struct group_workspace *init_group_workspace(const char *group)
27
28 buf->requested_group = get_group_gid(group);
29 buf->ngroups = sysconf(_SC_NGROUPS_MAX) + 1; /* room for the primary gid */
30- buf->groups = xcalloc(sizeof(*buf->groups), buf->ngroups);
31+ buf->groups = xcalloc(buf->ngroups, sizeof(*buf->groups));
32
33 return buf;
34 }
35--
362.40.0
diff --git a/meta/recipes-core/util-linux/util-linux/CVE-2024-28085-0005.patch b/meta/recipes-core/util-linux/util-linux/CVE-2024-28085-0005.patch
new file mode 100644
index 0000000000..a2b914d580
--- /dev/null
+++ b/meta/recipes-core/util-linux/util-linux/CVE-2024-28085-0005.patch
@@ -0,0 +1,34 @@
1From 404b0781f52f7c045ca811b2dceec526408ac253 Mon Sep 17 00:00:00 2001
2From: Karel Zak <kzak@redhat.com>
3Date: Thu, 21 Mar 2024 11:16:20 +0100
4Subject: [PATCH] wall: fix escape sequence Injection [CVE-2024-28085]
5
6Let's use for all cases the same output function.
7
8Reported-by: Skyler Ferrante <sjf5462@rit.edu>
9Signed-off-by: Karel Zak <kzak@redhat.com>
10
11CVE: CVE-2024-28085
12
13Upstream-Status: Backport [https://github.com/util-linux/util-linux/commit/404b0781f52f7c045ca811b2dceec526408ac253]
14
15Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
16---
17 term-utils/wall.c | 2 +-
18 1 file changed, 1 insertion(+), 1 deletion(-)
19
20diff --git a/term-utils/wall.c b/term-utils/wall.c
21index 85c006a..0212c03 100644
22--- a/term-utils/wall.c
23+++ b/term-utils/wall.c
24@@ -328,7 +328,7 @@ static char *makemsg(char *fname, char **mvec, int mvecsz,
25 int i;
26
27 for (i = 0; i < mvecsz; i++) {
28- fputs(mvec[i], fs);
29+ fputs_careful(mvec[i], fs, '^', true, TERM_WIDTH);
30 if (i < mvecsz - 1)
31 fputc(' ', fs);
32 }
33--
342.40.0