!162 [sync] PR-158: sync community patches
From: @openeuler-sync-bot Reviewed-by: @openeuler-basic Signed-off-by: @openeuler-basic
This commit is contained in:
commit
68f827a293
28
backport-add-return-in-supam_conv-function.patch
Normal file
28
backport-add-return-in-supam_conv-function.patch
Normal file
@ -0,0 +1,28 @@
|
||||
From 1ade162b7773ffd3a1c83ad9f4ce529ac69d619c Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Radu <stefan270101@gmail.com>
|
||||
Date: Tue, 25 Apr 2023 15:00:36 +0300
|
||||
Subject: [PATCH] add return in supam_conv function
|
||||
|
||||
Added return statement to ensure that all execution paths end with a
|
||||
return statement.
|
||||
|
||||
Signed-off-by: Stefan Radu <stefan270101@gmail.com>
|
||||
---
|
||||
login-utils/su-common.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/login-utils/su-common.c b/login-utils/su-common.c
|
||||
index 4b284995e..67c4fa271 100644
|
||||
--- a/login-utils/su-common.c
|
||||
+++ b/login-utils/su-common.c
|
||||
@@ -344,6 +344,7 @@ static int supam_conv( int num_msg,
|
||||
#elif defined(HAVE_SECURITY_OPENPAM_H)
|
||||
return openpam_ttyconv(num_msg, msg, resp, data);
|
||||
#endif
|
||||
+ return PAM_CONV_ERR;
|
||||
}
|
||||
|
||||
static void supam_cleanup(struct su_context *su, int retcode)
|
||||
--
|
||||
2.27.0
|
||||
|
||||
45
backport-hexdump-parse-handle-truncated-format-pattern.patch
Normal file
45
backport-hexdump-parse-handle-truncated-format-pattern.patch
Normal file
@ -0,0 +1,45 @@
|
||||
From e9aa06bad334b3a90ebe883dfc19b1e165a7c6cf Mon Sep 17 00:00:00 2001
|
||||
From: Ronan Pigott <ronan@rjp.ie>
|
||||
Date: Thu, 23 Mar 2023 15:18:00 -0700
|
||||
Subject: [PATCH] hexdump-parse: handle truncated format pattern
|
||||
|
||||
If the fmt being parsed by block_size is exactly '%', *++fmt is the
|
||||
terminator and strchr will return a valid pointer to the terminator of
|
||||
spec rather than NULL, the while condition will pass and subsequent
|
||||
strchr will read past the end of fmt until a spec character is found
|
||||
again
|
||||
|
||||
ASAN aborts with the following error on the first buffer overread:
|
||||
|
||||
AddressSanitizer: heap-buffer-overflow on address 0x602000000212 at pc 0x55bf1c4b2d78 bp 0x7ffe33c8cff0 sp 0x7ffe33c8cfe0
|
||||
READ of size 1 at 0x602000000212 thread T0
|
||||
#0 0x55bf1c4b2d77 in block_size ../text-utils/hexdump-parse.c:207
|
||||
#1 0x55bf1c4ad36f in main ../text-utils/hexdump.c:214
|
||||
#2 0x7f15f063c78f (/usr/lib/libc.so.6+0x2378f)
|
||||
#3 0x7f15f063c849 in __libc_start_main (/usr/lib/libc.so.6+0x23849)
|
||||
#4 0x55bf1c4ac6c4 in _start (../build/hexdump+0x86c4)
|
||||
---
|
||||
text-utils/hexdump-parse.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/text-utils/hexdump-parse.c b/text-utils/hexdump-parse.c
|
||||
index 0ceff8f21..272bb24e3 100644
|
||||
--- a/text-utils/hexdump-parse.c
|
||||
+++ b/text-utils/hexdump-parse.c
|
||||
@@ -204,10 +204,12 @@ int block_size(struct hexdump_fs *fs)
|
||||
* skip any special chars -- save precision in
|
||||
* case it's a %s format.
|
||||
*/
|
||||
- while (strchr(spec + 1, *++fmt))
|
||||
+ while (strchr(spec + 1, *++fmt) && *fmt != '\0')
|
||||
;
|
||||
if (*fmt == '.' && isdigit(*++fmt))
|
||||
fmt = next_number(fmt, &prec);
|
||||
+ if (*fmt == '\0')
|
||||
+ badfmt(fu->fmt);
|
||||
if (first_letter(fmt, "diouxX"))
|
||||
bcnt += 4;
|
||||
else if (first_letter(fmt, "efgEG"))
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,70 @@
|
||||
From 22769acf56daf6683d635fe92e06ceb52e0433ff Mon Sep 17 00:00:00 2001
|
||||
From: Karel Zak <kzak@redhat.com>
|
||||
Date: Tue, 4 Apr 2023 11:04:51 +0200
|
||||
Subject: [PATCH] libblkid: copy BLKID_PARTS_FORCE_GPT to whole-disk prober
|
||||
|
||||
Addresses: https://github.com/util-linux/util-linux/discussions/2146
|
||||
Signed-off-by: Karel Zak <kzak@redhat.com>
|
||||
---
|
||||
libblkid/src/blkidP.h | 3 +++
|
||||
libblkid/src/partitions/partitions.c | 5 +++++
|
||||
libblkid/src/probe.c | 6 ++++++
|
||||
3 files changed, 14 insertions(+)
|
||||
|
||||
diff --git a/libblkid/src/blkidP.h b/libblkid/src/blkidP.h
|
||||
index 5d2a02055..007cc357b 100644
|
||||
--- a/libblkid/src/blkidP.h
|
||||
+++ b/libblkid/src/blkidP.h
|
||||
@@ -544,6 +544,9 @@ extern int blkid_probe_get_hint(blkid_probe pr, const char *name, uint64_t *valu
|
||||
__attribute__((nonnull(1,2)))
|
||||
__attribute__((warn_unused_result));
|
||||
|
||||
+extern int blkid_probe_get_partitions_flags(blkid_probe pr)
|
||||
+ __attribute__((nonnull));
|
||||
+
|
||||
/* filter bitmap macros */
|
||||
#define blkid_bmp_wordsize (8 * sizeof(unsigned long))
|
||||
#define blkid_bmp_idx_bit(item) (1UL << ((item) % blkid_bmp_wordsize))
|
||||
diff --git a/libblkid/src/partitions/partitions.c b/libblkid/src/partitions/partitions.c
|
||||
index ae63a38cc..1c344fd30 100644
|
||||
--- a/libblkid/src/partitions/partitions.c
|
||||
+++ b/libblkid/src/partitions/partitions.c
|
||||
@@ -234,6 +234,11 @@ int blkid_probe_set_partitions_flags(blkid_probe pr, int flags)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+int blkid_probe_get_partitions_flags(blkid_probe pr)
|
||||
+{
|
||||
+ return pr->chains[BLKID_CHAIN_PARTS].flags;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* blkid_probe_reset_partitions_filter:
|
||||
* @pr: prober
|
||||
diff --git a/libblkid/src/probe.c b/libblkid/src/probe.c
|
||||
index 35de30334..b4299493f 100644
|
||||
--- a/libblkid/src/probe.c
|
||||
+++ b/libblkid/src/probe.c
|
||||
@@ -1930,6 +1930,7 @@ blkid_probe blkid_probe_get_wholedisk_probe(blkid_probe pr)
|
||||
if (!pr->disk_probe) {
|
||||
/* Open a new disk prober */
|
||||
char *disk_path = blkid_devno_to_devname(disk);
|
||||
+ int flags;
|
||||
|
||||
if (!disk_path)
|
||||
return NULL;
|
||||
@@ -1942,6 +1943,11 @@ blkid_probe blkid_probe_get_wholedisk_probe(blkid_probe pr)
|
||||
|
||||
if (!pr->disk_probe)
|
||||
return NULL; /* ENOMEM? */
|
||||
+
|
||||
+ flags = blkid_probe_get_partitions_flags(pr);
|
||||
+ if (flags & BLKID_PARTS_FORCE_GPT)
|
||||
+ blkid_probe_set_partitions_flags(pr->disk_probe,
|
||||
+ BLKID_PARTS_FORCE_GPT);
|
||||
}
|
||||
|
||||
return pr->disk_probe;
|
||||
--
|
||||
2.27.0
|
||||
|
||||
62
backport-libfdisk-Fix-randomly-generated-GPT-UUID-s.patch
Normal file
62
backport-libfdisk-Fix-randomly-generated-GPT-UUID-s.patch
Normal file
@ -0,0 +1,62 @@
|
||||
From dd405ea745e451fb0cf32e9dedd94d69850fe333 Mon Sep 17 00:00:00 2001
|
||||
From: Toomas Losin <tlo@lenrek.net>
|
||||
Date: Sun, 5 Mar 2023 15:57:55 -0800
|
||||
Subject: [PATCH] libfdisk: Fix randomly generated GPT UUID's
|
||||
|
||||
Fdisk commands that create random GPT UUID's result in values that are
|
||||
not UEFI-compliant being written to disk: The "g" command creates a
|
||||
new GPT whose in-core DiskGUID value is entirely big-endian; the "n"
|
||||
command creates a GPT partition whose in-core UniquePartitionGUID
|
||||
value is entirely big-endian. Those big-endian values are written to
|
||||
disk by the "w" command rather than the mix of little- and big-endian
|
||||
spec'd by UEFI.
|
||||
|
||||
This was caused by a libfdisk patch in 2017 that was addressing
|
||||
warnings about "taking address of packed member". Reading gpt.c finds
|
||||
two instances of dead code which suggests that perhaps there was some
|
||||
confusion between a struct and a pointer to a struct. The intent must
|
||||
have been to convert the randomly generated big-endian RFC 4122 UUID
|
||||
values to UEFI's mixed-endian but the confusion(?) resulted in some
|
||||
dead code and non-conversion of the UUID's.
|
||||
|
||||
This patch corrects the breakage while still avoiding "taking address
|
||||
of packed member" warnings. The "w" command will once again write
|
||||
UEFI-compliant values to disk.
|
||||
|
||||
Fixes: 92e486f80ef8 ("libfdisk: fix guid usage of packed struct gpt_entry")
|
||||
Signed-off-by: Toomas Losin <tlo@lenrek.net>
|
||||
---
|
||||
libfdisk/src/gpt.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/libfdisk/src/gpt.c b/libfdisk/src/gpt.c
|
||||
index d7b3e1c70..c3c0347cb 100644
|
||||
--- a/libfdisk/src/gpt.c
|
||||
+++ b/libfdisk/src/gpt.c
|
||||
@@ -878,9 +878,9 @@ static int gpt_mknew_header(struct fdisk_context *cxt,
|
||||
if (!has_id) {
|
||||
struct gpt_guid guid;
|
||||
|
||||
- uuid_generate_random((unsigned char *) &header->disk_guid);
|
||||
- guid = header->disk_guid;
|
||||
+ uuid_generate_random((unsigned char *) &guid);
|
||||
swap_efi_guid(&guid);
|
||||
+ header->disk_guid = guid;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -2621,9 +2621,9 @@ static int gpt_add_partition(
|
||||
*/
|
||||
struct gpt_guid guid;
|
||||
|
||||
- uuid_generate_random((unsigned char *) &e->partition_guid);
|
||||
- guid = e->partition_guid;
|
||||
+ uuid_generate_random((unsigned char *) &guid);
|
||||
swap_efi_guid(&guid);
|
||||
+ e->partition_guid = guid;
|
||||
}
|
||||
|
||||
if (pa && pa->name && *pa->name)
|
||||
--
|
||||
2.27.0
|
||||
|
||||
34
backport-lscpu-fix-p-output-all-caches-delimiter.patch
Normal file
34
backport-lscpu-fix-p-output-all-caches-delimiter.patch
Normal file
@ -0,0 +1,34 @@
|
||||
From 0da947eb78e3f37f63f33157562c221805ec7fe9 Mon Sep 17 00:00:00 2001
|
||||
From: Karel Zak <kzak@redhat.com>
|
||||
Date: Mon, 17 Apr 2023 10:50:08 +0200
|
||||
Subject: [PATCH] lscpu: fix -p --output-all caches delimiter
|
||||
|
||||
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=2187099
|
||||
Signed-off-by: Karel Zak <kzak@redhat.com>
|
||||
---
|
||||
sys-utils/lscpu.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/sys-utils/lscpu.c b/sys-utils/lscpu.c
|
||||
index 3f28db61c..8333dcbea 100644
|
||||
--- a/sys-utils/lscpu.c
|
||||
+++ b/sys-utils/lscpu.c
|
||||
@@ -1444,6 +1444,7 @@ int main(int argc, char *argv[])
|
||||
print_cpus_readable(cxt, columns, ncolumns);
|
||||
break;
|
||||
case LSCPU_OUTPUT_PARSABLE:
|
||||
+ cxt->show_compatible = 1;
|
||||
if (!ncolumns) {
|
||||
columns[ncolumns++] = COL_CPU_CPU;
|
||||
columns[ncolumns++] = COL_CPU_CORE;
|
||||
@@ -1453,7 +1454,6 @@ int main(int argc, char *argv[])
|
||||
columns[ncolumns++] = COL_CPU_SOCKET;
|
||||
columns[ncolumns++] = COL_CPU_NODE;
|
||||
columns[ncolumns++] = COL_CPU_CACHE;
|
||||
- cxt->show_compatible = 1;
|
||||
}
|
||||
if (outarg && string_add_to_idarray(outarg, columns,
|
||||
ARRAY_SIZE(columns),
|
||||
--
|
||||
2.27.0
|
||||
|
||||
59
backport-sulogin-fix-KDGKBMODE-ifdef.patch
Normal file
59
backport-sulogin-fix-KDGKBMODE-ifdef.patch
Normal file
@ -0,0 +1,59 @@
|
||||
From 8efec058d7a513c18f5e5666e79006ded786221a Mon Sep 17 00:00:00 2001
|
||||
From: Karel Zak <kzak@redhat.com>
|
||||
Date: Tue, 2 May 2023 11:36:49 +0200
|
||||
Subject: [PATCH] sulogin: fix KDGKBMODE ifdef
|
||||
|
||||
* remove ifdef-else for KDGKBMODE
|
||||
|
||||
* always call KDGKBMODE for virtual console to get K_UNICODE status
|
||||
|
||||
* use KDGKBMODE as a fallback to detect serial line
|
||||
|
||||
Fixes: https://github.com/util-linux/util-linux/issues/2185
|
||||
Suggested-by: Marcos Mello
|
||||
Signed-off-by: Karel Zak <kzak@redhat.com>
|
||||
---
|
||||
login-utils/sulogin.c | 14 +++++++-------
|
||||
1 file changed, 7 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/login-utils/sulogin.c b/login-utils/sulogin.c
|
||||
index 851d92d..3507272 100644
|
||||
--- a/login-utils/sulogin.c
|
||||
+++ b/login-utils/sulogin.c
|
||||
@@ -108,7 +108,7 @@ static void tcinit(struct console *con)
|
||||
struct termios *tio = &con->tio;
|
||||
const int fd = con->fd;
|
||||
#if defined(TIOCGSERIAL)
|
||||
- struct serial_struct serinfo;
|
||||
+ struct serial_struct serinfo = { .flags = 0 };
|
||||
#endif
|
||||
#ifdef USE_PLYMOUTH_SUPPORT
|
||||
struct termios lock;
|
||||
@@ -132,18 +132,18 @@ static void tcinit(struct console *con)
|
||||
errno = 0;
|
||||
#endif
|
||||
|
||||
-#if defined(TIOCGSERIAL)
|
||||
+#ifdef TIOCGSERIAL
|
||||
if (ioctl(fd, TIOCGSERIAL, &serinfo) >= 0)
|
||||
con->flags |= CON_SERIAL;
|
||||
errno = 0;
|
||||
-#else
|
||||
-# if defined(KDGKBMODE)
|
||||
- if (ioctl(fd, KDGKBMODE, &mode) < 0)
|
||||
+#endif
|
||||
+
|
||||
+#ifdef KDGKBMODE
|
||||
+ if (!(con->flags & CON_SERIAL)
|
||||
+ && ioctl(fd, KDGKBMODE, &mode) < 0)
|
||||
con->flags |= CON_SERIAL;
|
||||
errno = 0;
|
||||
-# endif
|
||||
#endif
|
||||
-
|
||||
if (tcgetattr(fd, tio) < 0) {
|
||||
int saveno = errno;
|
||||
#if defined(KDGKBMODE) || defined(TIOCGSERIAL)
|
||||
--
|
||||
2.33.0
|
||||
|
||||
227
backport-sulogin-ignore-none-existing-console-devices.patch
Normal file
227
backport-sulogin-ignore-none-existing-console-devices.patch
Normal file
@ -0,0 +1,227 @@
|
||||
From 0d092db5c40b94e1ea9529f3f1c384a74eca19f8 Mon Sep 17 00:00:00 2001
|
||||
From: Werner Fink <werner@suse.de>
|
||||
Date: Mon, 17 May 2021 17:20:32 +0200
|
||||
Subject: [PATCH] sulogin: ignore none-existing console devices
|
||||
|
||||
and also none-functional console devices. Redirect the error
|
||||
messages to the appropiate console device.
|
||||
|
||||
Signed-off-by: Werner Fink <werner@suse.de>
|
||||
---
|
||||
login-utils/sulogin-consoles.h | 1 +
|
||||
login-utils/sulogin.c | 92 ++++++++++++++++++++++++++++------
|
||||
2 files changed, 79 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/login-utils/sulogin-consoles.h b/login-utils/sulogin-consoles.h
|
||||
index 0bfbc38..12032c9 100644
|
||||
--- a/login-utils/sulogin-consoles.h
|
||||
+++ b/login-utils/sulogin-consoles.h
|
||||
@@ -40,6 +40,7 @@ struct console {
|
||||
int fd, id;
|
||||
#define CON_SERIAL 0x0001
|
||||
#define CON_NOTTY 0x0002
|
||||
+#define CON_EIO 0x0004
|
||||
pid_t pid;
|
||||
struct chardata cp;
|
||||
struct termios tio;
|
||||
diff --git a/login-utils/sulogin.c b/login-utils/sulogin.c
|
||||
index 4d48943..df27896 100644
|
||||
--- a/login-utils/sulogin.c
|
||||
+++ b/login-utils/sulogin.c
|
||||
@@ -52,6 +52,7 @@
|
||||
#ifdef __linux__
|
||||
# include <sys/kd.h>
|
||||
# include <sys/param.h>
|
||||
+# include <linux/serial.h>
|
||||
#endif
|
||||
|
||||
#include "c.h"
|
||||
@@ -106,6 +107,9 @@ static void tcinit(struct console *con)
|
||||
int flags = 0, mode = 0;
|
||||
struct termios *tio = &con->tio;
|
||||
const int fd = con->fd;
|
||||
+#if defined(TIOCGSERIAL)
|
||||
+ struct serial_struct serinfo;
|
||||
+#endif
|
||||
#ifdef USE_PLYMOUTH_SUPPORT
|
||||
struct termios lock;
|
||||
int i = (plymouth_command(MAGIC_PING)) ? PLYMOUTH_TERMIOS_FLAGS_DELAY : 0;
|
||||
@@ -125,27 +129,72 @@ static void tcinit(struct console *con)
|
||||
}
|
||||
memset(&lock, 0, sizeof(struct termios));
|
||||
ioctl(fd, TIOCSLCKTRMIOS, &lock);
|
||||
+ errno = 0;
|
||||
#endif
|
||||
+
|
||||
+#if defined(TIOCGSERIAL)
|
||||
+ if (ioctl(fd, TIOCGSERIAL, &serinfo) >= 0)
|
||||
+ con->flags |= CON_SERIAL;
|
||||
+ errno = 0;
|
||||
+#else
|
||||
+# if defined(KDGKBMODE)
|
||||
+ if (ioctl(fd, KDGKBMODE, &mode) < 0)
|
||||
+ con->flags |= CON_SERIAL;
|
||||
errno = 0;
|
||||
+# endif
|
||||
+#endif
|
||||
|
||||
if (tcgetattr(fd, tio) < 0) {
|
||||
- warn(_("tcgetattr failed"));
|
||||
- con->flags |= CON_NOTTY;
|
||||
- return;
|
||||
+ int saveno = errno;
|
||||
+#if defined(KDGKBMODE) || defined(TIOCGSERIAL)
|
||||
+ if (con->flags & CON_SERIAL) { /* Try to recover this */
|
||||
+
|
||||
+# if defined(TIOCGSERIAL)
|
||||
+ serinfo.flags |= ASYNC_SKIP_TEST; /* Skip test of UART */
|
||||
+
|
||||
+ if (ioctl(fd, TIOCSSERIAL, &serinfo) < 0)
|
||||
+ goto tcgeterr;
|
||||
+ if (ioctl(fd, TIOCSERCONFIG) < 0) /* Try to autoconfigure */
|
||||
+ goto tcgeterr;
|
||||
+ if (ioctl(fd, TIOCGSERIAL, &serinfo) < 0)
|
||||
+ goto tcgeterr; /* Ouch */
|
||||
+# endif
|
||||
+ if (tcgetattr(fd, tio) < 0) /* Retry to get tty attributes */
|
||||
+ saveno = errno;
|
||||
+ }
|
||||
+# if defined(TIOCGSERIAL)
|
||||
+ tcgeterr:
|
||||
+# endif
|
||||
+ if (saveno)
|
||||
+#endif
|
||||
+ {
|
||||
+ FILE *fcerr = fdopen(fd, "w");
|
||||
+ if (fcerr) {
|
||||
+ fprintf(fcerr, _("tcgetattr failed"));
|
||||
+ fclose(fcerr);
|
||||
+ }
|
||||
+ warn(_("tcgetattr failed"));
|
||||
+
|
||||
+ con->flags &= ~CON_SERIAL;
|
||||
+ if (saveno != EIO)
|
||||
+ con->flags |= CON_NOTTY;
|
||||
+ else
|
||||
+ con->flags |= CON_EIO;
|
||||
+
|
||||
+ errno = 0;
|
||||
+ return;
|
||||
+ }
|
||||
}
|
||||
|
||||
/* Handle lines other than virtual consoles here */
|
||||
-#if defined(KDGKBMODE)
|
||||
- if (ioctl(fd, KDGKBMODE, &mode) < 0)
|
||||
+#if defined(KDGKBMODE) || defined(TIOCGSERIAL)
|
||||
+ if (con->flags & CON_SERIAL)
|
||||
#endif
|
||||
{
|
||||
speed_t ispeed, ospeed;
|
||||
struct winsize ws;
|
||||
errno = 0;
|
||||
|
||||
- /* this is a modem line */
|
||||
- con->flags |= CON_SERIAL;
|
||||
-
|
||||
/* Flush input and output queues on modem lines */
|
||||
tcflush(fd, TCIOFLUSH);
|
||||
|
||||
@@ -222,6 +271,8 @@ static void tcfinal(struct console *con)
|
||||
struct termios *tio = &con->tio;
|
||||
const int fd = con->fd;
|
||||
|
||||
+ if (con->flags & CON_EIO)
|
||||
+ return;
|
||||
if ((con->flags & CON_SERIAL) == 0) {
|
||||
xsetenv("TERM", "linux", 1);
|
||||
return;
|
||||
@@ -559,12 +610,16 @@ err:
|
||||
static void setup(struct console *con)
|
||||
{
|
||||
int fd = con->fd;
|
||||
- const pid_t pid = getpid(), pgrp = getpgid(0), ppgrp =
|
||||
- getpgid(getppid()), ttypgrp = tcgetpgrp(fd);
|
||||
+ const pid_t pid = getpid(), pgrp = getpgid(0), ppgrp = getpgid(getppid());
|
||||
+ pid_t ttypgrp;
|
||||
|
||||
if (con->flags & CON_NOTTY)
|
||||
+ goto notty;
|
||||
+ if (con->flags & CON_EIO)
|
||||
return;
|
||||
|
||||
+ ttypgrp = tcgetpgrp(fd);
|
||||
+
|
||||
/*
|
||||
* Only go through this trouble if the new
|
||||
* tty doesn't fall in this process group.
|
||||
@@ -587,6 +642,7 @@ static void setup(struct console *con)
|
||||
ioctl(fd, TIOCSCTTY, (char *)1);
|
||||
tcsetpgrp(fd, ppgrp);
|
||||
}
|
||||
+notty:
|
||||
dup2(fd, STDIN_FILENO);
|
||||
dup2(fd, STDOUT_FILENO);
|
||||
dup2(fd, STDERR_FILENO);
|
||||
@@ -616,15 +672,19 @@ static char *getpasswd(struct console *con)
|
||||
int eightbit;
|
||||
const int fd = con->fd;
|
||||
|
||||
- if (con->flags & CON_NOTTY)
|
||||
+ if (con->flags & CON_EIO)
|
||||
goto out;
|
||||
+
|
||||
cp = &con->cp;
|
||||
tty = con->tio;
|
||||
|
||||
+ tc = 0;
|
||||
ret = pass;
|
||||
tty.c_iflag &= ~(IUCLC|IXON|IXOFF|IXANY);
|
||||
tty.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|TOSTOP|ISIG);
|
||||
- tc = (tcsetattr(fd, TCSAFLUSH, &tty) == 0);
|
||||
+
|
||||
+ if ((con->flags & CON_NOTTY) == 0)
|
||||
+ tc = (tcsetattr(fd, TCSAFLUSH, &tty) == 0);
|
||||
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_handler = alrm_handler;
|
||||
@@ -650,11 +710,12 @@ static char *getpasswd(struct console *con)
|
||||
}
|
||||
ret = NULL;
|
||||
switch (errno) {
|
||||
- case 0:
|
||||
case EIO:
|
||||
+ con->flags |= CON_EIO;
|
||||
case ESRCH:
|
||||
case EINVAL:
|
||||
case ENOENT:
|
||||
+ case 0:
|
||||
break;
|
||||
default:
|
||||
warn(_("cannot read %s"), con->tty);
|
||||
@@ -976,10 +1037,13 @@ int main(int argc, char **argv)
|
||||
con = list_entry(ptr, struct console, entry);
|
||||
if (con->id >= CONMAX)
|
||||
break;
|
||||
+ if (con->flags & CON_EIO)
|
||||
+ goto next;
|
||||
|
||||
switch ((con->pid = fork())) {
|
||||
case 0:
|
||||
mask_signal(SIGCHLD, SIG_DFL, NULL);
|
||||
+ dup2(con->fd, STDERR_FILENO);
|
||||
nofork:
|
||||
setup(con);
|
||||
while (1) {
|
||||
@@ -1040,7 +1104,7 @@ int main(int argc, char **argv)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
-
|
||||
+ next:
|
||||
ptr = ptr->next;
|
||||
|
||||
} while (ptr != &consoles);
|
||||
--
|
||||
2.33.0
|
||||
|
||||
170
backport-wall-convert-homebrew-buffering-to-open_memstream.patch
Normal file
170
backport-wall-convert-homebrew-buffering-to-open_memstream.patch
Normal file
@ -0,0 +1,170 @@
|
||||
From 27ee6446503af7ec0c2647704ca47ac4de3852ef Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?=D0=BD=D0=B0=D0=B1?= <nabijaczleweli@nabijaczleweli.xyz>
|
||||
Date: Wed, 15 Mar 2023 16:16:43 +0100
|
||||
Subject: [PATCH] wall: convert homebrew buffering to open_memstream()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The struct buffer system duplicates a plethora of standard I/O
|
||||
functions (including a fork of fputc_careful())
|
||||
and adds a lot of complexity ‒ open_memstream() is standard,
|
||||
and fits perfectly into this niche
|
||||
---
|
||||
term-utils/wall.c | 95 ++++++++++-------------------------------------
|
||||
1 file changed, 20 insertions(+), 75 deletions(-)
|
||||
|
||||
diff --git a/term-utils/wall.c b/term-utils/wall.c
|
||||
index c601d3e5b..a51a92829 100644
|
||||
--- a/term-utils/wall.c
|
||||
+++ b/term-utils/wall.c
|
||||
@@ -274,74 +274,22 @@ int main(int argc, char **argv)
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
-struct buffer {
|
||||
- size_t sz;
|
||||
- size_t used;
|
||||
- char *data;
|
||||
-};
|
||||
-
|
||||
-static void buf_enlarge(struct buffer *bs, size_t len)
|
||||
+static void buf_putc_careful(FILE *fs, int c)
|
||||
{
|
||||
- if (bs->sz == 0 || len > bs->sz - bs->used) {
|
||||
- bs->sz += len < 128 ? 128 : len;
|
||||
- bs->data = xrealloc(bs->data, bs->sz);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-static void buf_puts(struct buffer *bs, const char *s)
|
||||
-{
|
||||
- size_t len = strlen(s);
|
||||
-
|
||||
- buf_enlarge(bs, len + 1);
|
||||
- memcpy(bs->data + bs->used, s, len + 1);
|
||||
- bs->used += len;
|
||||
-}
|
||||
-
|
||||
-static void __attribute__((__format__ (__printf__, 2, 3)))
|
||||
- buf_printf(struct buffer *bs, const char *fmt, ...)
|
||||
-{
|
||||
- int rc;
|
||||
- va_list ap;
|
||||
- size_t limit;
|
||||
-
|
||||
- buf_enlarge(bs, 0); /* default size */
|
||||
- limit = bs->sz - bs->used;
|
||||
-
|
||||
- va_start(ap, fmt);
|
||||
- rc = vsnprintf(bs->data + bs->used, limit, fmt, ap);
|
||||
- va_end(ap);
|
||||
-
|
||||
- if (rc >= 0 && (size_t) rc >= limit) { /* not enough, enlarge */
|
||||
- buf_enlarge(bs, (size_t)rc + 1);
|
||||
- limit = bs->sz - bs->used;
|
||||
- va_start(ap, fmt);
|
||||
- rc = vsnprintf(bs->data + bs->used, limit, fmt, ap);
|
||||
- va_end(ap);
|
||||
- }
|
||||
-
|
||||
- if (rc > 0)
|
||||
- bs->used += rc;
|
||||
-}
|
||||
-
|
||||
-static void buf_putc_careful(struct buffer *bs, int c)
|
||||
-{
|
||||
- if (isprint(c) || c == '\a' || c == '\t' || c == '\r' || c == '\n') {
|
||||
- buf_enlarge(bs, 1);
|
||||
- bs->data[bs->used++] = c;
|
||||
- } else if (!c_isascii(c))
|
||||
- buf_printf(bs, "\\%3o", (unsigned char)c);
|
||||
- else {
|
||||
- char tmp[] = { '^', c ^ 0x40, '\0' };
|
||||
- buf_puts(bs, tmp);
|
||||
- }
|
||||
+ if (isprint(c) || c == '\a' || c == '\t' || c == '\r' || c == '\n')
|
||||
+ fputc(c, fs);
|
||||
+ else if (!c_isascii(c))
|
||||
+ fprintf(fs, "\\%3o", (unsigned char)c);
|
||||
+ else
|
||||
+ fputs((char[]){ '^', c ^ 0x40, '\0' }, fs);
|
||||
}
|
||||
|
||||
static char *makemsg(char *fname, char **mvec, int mvecsz,
|
||||
size_t *mbufsize, int print_banner)
|
||||
{
|
||||
- struct buffer _bs = {.used = 0}, *bs = &_bs;
|
||||
register int ch, cnt;
|
||||
- char *p, *lbuf;
|
||||
+ char *p, *lbuf, *retbuf;
|
||||
+ FILE * fs = open_memstream(&retbuf, mbufsize);
|
||||
long line_max;
|
||||
|
||||
line_max = sysconf(_SC_LINE_MAX);
|
||||
@@ -379,15 +327,15 @@ static char *makemsg(char *fname, char **mvec, int mvecsz,
|
||||
*/
|
||||
/* snprintf is not always available, but the sprintf's here
|
||||
will not overflow as long as %d takes at most 100 chars */
|
||||
- buf_printf(bs, "\r%*s\r\n", TERM_WIDTH, " ");
|
||||
+ fprintf(fs, "\r%*s\r\n", TERM_WIDTH, " ");
|
||||
|
||||
snprintf(lbuf, line_max,
|
||||
_("Broadcast message from %s@%s (%s) (%s):"),
|
||||
whom, hostname, where, date);
|
||||
- buf_printf(bs, "%-*.*s\007\007\r\n", TERM_WIDTH, TERM_WIDTH, lbuf);
|
||||
+ fprintf(fs, "%-*.*s\007\007\r\n", TERM_WIDTH, TERM_WIDTH, lbuf);
|
||||
free(hostname);
|
||||
}
|
||||
- buf_printf(bs, "%*s\r\n", TERM_WIDTH, " ");
|
||||
+ fprintf(fs, "%*s\r\n", TERM_WIDTH, " ");
|
||||
|
||||
if (mvec) {
|
||||
/*
|
||||
@@ -396,11 +344,11 @@ static char *makemsg(char *fname, char **mvec, int mvecsz,
|
||||
int i;
|
||||
|
||||
for (i = 0; i < mvecsz; i++) {
|
||||
- buf_puts(bs, mvec[i]);
|
||||
+ fputs(mvec[i], fs);
|
||||
if (i < mvecsz - 1)
|
||||
- buf_puts(bs, " ");
|
||||
+ fputc(' ', fs);
|
||||
}
|
||||
- buf_puts(bs, "\r\n");
|
||||
+ fputs("\r\n", fs);
|
||||
} else {
|
||||
/*
|
||||
* read message from <file>
|
||||
@@ -428,23 +376,20 @@ static char *makemsg(char *fname, char **mvec, int mvecsz,
|
||||
while (fgets(lbuf, line_max, stdin)) {
|
||||
for (cnt = 0, p = lbuf; (ch = *p) != '\0'; ++p, ++cnt) {
|
||||
if (cnt == TERM_WIDTH || ch == '\n') {
|
||||
- for (; cnt < TERM_WIDTH; ++cnt)
|
||||
- buf_puts(bs, " ");
|
||||
- buf_puts(bs, "\r\n");
|
||||
+ fprintf(fs, "%*s\r\n", TERM_WIDTH - cnt, "");
|
||||
cnt = 0;
|
||||
}
|
||||
if (ch == '\t')
|
||||
cnt += (7 - (cnt % 8));
|
||||
if (ch != '\n')
|
||||
- buf_putc_careful(bs, ch);
|
||||
+ buf_putc_careful(fs, ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
- buf_printf(bs, "%*s\r\n", TERM_WIDTH, " ");
|
||||
+ fprintf(fs, "%*s\r\n", TERM_WIDTH, " ");
|
||||
|
||||
free(lbuf);
|
||||
|
||||
- bs->data[bs->used] = '\0'; /* be paranoid */
|
||||
- *mbufsize = bs->used;
|
||||
- return bs->data;
|
||||
+ fclose(fs);
|
||||
+ return retbuf;
|
||||
}
|
||||
--
|
||||
2.27.0
|
||||
|
||||
218
backport-wall-use-fputs_careful.patch
Normal file
218
backport-wall-use-fputs_careful.patch
Normal file
@ -0,0 +1,218 @@
|
||||
From aa13246a1bf1be9e4f6eb331f4d4d2dbc875e22f Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?=D0=BD=D0=B0=D0=B1?= <nabijaczleweli@nabijaczleweli.xyz>
|
||||
Date: Wed, 15 Mar 2023 16:16:48 +0100
|
||||
Subject: [PATCH] wall: use fputs_careful()
|
||||
|
||||
LINE_MAX only applies to teletypes in canonical mode: when stdin is a
|
||||
file, it could still very much tear; start off at 512 for the sprintf(),
|
||||
then use getline() like in write.
|
||||
|
||||
The line wrapping has one suboptimal edge-case:
|
||||
$ wall < all
|
||||
|
||||
Broadcast message from nabijaczleweli@tarta (pts/4) (Tue Mar 14 22:31:25
|
||||
2023):
|
||||
|
||||
^N^O^P^Q^R^S^T^U^V^W^X^Y^Z^[^\^]^^^_
|
||||
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJ
|
||||
KLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~^?\200\201\202\203\204\205\206
|
||||
\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232
|
||||
\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256
|
||||
\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302
|
||||
\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326
|
||||
\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352
|
||||
\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376
|
||||
\377
|
||||
but that's a pathological input, and the result is still infinitely
|
||||
better than it was before, so fixing that is more trouble than it's
|
||||
worth.
|
||||
|
||||
Bug-Debian: https://bugs.debian.org/826596
|
||||
---
|
||||
include/carefulputc.h | 42 +++++++++++++++++++++++++++++++++---------
|
||||
login-utils/last.c | 2 +-
|
||||
term-utils/wall.c | 38 ++++++--------------------------------
|
||||
term-utils/write.c | 2 +-
|
||||
4 files changed, 41 insertions(+), 43 deletions(-)
|
||||
|
||||
diff --git a/include/carefulputc.h b/include/carefulputc.h
|
||||
index 740add68e..3cc6f7ff9 100644
|
||||
--- a/include/carefulputc.h
|
||||
+++ b/include/carefulputc.h
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <ctype.h>
|
||||
#ifdef HAVE_WIDECHAR
|
||||
#include <wctype.h>
|
||||
+#include <wchar.h>
|
||||
#endif
|
||||
#include <stdbool.h>
|
||||
|
||||
@@ -15,18 +16,35 @@
|
||||
* A puts() for use in write and wall (that sometimes are sgid tty).
|
||||
* It avoids control and invalid characters.
|
||||
* The locale of the recipient is nominally unknown,
|
||||
- * but it's a solid bet that the encoding is compatible with the author's.
|
||||
+ * but it's a solid bet that it's compatible with the author's.
|
||||
+ * Use soft_width=0 to disable wrapping.
|
||||
*/
|
||||
-static inline int fputs_careful(const char * s, FILE *fp, const char ctrl, bool cr_lf)
|
||||
+static inline int fputs_careful(const char * s, FILE *fp, const char ctrl, bool cr_lf, int soft_width)
|
||||
{
|
||||
- int ret = 0;
|
||||
+ int ret = 0, col = 0;
|
||||
|
||||
for (size_t slen = strlen(s); *s; ++s, --slen) {
|
||||
- if (*s == '\n')
|
||||
+ if (*s == '\t')
|
||||
+ col += (7 - (col % 8)) - 1;
|
||||
+ else if (*s == '\r')
|
||||
+ col = -1;
|
||||
+ else if (*s == '\a')
|
||||
+ --col;
|
||||
+
|
||||
+ if ((soft_width && col >= soft_width) || *s == '\n') {
|
||||
+ if (soft_width) {
|
||||
+ fprintf(fp, "%*s", soft_width - col, "");
|
||||
+ col = 0;
|
||||
+ }
|
||||
ret = fputs(cr_lf ? "\r\n" : "\n", fp);
|
||||
- else if (isprint(*s) || *s == '\a' || *s == '\t' || *s == '\r')
|
||||
+ if (*s == '\n' || ret < 0)
|
||||
+ goto wrote;
|
||||
+ }
|
||||
+
|
||||
+ if (isprint(*s) || *s == '\a' || *s == '\t' || *s == '\r') {
|
||||
ret = putc(*s, fp);
|
||||
- else if (!c_isascii(*s)) {
|
||||
+ ++col;
|
||||
+ } else if (!c_isascii(*s)) {
|
||||
#ifdef HAVE_WIDECHAR
|
||||
wchar_t w;
|
||||
size_t clen = mbtowc(&w, s, slen);
|
||||
@@ -35,21 +53,27 @@ static inline int fputs_careful(const char * s, FILE *fp, const char ctrl, bool
|
||||
case (size_t)-1: // EILSEQ
|
||||
mbtowc(NULL, NULL, 0);
|
||||
nonprint:
|
||||
- ret = fprintf(fp, "\\%3hho", *s);
|
||||
+ col += ret = fprintf(fp, "\\%3hho", *s);
|
||||
break;
|
||||
default:
|
||||
if(!iswprint(w))
|
||||
goto nonprint;
|
||||
ret = fwrite(s, 1, clen, fp);
|
||||
+ if (soft_width)
|
||||
+ col += wcwidth(w);
|
||||
s += clen - 1;
|
||||
slen -= clen - 1;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
- ret = fprintf(fp, "\\%3hho", *s);
|
||||
+ col += ret = fprintf(fp, "\\%3hho", *s);
|
||||
#endif
|
||||
- } else
|
||||
+ } else {
|
||||
ret = fputs((char[]){ ctrl, *s ^ 0x40, '\0' }, fp);
|
||||
+ col += 2;
|
||||
+ }
|
||||
+
|
||||
+ wrote:
|
||||
if (ret < 0)
|
||||
return EOF;
|
||||
}
|
||||
diff --git a/login-utils/last.c b/login-utils/last.c
|
||||
index 1b45dbf24..37c6abe97 100644
|
||||
--- a/login-utils/last.c
|
||||
+++ b/login-utils/last.c
|
||||
@@ -547,7 +547,7 @@ static int list(const struct last_control *ctl, struct utmpx *p, time_t logout_t
|
||||
/*
|
||||
* Print out "final" string safely.
|
||||
*/
|
||||
- fputs_careful(final, stdout, '*', false);
|
||||
+ fputs_careful(final, stdout, '*', false, 0);
|
||||
|
||||
if (len < 0 || (size_t)len >= sizeof(final))
|
||||
putchar('\n');
|
||||
diff --git a/term-utils/wall.c b/term-utils/wall.c
|
||||
index a51a92829..377db4518 100644
|
||||
--- a/term-utils/wall.c
|
||||
+++ b/term-utils/wall.c
|
||||
@@ -274,29 +274,13 @@ int main(int argc, char **argv)
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
-static void buf_putc_careful(FILE *fs, int c)
|
||||
-{
|
||||
- if (isprint(c) || c == '\a' || c == '\t' || c == '\r' || c == '\n')
|
||||
- fputc(c, fs);
|
||||
- else if (!c_isascii(c))
|
||||
- fprintf(fs, "\\%3o", (unsigned char)c);
|
||||
- else
|
||||
- fputs((char[]){ '^', c ^ 0x40, '\0' }, fs);
|
||||
-}
|
||||
-
|
||||
static char *makemsg(char *fname, char **mvec, int mvecsz,
|
||||
size_t *mbufsize, int print_banner)
|
||||
{
|
||||
- register int ch, cnt;
|
||||
- char *p, *lbuf, *retbuf;
|
||||
+ char *lbuf, *retbuf;
|
||||
FILE * fs = open_memstream(&retbuf, mbufsize);
|
||||
- long line_max;
|
||||
-
|
||||
- line_max = sysconf(_SC_LINE_MAX);
|
||||
- if (line_max <= 0)
|
||||
- line_max = 512;
|
||||
-
|
||||
- lbuf = xmalloc(line_max);
|
||||
+ size_t lbuflen = 512;
|
||||
+ lbuf = xmalloc(lbuflen);
|
||||
|
||||
if (print_banner == TRUE) {
|
||||
char *hostname = xgethostname();
|
||||
@@ -329,7 +313,7 @@ static char *makemsg(char *fname, char **mvec, int mvecsz,
|
||||
will not overflow as long as %d takes at most 100 chars */
|
||||
fprintf(fs, "\r%*s\r\n", TERM_WIDTH, " ");
|
||||
|
||||
- snprintf(lbuf, line_max,
|
||||
+ snprintf(lbuf, lbuflen,
|
||||
_("Broadcast message from %s@%s (%s) (%s):"),
|
||||
whom, hostname, where, date);
|
||||
fprintf(fs, "%-*.*s\007\007\r\n", TERM_WIDTH, TERM_WIDTH, lbuf);
|
||||
@@ -373,18 +357,8 @@ static char *makemsg(char *fname, char **mvec, int mvecsz,
|
||||
/*
|
||||
* Read message from stdin.
|
||||
*/
|
||||
- while (fgets(lbuf, line_max, stdin)) {
|
||||
- for (cnt = 0, p = lbuf; (ch = *p) != '\0'; ++p, ++cnt) {
|
||||
- if (cnt == TERM_WIDTH || ch == '\n') {
|
||||
- fprintf(fs, "%*s\r\n", TERM_WIDTH - cnt, "");
|
||||
- cnt = 0;
|
||||
- }
|
||||
- if (ch == '\t')
|
||||
- cnt += (7 - (cnt % 8));
|
||||
- if (ch != '\n')
|
||||
- buf_putc_careful(fs, ch);
|
||||
- }
|
||||
- }
|
||||
+ while (getline(&lbuf, &lbuflen, stdin) >= 0)
|
||||
+ fputs_careful(lbuf, fs, '^', true, TERM_WIDTH);
|
||||
}
|
||||
fprintf(fs, "%*s\r\n", TERM_WIDTH, " ");
|
||||
|
||||
diff --git a/term-utils/write.c b/term-utils/write.c
|
||||
index b485e28fd..a5a21280c 100644
|
||||
--- a/term-utils/write.c
|
||||
+++ b/term-utils/write.c
|
||||
@@ -276,7 +276,7 @@ static void do_write(const struct write_control *ctl)
|
||||
if (signal_received)
|
||||
break;
|
||||
|
||||
- if (fputs_careful(line, stdout, '^', true) == EOF)
|
||||
+ if (fputs_careful(line, stdout, '^', true, 0) == EOF)
|
||||
err(EXIT_FAILURE, _("carefulputc failed"));
|
||||
}
|
||||
free(line);
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
From 3fe8061d4a7cf2e282ef4b67202d351ce05de4d1 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Radu <stefan270101@gmail.com>
|
||||
Date: Tue, 25 Apr 2023 18:55:07 +0300
|
||||
Subject: [PATCH] wrap return in #else directive to avoid dead code
|
||||
|
||||
Signed-off-by: Stefan Radu <stefan270101@gmail.com>
|
||||
---
|
||||
login-utils/su-common.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/login-utils/su-common.c b/login-utils/su-common.c
|
||||
index 67c4fa271..b67492048 100644
|
||||
--- a/login-utils/su-common.c
|
||||
+++ b/login-utils/su-common.c
|
||||
@@ -343,8 +343,9 @@ static int supam_conv( int num_msg,
|
||||
return misc_conv(num_msg, msg, resp, data);
|
||||
#elif defined(HAVE_SECURITY_OPENPAM_H)
|
||||
return openpam_ttyconv(num_msg, msg, resp, data);
|
||||
-#endif
|
||||
+#else
|
||||
return PAM_CONV_ERR;
|
||||
+#endif
|
||||
}
|
||||
|
||||
static void supam_cleanup(struct su_context *su, int retcode)
|
||||
--
|
||||
2.27.0
|
||||
|
||||
199
backport-write-correctly-handle-wide-characters.patch
Normal file
199
backport-write-correctly-handle-wide-characters.patch
Normal file
@ -0,0 +1,199 @@
|
||||
From 8a7b8456d1dc0e7ca557d1ac31f638986704757f Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?=D0=BD=D0=B0=D0=B1?= <nabijaczleweli@nabijaczleweli.xyz>
|
||||
Date: Wed, 15 Mar 2023 16:16:31 +0100
|
||||
Subject: [PATCH] write: correctly handle wide characters
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Do this by replacing fputc_careful() (notice that the description said
|
||||
it's locale-aware ‒ it very much is /not/), with a fputs_careful() which
|
||||
does the same thing, but if it were to output a byte in the \123 format,
|
||||
first it checks whether this byte starts a valid multibyte character.
|
||||
|
||||
If it does, and that character is printable, write it verbatim.
|
||||
This means that
|
||||
echo 'foo åäö ąęćźżń bar' | write nabijaczleweli pts/4
|
||||
instead of
|
||||
foo \303\245\303\244\303\266
|
||||
\304\205\304\231\304\207\305\272\305\274\305\204 bar
|
||||
yields
|
||||
foo åäö ąęćźżń bar
|
||||
or, more realistically, from a message I got earlier today,
|
||||
Filip powiedzia\305\202 \305\274e zap\305\202aci jutro
|
||||
becomes
|
||||
Filip powiedział że zapłaci jutro
|
||||
|
||||
Invalid/non-printable sequences get processed as before.
|
||||
|
||||
Line reading in write must become getline() to avoid dealing with
|
||||
partial characters: for example on input consisting solely of
|
||||
ąęćźżń, where every {1} is an instance, the output would be
|
||||
{42}ąęć\305\272żń{84}ąęćź\305\274ń{84}ąęćźż\305\204{39}
|
||||
with just fixed-512 fgets()
|
||||
|
||||
Bug-Debian: https://bugs.debian.org/826596
|
||||
---
|
||||
include/carefulputc.h | 60 +++++++++++++++++++++++++++++++------------
|
||||
login-utils/last.c | 4 +--
|
||||
term-utils/write.c | 25 +++++-------------
|
||||
3 files changed, 52 insertions(+), 37 deletions(-)
|
||||
|
||||
diff --git a/include/carefulputc.h b/include/carefulputc.h
|
||||
index 8860b1234..740add68e 100644
|
||||
--- a/include/carefulputc.h
|
||||
+++ b/include/carefulputc.h
|
||||
@@ -1,31 +1,59 @@
|
||||
#ifndef UTIL_LINUX_CAREFULPUTC_H
|
||||
#define UTIL_LINUX_CAREFULPUTC_H
|
||||
|
||||
-/*
|
||||
- * A putc() for use in write and wall (that sometimes are sgid tty).
|
||||
- * It avoids control characters in our locale, and also ASCII control
|
||||
- * characters. Note that the locale of the recipient is unknown.
|
||||
-*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
+#ifdef HAVE_WIDECHAR
|
||||
+#include <wctype.h>
|
||||
+#endif
|
||||
+#include <stdbool.h>
|
||||
|
||||
#include "cctype.h"
|
||||
|
||||
-static inline int fputc_careful(int c, FILE *fp, const char fail)
|
||||
+/*
|
||||
+ * A puts() for use in write and wall (that sometimes are sgid tty).
|
||||
+ * It avoids control and invalid characters.
|
||||
+ * The locale of the recipient is nominally unknown,
|
||||
+ * but it's a solid bet that the encoding is compatible with the author's.
|
||||
+ */
|
||||
+static inline int fputs_careful(const char * s, FILE *fp, const char ctrl, bool cr_lf)
|
||||
{
|
||||
- int ret;
|
||||
+ int ret = 0;
|
||||
|
||||
- if (isprint(c) || c == '\a' || c == '\t' || c == '\r' || c == '\n')
|
||||
- ret = putc(c, fp);
|
||||
- else if (!c_isascii(c))
|
||||
- ret = fprintf(fp, "\\%3o", (unsigned char)c);
|
||||
- else {
|
||||
- ret = putc(fail, fp);
|
||||
- if (ret != EOF)
|
||||
- ret = putc(c ^ 0x40, fp);
|
||||
+ for (size_t slen = strlen(s); *s; ++s, --slen) {
|
||||
+ if (*s == '\n')
|
||||
+ ret = fputs(cr_lf ? "\r\n" : "\n", fp);
|
||||
+ else if (isprint(*s) || *s == '\a' || *s == '\t' || *s == '\r')
|
||||
+ ret = putc(*s, fp);
|
||||
+ else if (!c_isascii(*s)) {
|
||||
+#ifdef HAVE_WIDECHAR
|
||||
+ wchar_t w;
|
||||
+ size_t clen = mbtowc(&w, s, slen);
|
||||
+ switch(clen) {
|
||||
+ case (size_t)-2: // incomplete
|
||||
+ case (size_t)-1: // EILSEQ
|
||||
+ mbtowc(NULL, NULL, 0);
|
||||
+ nonprint:
|
||||
+ ret = fprintf(fp, "\\%3hho", *s);
|
||||
+ break;
|
||||
+ default:
|
||||
+ if(!iswprint(w))
|
||||
+ goto nonprint;
|
||||
+ ret = fwrite(s, 1, clen, fp);
|
||||
+ s += clen - 1;
|
||||
+ slen -= clen - 1;
|
||||
+ break;
|
||||
+ }
|
||||
+#else
|
||||
+ ret = fprintf(fp, "\\%3hho", *s);
|
||||
+#endif
|
||||
+ } else
|
||||
+ ret = fputs((char[]){ ctrl, *s ^ 0x40, '\0' }, fp);
|
||||
+ if (ret < 0)
|
||||
+ return EOF;
|
||||
}
|
||||
- return (ret < 0) ? EOF : 0;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static inline void fputs_quoted_case(const char *data, FILE *out, int dir)
|
||||
diff --git a/login-utils/last.c b/login-utils/last.c
|
||||
index d3eeed4b6..1b45dbf24 100644
|
||||
--- a/login-utils/last.c
|
||||
+++ b/login-utils/last.c
|
||||
@@ -392,7 +392,6 @@ static int list(const struct last_control *ctl, struct utmpx *p, time_t logout_t
|
||||
char final[512];
|
||||
char utline[sizeof(p->ut_line) + 1];
|
||||
char domain[256];
|
||||
- char *s;
|
||||
int mins, hours, days;
|
||||
int r, len;
|
||||
struct last_timefmt *fmt;
|
||||
@@ -548,8 +547,7 @@ static int list(const struct last_control *ctl, struct utmpx *p, time_t logout_t
|
||||
/*
|
||||
* Print out "final" string safely.
|
||||
*/
|
||||
- for (s = final; *s; s++)
|
||||
- fputc_careful(*s, stdout, '*');
|
||||
+ fputs_careful(final, stdout, '*', false);
|
||||
|
||||
if (len < 0 || (size_t)len >= sizeof(final))
|
||||
putchar('\n');
|
||||
diff --git a/term-utils/write.c b/term-utils/write.c
|
||||
index 8b86e9a9d..b485e28fd 100644
|
||||
--- a/term-utils/write.c
|
||||
+++ b/term-utils/write.c
|
||||
@@ -223,21 +223,6 @@ static void signal_handler(int signo)
|
||||
signal_received = signo;
|
||||
}
|
||||
|
||||
-/*
|
||||
- * write_line - like fputs(), but makes control characters visible and
|
||||
- * turns \n into \r\n.
|
||||
- */
|
||||
-static void write_line(char *s)
|
||||
-{
|
||||
- while (*s) {
|
||||
- const int c = *s++;
|
||||
-
|
||||
- if ((c == '\n' && fputc_careful('\r', stdout, '^') == EOF)
|
||||
- || fputc_careful(c, stdout, '^') == EOF)
|
||||
- err(EXIT_FAILURE, _("carefulputc failed"));
|
||||
- }
|
||||
-}
|
||||
-
|
||||
/*
|
||||
* do_write - actually make the connection
|
||||
*/
|
||||
@@ -247,7 +232,8 @@ static void do_write(const struct write_control *ctl)
|
||||
struct passwd *pwd;
|
||||
time_t now;
|
||||
struct tm *tm;
|
||||
- char *host, line[512];
|
||||
+ char *host, *line = NULL;
|
||||
+ size_t linelen = 0;
|
||||
struct sigaction sigact;
|
||||
|
||||
/* Determine our login name(s) before the we reopen() stdout */
|
||||
@@ -286,11 +272,14 @@ static void do_write(const struct write_control *ctl)
|
||||
free(host);
|
||||
printf("\r\n");
|
||||
|
||||
- while (fgets(line, sizeof(line), stdin) != NULL) {
|
||||
+ while (getline(&line, &linelen, stdin) >= 0) {
|
||||
if (signal_received)
|
||||
break;
|
||||
- write_line(line);
|
||||
+
|
||||
+ if (fputs_careful(line, stdout, '^', true) == EOF)
|
||||
+ err(EXIT_FAILURE, _("carefulputc failed"));
|
||||
}
|
||||
+ free(line);
|
||||
printf("EOF\r\n");
|
||||
}
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
Name: util-linux
|
||||
Version: 2.37.2
|
||||
Release: 18
|
||||
Release: 19
|
||||
Summary: A random collection of Linux utilities
|
||||
License: GPLv2 and GPLv2+ and LGPLv2+ and BSD with advertising and Public Domain
|
||||
URL: https://git.kernel.org/pub/scm/utils/util-linux/util-linux.git
|
||||
@ -93,6 +93,17 @@ Patch6071: backport-mkswap-do-not-use-uninitialized-stack-value.patch
|
||||
Patch6072: backport-lib-pager-fix-signal-safety-issues.patch
|
||||
Patch6073: backport-libblkid-nvidia_raid-verify-superblock-size.patch
|
||||
Patch6074: backport-libblkid-nvidia_raid-validate-checksum.patch
|
||||
Patch6075: backport-libfdisk-Fix-randomly-generated-GPT-UUID-s.patch
|
||||
Patch6076: backport-write-correctly-handle-wide-characters.patch
|
||||
Patch6077: backport-wall-convert-homebrew-buffering-to-open_memstream.patch
|
||||
Patch6078: backport-wall-use-fputs_careful.patch
|
||||
Patch6079: backport-hexdump-parse-handle-truncated-format-pattern.patch
|
||||
Patch6080: backport-libblkid-copy-BLKID_PARTS_FORCE_GPT-to-whole-disk-pr.patch
|
||||
Patch6081: backport-lscpu-fix-p-output-all-caches-delimiter.patch
|
||||
Patch6082: backport-add-return-in-supam_conv-function.patch
|
||||
Patch6083: backport-wrap-return-in-else-directive-to-avoid-dead-code.patch
|
||||
Patch6084: backport-sulogin-ignore-none-existing-console-devices.patch
|
||||
Patch6085: backport-sulogin-fix-KDGKBMODE-ifdef.patch
|
||||
|
||||
Patch9000: Add-check-to-resolve-uname26-version-test-failed.patch
|
||||
Patch9001: SKIPPED-no-root-permissions-test.patch
|
||||
@ -464,6 +475,23 @@ fi
|
||||
%{_mandir}/man8/{swapoff.8*,swapon.8*,switch_root.8*,umount.8*,wdctl.8.gz,wipefs.8*,zramctl.8*}
|
||||
|
||||
%changelog
|
||||
* Mon Jun 5 2023 zhangyao <zhangyao108@huawei.com> - 2.37.2-19
|
||||
- Type:bugfix
|
||||
- CVE:NA
|
||||
- SUG:NA
|
||||
- DESC:sync community patches
|
||||
[add]backport-libfdisk-Fix-randomly-generated-GPT-UUID-s.patch
|
||||
backport-write-correctly-handle-wide-characters.patch
|
||||
backport-wall-convert-homebrew-buffering-to-open_memstream.patch
|
||||
backport-wall-use-fputs_careful.patch
|
||||
backport-hexdump-parse-handle-truncated-format-pattern.patch
|
||||
backport-libblkid-copy-BLKID_PARTS_FORCE_GPT-to-whole-disk-pr.patch
|
||||
backport-lscpu-fix-p-output-all-caches-delimiter.patch
|
||||
backport-add-return-in-supam_conv-function.patch
|
||||
backport-wrap-return-in-else-directive-to-avoid-dead-code.patch
|
||||
backport-sulogin-ignore-none-existing-console-devices.patch
|
||||
backport-sulogin-fix-KDGKBMODE-ifdef.patch
|
||||
|
||||
* Fri May 12 2023 zhangyao <zhangyao108@huawei.com> - 2.37.2-18
|
||||
- Type:bugfix
|
||||
- CVE:NA
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user