aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAriadne Conill <ariadne@dereferenced.org>2021-06-08 00:58:25 -0600
committerAriadne Conill <ariadne@dereferenced.org>2021-06-08 01:06:03 -0600
commit10a16a5c1bb8687e8da172fc99c3a6da655cb322 (patch)
treed46a5cec3c828d53b574a7ad6e3aac4f5fc70a3f
parent8c57e213af9540a4d61a47260aec48d7751e1682 (diff)
downloadaports-10a16a5c1bb8687e8da172fc99c3a6da655cb322.tar.gz
aports-10a16a5c1bb8687e8da172fc99c3a6da655cb322.tar.bz2
aports-10a16a5c1bb8687e8da172fc99c3a6da655cb322.tar.xz
main/openrc: add mitigation for CVE-2018-21269
-rw-r--r--main/openrc/APKBUILD16
-rw-r--r--main/openrc/CVE-2018-21269.patch244
2 files changed, 256 insertions, 4 deletions
diff --git a/main/openrc/APKBUILD b/main/openrc/APKBUILD
index d647c6eb4e..3813917c64 100644
--- a/main/openrc/APKBUILD
+++ b/main/openrc/APKBUILD
@@ -2,7 +2,7 @@
pkgname=openrc
pkgver=0.41.2
_ver=${pkgver/_git*/}
-pkgrel=1
+pkgrel=2
pkgdesc="OpenRC manages the services, startup and shutdown of a host"
url="https://github.com/OpenRC/openrc"
arch="all"
@@ -25,6 +25,8 @@ source="$pkgname-$pkgver.tar.gz::https://github.com/OpenRC/openrc/archive/$pkgve
0009-Support-early-loading-of-keymap-if-kdb-is-installed.patch
0010-Allow-0-respawn-max.patch
+ CVE-2018-21269.patch
+
openrc.logrotate
hostname.initd
hwdrivers.initd
@@ -37,6 +39,10 @@ source="$pkgname-$pkgver.tar.gz::https://github.com/OpenRC/openrc/archive/$pkgve
"
builddir="$srcdir/$pkgname-$_ver"
+# secfixes:
+# 0.41.2-r2:
+# - CVE-2018-21269
+
prepare() {
default_prepare
sed -i -e '/^sed/d' "$builddir"/pkgconfig/Makefile
@@ -113,8 +119,8 @@ zshcomp() {
"$subpkgdir"/usr/share/zsh
rm -rf "$pkgdir"/usr/share/zsh
}
-
-sha512sums="ebfa691cae4704bb3023ea0508a712a45b8c20809828729dfa5292e96f3fd1b309813d80d7c286d0c09680bf5378aba40cfd994f27951f43a3ffb1fd0d69a58b openrc-0.41.2.tar.gz
+sha512sums="
+ebfa691cae4704bb3023ea0508a712a45b8c20809828729dfa5292e96f3fd1b309813d80d7c286d0c09680bf5378aba40cfd994f27951f43a3ffb1fd0d69a58b openrc-0.41.2.tar.gz
71fce711adbcb411189a089f1d49567c50348e12c42b7a9c9b582dae5d18051f88ccf81c768337e87d6792d953e84d1e8b93d7978a1947d7d20ef3b1cd330875 0001-call-sbin-mkmntdirs-in-localmount-OpenRC-service.patch
b1cedd38badda4fc308decdff06f9644b96fe35617792da8d6d62407409841705fd71b5b57d1804a6395095604a70898f80830c76395ec99f715038a0809d815 0002-force-root-be-rw-before-localmount.patch
9dea3fcdb90e3e8078a771beefeba3ca91b9966a1b8ee9ff96cf460e7dd21abbc4a46a501a960c3edf5a76c083c2cf60ccb06d9da7a4c6df2a50660745beb278 0003-sysctl-add-compatibility-for-busybox-sysctl.patch
@@ -125,6 +131,7 @@ dbe3f170440f0f357f31ac4d49c56a9a7ec22172df2701bf4a0afdee22aedda1f88b9fa5ffdbe19a
d2b8700f56b05579926352855de8fcee5cf78f0c13200643a5195f8c60e2b5082d476b42cc77b13246b9fb883aa002d723237b0fc7ae84ccd7ebe3b25690cf50 0008-fix-undeclared-UT_LINESIZE.patch
667085d89e194f7e2255d5c098c3d8de272f54cb925710cb98d5e7a6b58982d0acfe15f97b574cfc646b139cd7aa5b527ba700ef9b8048a6d6d9dee8cc74913c 0009-Support-early-loading-of-keymap-if-kdb-is-installed.patch
275d3e65fa84aaf06f908bf5c99c8e1243acb691fc931b28b2276b586b55b6198986ed9080c28fb2b598b7bdb2d577439031bea6d232eac0d8f9d8f5cb373fa3 0010-Allow-0-respawn-max.patch
+715016b4f481a6d4d2ab37d23659e6cacc023b02fa6908b566391ee2744369076ea74e54f0fe576e2cc1d3371d4d9e3818395ca3f417233358fc70a9edc4dba6 CVE-2018-21269.patch
12bb6354e808fbf47bbab963de55ee7901738b4a912659982c57ef2777fff9a670e867fcb8ec316a76b151032c92dc89a950d7d1d835ef53f753a8f3b41d2cec openrc.logrotate
259552165ee5e9ca973bbe18d1d9ec5cc67526cb26a9e0ac717076ef4913bb7ff4055d6ccb9f77996ed9c00b67f46edba552e1a21b836068a112dda2428502b3 hostname.initd
c06eac7264f6cc6888563feeae5ca745aae538323077903de1b19102e4f16baa34c18b8c27af5dd5423e7670834e2261e9aa55f2b1ec8d8fdc2be105fe894d55 hwdrivers.initd
@@ -133,4 +140,5 @@ b04058ec630e19de0bafefe06198dc1bff8c8d5d2c89e4660dd83dda8bb82a76cdb1d8661cce88e4
55df0ac13dac1f215f0c573ac07b150d31232a5204eccfc8941d5af73f91b4535a85d79b7f6514217038ecbe6bffa28cb83fd8d46fd4c596e07103deb8bc8a57 networking.initd
80e43ded522e2d48b876131c7c9997debd43f3790e0985801a8c1dd60bc6e09f625b35a127bf225eb45a65eec7808a50d1c08a5e8abceafc61726211e061e0a2 modloop.confd
d76c75c58e6f4b0801edac4e081b725ef3d50a9a8c9bbb5692bf4d0f804af7d383bf71a73d5d03ed348a89741ef0b2427eb6a7cbf5a9b9ff60a240639fa6ec88 sysfsconf.initd
-f65b061b4272463071022e88a7392d5573f2d95f91e42c8b4f3ef69171604460ddd3d426dfbab382f73a3fac68d4b4ff3a923fdc49fb6fd9f27ebd3ab24e0d0e firstboot.initd"
+f65b061b4272463071022e88a7392d5573f2d95f91e42c8b4f3ef69171604460ddd3d426dfbab382f73a3fac68d4b4ff3a923fdc49fb6fd9f27ebd3ab24e0d0e firstboot.initd
+"
diff --git a/main/openrc/CVE-2018-21269.patch b/main/openrc/CVE-2018-21269.patch
new file mode 100644
index 0000000000..9975d7bf81
--- /dev/null
+++ b/main/openrc/CVE-2018-21269.patch
@@ -0,0 +1,244 @@
+From 577f00abe5f8ec6da40ac79d77df3e514593090d Mon Sep 17 00:00:00 2001
+From: William Hubbs <w.d.hubbs@gmail.com>
+Date: Wed, 11 Nov 2020 10:28:50 -0600
+Subject: [PATCH] checkpath: fix CVE-2018-21269
+
+This walks the directory path to the file we are going to manipulate to make
+sure that when we create the file and change the ownership and permissions
+we are working on the same file.
+Also, all non-terminal symbolic links must be owned by root. This will
+keep a non-root user from making a symbolic link as described in the
+bug. If root creates the symbolic link, it is assumed to be trusted.
+
+On non-linux platforms, we no longer follow non-terminal symbolic links
+by default. If you need to do that, add the -s option on the checkpath
+command line, but keep in mind that this is not secure.
+
+This fixes #201.
+---
+ man/openrc-run.8 | 6 +++
+ src/rc/checkpath.c | 103 ++++++++++++++++++++++++++++++++++++++++++---
+ 2 files changed, 102 insertions(+), 7 deletions(-)
+
+diff --git a/man/openrc-run.8 b/man/openrc-run.8
+index 1102daaa..ec4b88de 100644
+--- a/man/openrc-run.8
++++ b/man/openrc-run.8
+@@ -461,6 +461,7 @@ Mark the service as inactive.
+ .Op Fl p , -pipe
+ .Op Fl m , -mode Ar mode
+ .Op Fl o , -owner Ar owner
++.Op Fl s , -symlinks
+ .Op Fl W , -writable
+ .Op Fl q , -quiet
+ .Ar path ...
+@@ -481,6 +482,11 @@ or with names, and are separated by a colon.
+ The truncate options (-D and -F) cause the directory or file to be
+ cleared of all contents.
+ .Pp
++If -s is not specified on a non-linux platform, checkpath will refuse to
++allow non-terminal symbolic links to exist in the path. This is for
++security reasons so that a non-root user can't create a symbolic link to
++a root-owned file and take ownership of that file.
++.Pp
+ If -W is specified, checkpath checks to see if the first path given on
+ the command line is writable. This is different from how the test
+ command in the shell works, because it also checks to make sure the file
+diff --git a/src/rc/checkpath.c b/src/rc/checkpath.c
+index 448c9cf8..ff54a892 100644
+--- a/src/rc/checkpath.c
++++ b/src/rc/checkpath.c
+@@ -16,6 +16,7 @@
+ * except according to the terms contained in the LICENSE file.
+ */
+
++#define _GNU_SOURCE
+ #include <sys/types.h>
+ #include <sys/stat.h>
+
+@@ -23,6 +24,7 @@
+ #include <fcntl.h>
+ #include <getopt.h>
+ #include <grp.h>
++#include <libgen.h>
+ #include <pwd.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+@@ -44,7 +46,7 @@ typedef enum {
+
+ const char *applet = NULL;
+ const char *extraopts ="path1 [path2] [...]";
+-const char *getoptstring = "dDfFpm:o:W" getoptstring_COMMON;
++const char *getoptstring = "dDfFpm:o:sW" getoptstring_COMMON;
+ const struct option longopts[] = {
+ { "directory", 0, NULL, 'd'},
+ { "directory-truncate", 0, NULL, 'D'},
+@@ -53,6 +55,7 @@ const struct option longopts[] = {
+ { "pipe", 0, NULL, 'p'},
+ { "mode", 1, NULL, 'm'},
+ { "owner", 1, NULL, 'o'},
++ { "symlinks", 0, NULL, 's'},
+ { "writable", 0, NULL, 'W'},
+ longopts_COMMON
+ };
+@@ -64,15 +67,92 @@ const char * const longopts_help[] = {
+ "Create a named pipe (FIFO) if not exists",
+ "Mode to check",
+ "Owner to check (user:group)",
++ "follow symbolic links (irrelivent on linux)",
+ "Check whether the path is writable or not",
+ longopts_help_COMMON
+ };
+ const char *usagestring = NULL;
+
++static int get_dirfd(char *path, bool symlinks) {
++ char *ch;
++ char *item;
++ char *linkpath = NULL;
++ char *path_dupe;
++ char *str;
++ int components = 0;
++ int dirfd;
++ int flags = 0;
++ int new_dirfd;
++ struct stat st;
++ ssize_t linksize;
++
++ if (!path || *path != '/')
++ eerrorx("%s: empty or relative path", applet);
++ dirfd = openat(dirfd, "/", O_RDONLY);
++ if (dirfd == -1)
++ eerrorx("%s: unable to open the root directory: %s",
++ applet, strerror(errno));
++ path_dupe = xstrdup(path);
++ ch = path_dupe;
++ while (*ch) {
++ if (*ch == '/')
++ components++;
++ ch++;
++ }
++ item = strtok(path_dupe, "/");
++#ifdef O_PATH
++ flags |= O_PATH;
++#endif
++ if (!symlinks)
++ flags |= O_NOFOLLOW;
++ flags |= O_RDONLY;
++ while (dirfd > 0 && item && components > 1) {
++ str = xstrdup(linkpath ? linkpath : item);
++ new_dirfd = openat(dirfd, str, flags);
++ if (new_dirfd == -1)
++ eerrorx("%s: %s: could not open %s: %s", applet, path, str,
++ strerror(errno));
++ if (fstat(new_dirfd, &st) == -1)
++ eerrorx("%s: %s: unable to stat %s: %s", applet, path, item,
++ strerror(errno));
++ if (S_ISLNK(st.st_mode) ) {
++ if (st.st_uid != 0)
++ eerrorx("%s: %s: synbolic link %s not owned by root",
++ applet, path, str);
++ linksize = st.st_size+1;
++ if (linkpath)
++ free(linkpath);
++ linkpath = xmalloc(linksize);
++ memset(linkpath, 0, linksize);
++ if (readlinkat(new_dirfd, "", linkpath, linksize) != st.st_size)
++ eerrorx("%s: symbolic link destination changed", applet);
++ /*
++ * now follow the symlink.
++ */
++ close(new_dirfd);
++ } else {
++ close(dirfd);
++ dirfd = new_dirfd;
++ free(linkpath);
++ linkpath = NULL;
++ item = strtok(NULL, "/");
++ components--;
++ }
++ }
++ free(path_dupe);
++ if (linkpath) {
++ free(linkpath);
++ linkpath = NULL;
++ }
++ return dirfd;
++}
++
+ static int do_check(char *path, uid_t uid, gid_t gid, mode_t mode,
+- inode_t type, bool trunc, bool chowner, bool selinux_on)
++ inode_t type, bool trunc, bool chowner, bool symlinks, bool selinux_on)
+ {
+ struct stat st;
++ char *name = NULL;
++ int dirfd;
+ int fd;
+ int flags;
+ int r;
+@@ -93,14 +173,16 @@ static int do_check(char *path, uid_t uid, gid_t gid, mode_t mode,
+ #endif
+ if (trunc)
+ flags |= O_TRUNC;
+- readfd = open(path, readflags);
++ xasprintf(&name, "%s", basename_c(path));
++ dirfd = get_dirfd(path, symlinks);
++ readfd = openat(dirfd, name, readflags);
+ if (readfd == -1 || (type == inode_file && trunc)) {
+ if (type == inode_file) {
+ einfo("%s: creating file", path);
+ if (!mode) /* 664 */
+ mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH;
+ u = umask(0);
+- fd = open(path, flags, mode);
++ fd = openat(dirfd, name, flags, mode);
+ umask(u);
+ if (fd == -1) {
+ eerror("%s: open: %s", applet, strerror(errno));
+@@ -122,7 +204,7 @@ static int do_check(char *path, uid_t uid, gid_t gid, mode_t mode,
+ strerror (errno));
+ return -1;
+ }
+- readfd = open(path, readflags);
++ readfd = openat(dirfd, name, readflags);
+ if (readfd == -1) {
+ eerror("%s: unable to open directory: %s", applet,
+ strerror(errno));
+@@ -140,7 +222,7 @@ static int do_check(char *path, uid_t uid, gid_t gid, mode_t mode,
+ strerror (errno));
+ return -1;
+ }
+- readfd = open(path, readflags);
++ readfd = openat(dirfd, name, readflags);
+ if (readfd == -1) {
+ eerror("%s: unable to open fifo: %s", applet,
+ strerror(errno));
+@@ -259,6 +341,7 @@ int main(int argc, char **argv)
+ int retval = EXIT_SUCCESS;
+ bool trunc = false;
+ bool chowner = false;
++ bool symlinks = false;
+ bool writable = false;
+ bool selinux_on = false;
+
+@@ -293,6 +376,11 @@ int main(int argc, char **argv)
+ eerrorx("%s: owner `%s' not found",
+ applet, optarg);
+ break;
++ case 's':
++#ifndef O_PATH
++ symlinks = true;
++#endif
++ break;
+ case 'W':
+ writable = true;
+ break;
+@@ -320,7 +408,8 @@ int main(int argc, char **argv)
+ while (optind < argc) {
+ if (writable)
+ exit(!is_writable(argv[optind]));
+- if (do_check(argv[optind], uid, gid, mode, type, trunc, chowner, selinux_on))
++ if (do_check(argv[optind], uid, gid, mode, type, trunc, chowner,
++ symlinks, selinux_on))
+ retval = EXIT_FAILURE;
+ optind++;
+ }