diff options
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 | ||
40 | SRC_URI[sha256sum] = "634e6916ad913366c3536b6468e7844769549b99a7b2bf80314de78ab5655b83" | 45 | SRC_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 @@ | |||
1 | From 8a7b8456d1dc0e7ca557d1ac31f638986704757f Mon Sep 17 00:00:00 2001 | ||
2 | From: наб <nabijaczleweli@nabijaczleweli.xyz> | ||
3 | Date: Wed Mar 15 16:16:31 2023 +0100 | ||
4 | Subject: [PATCH] write: correctly handle wide characters | ||
5 | |||
6 | Do this by replacing fputc_careful() (notice that the description said | ||
7 | it's locale-aware ‒ it very much is /not/), with a fputs_careful() which | ||
8 | does the same thing, but if it were to output a byte in the \123 format, | ||
9 | first it checks whether this byte starts a valid multibyte character. | ||
10 | |||
11 | If it does, and that character is printable, write it verbatim. | ||
12 | This means that | ||
13 | echo 'foo åäö ąęćźżń bar' | write nabijaczleweli pts/4 | ||
14 | instead of | ||
15 | foo \303\245\303\244\303\266 | ||
16 | \304\205\304\231\304\207\305\272\305\274\305\204 bar | ||
17 | yields | ||
18 | foo åäö ąęćźżń bar | ||
19 | or, more realistically, from a message I got earlier today, | ||
20 | Filip powiedzia\305\202 \305\274e zap\305\202aci jutro | ||
21 | becomes | ||
22 | Filip powiedział że zapłaci jutro | ||
23 | |||
24 | Invalid/non-printable sequences get processed as before. | ||
25 | |||
26 | Line reading in write must become getline() to avoid dealing with | ||
27 | partial 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} | ||
30 | with just fixed-512 fgets() | ||
31 | |||
32 | Bug-Debian: https://bugs.debian.org/826596 | ||
33 | |||
34 | CVE: CVE-2024-28085 | ||
35 | |||
36 | Upstream-Status: Backport [https://github.com/util-linux/util-linux/commit/8a7b8456d1dc0e7ca557d1ac31f638986704757f] | ||
37 | |||
38 | Signed-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 | |||
45 | diff --git a/include/carefulputc.h b/include/carefulputc.h | ||
46 | index 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) | ||
126 | diff --git a/login-utils/last.c b/login-utils/last.c | ||
127 | index 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'); | ||
148 | diff --git a/term-utils/write.c b/term-utils/write.c | ||
149 | index 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 | -- | ||
202 | 2.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 @@ | |||
1 | From 27ee6446503af7ec0c2647704ca47ac4de3852ef Mon Sep 17 00:00:00 2001 | ||
2 | From: наб <nabijaczleweli@nabijaczleweli.xyz> | ||
3 | Date: Wed, 15 Mar 2023 16:16:43 +0100 | ||
4 | Subject: [PATCH] wall: convert homebrew buffering to open_memstream() | ||
5 | |||
6 | The struct buffer system duplicates a plethora of standard I/O | ||
7 | functions (including a fork of fputc_careful()) | ||
8 | and adds a lot of complexity ‒ open_memstream() is standard, | ||
9 | and fits perfectly into this niche | ||
10 | |||
11 | CVE: CVE-2024-28085 | ||
12 | |||
13 | Upstream-Status: Backport [https://github.com/util-linux/util-linux/commit/27ee6446503af7ec0c2647704ca47ac4de3852ef] | ||
14 | |||
15 | Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com> | ||
16 | --- | ||
17 | term-utils/wall.c | 95 ++++++++++------------------------------------- | ||
18 | 1 file changed, 20 insertions(+), 75 deletions(-) | ||
19 | |||
20 | diff --git a/term-utils/wall.c b/term-utils/wall.c | ||
21 | index 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 | -- | ||
172 | 2.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 @@ | |||
1 | From aa13246a1bf1be9e4f6eb331f4d4d2dbc875e22f Mon Sep 17 00:00:00 2001 | ||
2 | From: наб <nabijaczleweli@nabijaczleweli.xyz> | ||
3 | Date: Wed, 15 Mar 2023 16:16:48 +0100 | ||
4 | Subject: [PATCH] wall: use fputs_careful() | ||
5 | |||
6 | LINE_MAX only applies to teletypes in canonical mode: when stdin is a | ||
7 | file, it could still very much tear; start off at 512 for the sprintf(), | ||
8 | then use getline() like in write. | ||
9 | |||
10 | The 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 | ||
26 | but that's a pathological input, and the result is still infinitely | ||
27 | better than it was before, so fixing that is more trouble than it's | ||
28 | worth. | ||
29 | |||
30 | Bug-Debian: https://bugs.debian.org/826596 | ||
31 | |||
32 | CVE: CVE-2024-28085 | ||
33 | |||
34 | Upstream-Status: Backport [https://github.com/util-linux/util-linux/commit/aa13246a1bf1be9e4f6eb331f4d4d2dbc875e22f] | ||
35 | |||
36 | Signed-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 | |||
44 | diff --git a/include/carefulputc.h b/include/carefulputc.h | ||
45 | index 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 | } | ||
129 | diff --git a/login-utils/last.c b/login-utils/last.c | ||
130 | index 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'); | ||
142 | diff --git a/term-utils/wall.c b/term-utils/wall.c | ||
143 | index 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 | |||
209 | diff --git a/term-utils/write.c b/term-utils/write.c | ||
210 | index 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 | -- | ||
223 | 2.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 @@ | |||
1 | From 07f0f0f5bd1e5e2268257ae1ff6d76a9b6c6ea8b Mon Sep 17 00:00:00 2001 | ||
2 | From: Karel Zak <kzak@redhat.com> | ||
3 | Date: Wed, 17 Jan 2024 12:37:08 +0100 | ||
4 | Subject: [PATCH] wall: fix calloc cal [-Werror=calloc-transposed-args] | ||
5 | |||
6 | term-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 | | ^ | ||
9 | term-utils/wall.c:143:37: note: earlier argument should specify number of elements, later size of each element | ||
10 | |||
11 | Signed-off-by: Karel Zak <kzak@redhat.com> | ||
12 | |||
13 | CVE: CVE-2024-28085 | ||
14 | |||
15 | Upstream-Status: Backport [https://github.com/util-linux/util-linux/commit/07f0f0f5bd1e5e2268257ae1ff6d76a9b6c6ea8b] | ||
16 | |||
17 | Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com> | ||
18 | --- | ||
19 | term-utils/wall.c | 2 +- | ||
20 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
21 | |||
22 | diff --git a/term-utils/wall.c b/term-utils/wall.c | ||
23 | index 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 | -- | ||
36 | 2.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 @@ | |||
1 | From 404b0781f52f7c045ca811b2dceec526408ac253 Mon Sep 17 00:00:00 2001 | ||
2 | From: Karel Zak <kzak@redhat.com> | ||
3 | Date: Thu, 21 Mar 2024 11:16:20 +0100 | ||
4 | Subject: [PATCH] wall: fix escape sequence Injection [CVE-2024-28085] | ||
5 | |||
6 | Let's use for all cases the same output function. | ||
7 | |||
8 | Reported-by: Skyler Ferrante <sjf5462@rit.edu> | ||
9 | Signed-off-by: Karel Zak <kzak@redhat.com> | ||
10 | |||
11 | CVE: CVE-2024-28085 | ||
12 | |||
13 | Upstream-Status: Backport [https://github.com/util-linux/util-linux/commit/404b0781f52f7c045ca811b2dceec526408ac253] | ||
14 | |||
15 | Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com> | ||
16 | --- | ||
17 | term-utils/wall.c | 2 +- | ||
18 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
19 | |||
20 | diff --git a/term-utils/wall.c b/term-utils/wall.c | ||
21 | index 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 | -- | ||
34 | 2.40.0 | ||