From 937beaa81b3e64728fa835e1f1e339ee3bbade9c0ddc539cefc321bd13ef402a Mon Sep 17 00:00:00 2001 From: "Dr. Werner Fink" Date: Tue, 12 Dec 2017 16:12:12 +0000 Subject: [PATCH] Accepting request 556516 from home:pmladek:branches:Base:System - hardening of the console list generation (bsc#1071568): * libconsole-never-return-empty-list-from-getconsoles.patch * libconsole-Really-allow-to-use-dev-console-as-a-fall.patch * libconsole-Add-console-into-the-list-only-when-succe.patch * libconsole-Correctly-ignore-early-consoles.patch OBS-URL: https://build.opensuse.org/request/show/556516 OBS-URL: https://build.opensuse.org/package/show/Base:System/blog?expand=0&rev=26 --- blog.changes | 9 ++ blog.spec | 12 ++ ...onsole-into-the-list-only-when-succe.patch | 112 ++++++++++++++++++ ...sole-Correctly-ignore-early-consoles.patch | 55 +++++++++ ...y-allow-to-use-dev-console-as-a-fall.patch | 36 ++++++ ...r-return-empty-list-from-getconsoles.patch | 39 ++++++ 6 files changed, 263 insertions(+) create mode 100644 libconsole-Add-console-into-the-list-only-when-succe.patch create mode 100644 libconsole-Correctly-ignore-early-consoles.patch create mode 100644 libconsole-Really-allow-to-use-dev-console-as-a-fall.patch create mode 100644 libconsole-never-return-empty-list-from-getconsoles.patch diff --git a/blog.changes b/blog.changes index 8e5d9a2..dcb0fbf 100644 --- a/blog.changes +++ b/blog.changes @@ -1,3 +1,12 @@ +------------------------------------------------------------------- +Tue Dec 12 15:30:53 UTC 2017 - pmladek@suse.com + +- hardening of the console list generation (bsc#1071568): + * libconsole-never-return-empty-list-from-getconsoles.patch + * libconsole-Really-allow-to-use-dev-console-as-a-fall.patch + * libconsole-Add-console-into-the-list-only-when-succe.patch + * libconsole-Correctly-ignore-early-consoles.patch + ------------------------------------------------------------------- Mon Nov 6 09:28:13 UTC 2017 - werner@suse.de diff --git a/blog.spec b/blog.spec index 4331976..f829ca4 100644 --- a/blog.spec +++ b/blog.spec @@ -29,6 +29,14 @@ BuildRequires: suse-module-tools Requires(post): coreutils BuildRoot: %{_tmppath}/%{name}-%{version}-build Provides: sysvinit-tools:/sbin/blogd +# PATCH-FIX-UPSTREAM libconsole-never-return-empty-list-from-getconsoles.patch bsc#1071568 +Patch0: libconsole-never-return-empty-list-from-getconsoles.patch +# PATCH-FIX-UPSTREAM libconsole-Really-allow-to-use-dev-console-as-a-fall.patch bsc#1071568 +Patch1: libconsole-Really-allow-to-use-dev-console-as-a-fall.patch +# PATCH-FIX-UPSTREAM libconsole-Add-console-into-the-list-only-when-succe.patch bsc#1071568 +Patch2: libconsole-Add-console-into-the-list-only-when-succe.patch +# PATCH-FIX-UPSTREAM libconsole-Correctly-ignore-early-consoles.patch bsc#1071568 +Patch3: libconsole-Correctly-ignore-early-consoles.patch %description The blogd daemon determines the real underlying character device of @@ -66,6 +74,10 @@ the LSB startproc command. %prep %setup -q -n showconsole-%version +%patch0 -p1 +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 %build make %{?_smp_mflags} CC="%__cc" \ diff --git a/libconsole-Add-console-into-the-list-only-when-succe.patch b/libconsole-Add-console-into-the-list-only-when-succe.patch new file mode 100644 index 0000000..08e39f8 --- /dev/null +++ b/libconsole-Add-console-into-the-list-only-when-succe.patch @@ -0,0 +1,112 @@ +From: Petr Mladek +Date: Tue, 12 Dec 2017 11:41:19 +0100 +Subject: libconsole: Add console into the list only when successfully allocated +Git-commit: 34a74a07c05d53f7c71bf7ba44a48f8be32942fd +References: bsc#1071568 +Upstream: merged + +consalloc() initializes the console when it is used from blogd (io = 1). +This operation might fail when the related tty device cannot be opened. +The structure is freed in this case but it was already added into +the list before. This might cause access to a freed memory. + +This patch moves the initialization code into a separate function. +The structure is added to the list only when the initialization +succeeds. It is freed otherwise. + +Signed-off-by: Petr Mladek +--- + libconsole/console.c | 57 +++++++++++++++++++++++++++++----------------------- + 1 file changed, 32 insertions(+), 25 deletions(-) + +diff --git a/libconsole/console.c b/libconsole/console.c +index 600e22608630..47e95a4b9046 100644 +--- a/libconsole/console.c ++++ b/libconsole/console.c +@@ -531,13 +531,39 @@ void closeIO(void) + return; + } + ++static int consinitIO(struct console *newc) ++{ ++ int tflags; ++ ++ if ((newc->fd = open(newc->tty, O_WRONLY|O_NONBLOCK|O_NOCTTY)) < 0) { ++ if (errno == EACCES) ++ error("can not open %s", newc->tty); ++ warn("can not open %s", newc->tty); ++ return 0; ++ } ++ ++ newc->tlock = 0; ++ newc->max_canon = _POSIX_MAX_CANON; ++ memset(&newc->ltio, 0, sizeof(newc->ltio)); ++ memset(&newc->otio, 0, sizeof(newc->otio)); ++ memset(&newc->ctio, 0, sizeof(newc->ctio)); ++ if ((tflags = fcntl(newc->fd, F_GETFL)) < 0) ++ warn("can not get terminal flags of %s", newc->tty); ++ ++ tflags &= ~(O_NONBLOCK); ++ tflags |= O_NOCTTY; ++ if (fcntl(newc->fd, F_SETFL, tflags) < 0) ++ warn("can not set terminal flags of %s", newc->tty); ++ ++ return 1; ++} ++ + /* Allocate a console */ + static list_t lcons = { &(lcons), &(lcons) }; + static int consalloc(struct console **cons, char *name, const int cflags, const dev_t dev, int io) + { + struct console *newc; + list_t *head; +- int tflags; + + if (!cons) + error("missing console pointer"); +@@ -551,6 +577,11 @@ static int consalloc(struct console **cons, char *name, const int cflags, const + newc->dev = dev; + newc->pid = -1; + ++ if (io && !consinitIO(newc)) { ++ free(newc); ++ return 0; ++ } ++ + if (!*cons) { + head = &lcons; + *cons = (struct console*)head; +@@ -558,30 +589,6 @@ static int consalloc(struct console **cons, char *name, const int cflags, const + head = &(*cons)->node; + insert(&newc->node, head); + +- if (!io) +- return 1; +- +- if ((newc->fd = open(newc->tty, O_WRONLY|O_NONBLOCK|O_NOCTTY)) < 0) { +- if (errno == EACCES) +- error("can not open %s", newc->tty); +- warn("can not open %s", newc->tty); +- free(newc); +- return 0; +- } +- +- newc->tlock = 0; +- newc->max_canon = _POSIX_MAX_CANON; +- memset(&newc->ltio, 0, sizeof(newc->ltio)); +- memset(&newc->otio, 0, sizeof(newc->otio)); +- memset(&newc->ctio, 0, sizeof(newc->ctio)); +- if ((tflags = fcntl(newc->fd, F_GETFL)) < 0) +- warn("can not get terminal flags of %s", newc->tty); +- +- tflags &= ~(O_NONBLOCK); +- tflags |= O_NOCTTY; +- if (fcntl(newc->fd, F_SETFL, tflags) < 0) +- warn("can not set terminal flags of %s", newc->tty); +- + return 1; + } + +-- +2.13.6 + diff --git a/libconsole-Correctly-ignore-early-consoles.patch b/libconsole-Correctly-ignore-early-consoles.patch new file mode 100644 index 0000000..40f4842 --- /dev/null +++ b/libconsole-Correctly-ignore-early-consoles.patch @@ -0,0 +1,55 @@ +From: Petr Mladek +Date: Tue, 12 Dec 2017 12:49:39 +0100 +Subject: libconsole: Correctly ignore early consoles +Git-commit: 08b7314b53524040a16ce2a7f95a73304c55db30 +References: bsc#1071568 +Upstream: merged + +There might be consoles without tty binding. These do not have +defined major and minor numbers in the /proc/consoles list. +For example, it might look like: + +$> cat /proc/consoles +pl11 -W- (E Bp ) +ttyAMA0 -W- (EC p a) 204:64 + +Let's just ignore them. + +Signed-off-by: Petr Mladek +--- + libconsole/console.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/libconsole/console.c b/libconsole/console.c +index 47e95a4b9046..c4396b1f9b5e 100644 +--- a/libconsole/console.c ++++ b/libconsole/console.c +@@ -609,6 +609,7 @@ void getconsoles(struct console **cons, int io) + char fbuf[16], dev[64]; + char *tty = NULL; + FILE *fc; ++ int items; + + if (!cons) + error("error: console pointer empty"); +@@ -621,11 +622,16 @@ void getconsoles(struct console **cons, int io) + goto err; + } + +- while ((fscanf(fc, "%*s %*s (%[^)]) %[0-9:]", &fbuf[0], &dev[0]) == 2)) { ++ while ((items = fscanf(fc, "%*s %*s (%[^)]) %[0-9:]", &fbuf[0], &dev[0])) ++ != EOF) { + char *tmp; + int flags, n, maj, min; + int ret; + ++ /* Ignore consoles without tty binding. */ ++ if (items != 2) ++ continue; ++ + if (!strchr(fbuf, 'E')) + continue; + +-- +2.13.6 + diff --git a/libconsole-Really-allow-to-use-dev-console-as-a-fall.patch b/libconsole-Really-allow-to-use-dev-console-as-a-fall.patch new file mode 100644 index 0000000..a4a714a --- /dev/null +++ b/libconsole-Really-allow-to-use-dev-console-as-a-fall.patch @@ -0,0 +1,36 @@ +From: Petr Mladek +Date: Mon, 11 Dec 2017 16:40:39 +0100 +Subject: libconsole: Really allow to use /dev/console as a fallback in showconsole +Git-commit: 19329e59e442c81d270028cbc945fe83a9732327 +References: bsc#1071568 +Upstream: merged + +consalloc() always returns an error when it is called from +showconsole (with io = 0). As a result, /dev/console is ignored +because it is not assigned to the global "cons" pointer +in getconsoles(). + +consalloc() should return success (1) when the console is added +to the list and the io-related operations are skipped. + +Signed-off-by: Petr Mladek +--- + libconsole/console.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libconsole/console.c b/libconsole/console.c +index 2f6e0b1d56d9..600e22608630 100644 +--- a/libconsole/console.c ++++ b/libconsole/console.c +@@ -559,7 +559,7 @@ static int consalloc(struct console **cons, char *name, const int cflags, const + insert(&newc->node, head); + + if (!io) +- return 0; ++ return 1; + + if ((newc->fd = open(newc->tty, O_WRONLY|O_NONBLOCK|O_NOCTTY)) < 0) { + if (errno == EACCES) +-- +2.13.6 + diff --git a/libconsole-never-return-empty-list-from-getconsoles.patch b/libconsole-never-return-empty-list-from-getconsoles.patch new file mode 100644 index 0000000..61b8880 --- /dev/null +++ b/libconsole-never-return-empty-list-from-getconsoles.patch @@ -0,0 +1,39 @@ +From: Petr Mladek +Date: Mon, 11 Dec 2017 16:32:11 +0100 +Subject: libconsole: never return empty list from getconsoles() +Git-commit: d7fe84cd6198c4acc00a59d7c403fe6bdc3f509a +References: bsc#1071568 +Upstream: merged + +getconsoles() users expect that they get a non-empty list of consoles. +Otherwise, they might access an invalid memory. + +There is an attempt to create fallback to /dev/console but it is +used (assigned to *cons) only when the corresponding consalloc() +passes. Otherwise, we should printk an error and exit. + +Signed-off-by: Petr Mladek +--- + libconsole/console.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/libconsole/console.c b/libconsole/console.c +index 2c6bbac8989f..2f6e0b1d56d9 100644 +--- a/libconsole/console.c ++++ b/libconsole/console.c +@@ -662,8 +662,10 @@ err: + if (!tty) + error("can not allocate string"); + +- if (consalloc(&c, tty, CON_CONSDEV, makedev(TTYAUX_MAJOR, 1), io)) +- *cons = c; ++ if (!consalloc(&c, tty, CON_CONSDEV, makedev(TTYAUX_MAJOR, 1), io)) ++ error("/dev/console is not a valid fallback\n"); ++ ++ *cons = c; + } + + /* +-- +2.13.6 +