Browse code

rpm : CVE-2017-7501

Change-Id: Ibbcf8bc8aff8834fdc11d25f7114d4691441d524
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/4560
Tested-by: gerrit-photon <photon-checkins@vmware.com>
Reviewed-by: Xiaolin Li <xiaolinl@vmware.com>

xiaolin-vmware authored on 2017/12/22 06:38:04
Showing 2 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,96 @@
0
+From 404ef011c300207cdb1e531670384564aae04bdc Mon Sep 17 00:00:00 2001
1
+From: Panu Matilainen <pmatilai@redhat.com>
2
+Date: Tue, 19 Sep 2017 14:46:36 +0300
3
+Subject: [PATCH] Don't follow symlinks on file creation (CVE-2017-7501)
4
+
5
+Open newly created files with O_EXCL to prevent symlink tricks.
6
+When reopening hardlinks for writing the actual content, use append
7
+mode instead. This is compatible with the write-only permissions but
8
+is not destructive in case we got redirected to somebody elses file,
9
+verify the target before actually writing anything.
10
+
11
+As these are files with the temporary suffix, errors mean a local
12
+user with sufficient privileges to break the installation of the package
13
+anyway is trying to goof us on purpose, don't bother trying to mend it
14
+(we couldn't fix the hardlink case anyhow) but just bail out.
15
+
16
+Based on a patch by Florian Festi.
17
+---
18
+ lib/fsm.c | 29 +++++++++++++++++++++++------
19
+ 1 file changed, 23 insertions(+), 6 deletions(-)
20
+
21
+diff --git a/lib/fsm.c b/lib/fsm.c
22
+index 553774b30..e0e9d03a1 100644
23
+--- a/lib/fsm.c
24
+@@ -206,11 +206,22 @@ static int fsmSetFCaps(const char *path, const char *captxt)
25
+     return rc;
26
+ }
27
+ 
28
++/* Check dest is the same, empty and regular file with writeonly permissions */
29
++static int linkSane(FD_t wfd, const char *dest)
30
++{
31
++    struct stat sb, lsb;
32
++
33
++    return (fstat(Fileno(wfd), &sb) == 0 && sb.st_size == 0 &&
34
++	    (sb.st_mode & ~S_IFMT) == S_IWUSR &&
35
++	    lstat(dest, &lsb) == 0 && S_ISREG(lsb.st_mode) &&
36
++	    sb.st_dev == lsb.st_dev && sb.st_ino == lsb.st_ino);
37
++}
38
++
39
+ /** \ingroup payload
40
+  * Create file from payload stream.
41
+  * @return		0 on success
42
+  */
43
+-static int expandRegular(rpmfi fi, const char *dest, rpmpsm psm, int nodigest, int nocontent)
44
++static int expandRegular(rpmfi fi, const char *dest, rpmpsm psm, int exclusive, int nodigest, int nocontent)
45
+ {
46
+     FD_t wfd = NULL;
47
+     int rc = 0;
48
+@@ -218,8 +229,14 @@ static int expandRegular(rpmfi fi, const char *dest, rpmpsm psm, int nodigest, i
49
+     /* Create the file with 0200 permissions (write by owner). */
50
+     {
51
+ 	mode_t old_umask = umask(0577);
52
+-	wfd = Fopen(dest, "w.ufdio");
53
++	wfd = Fopen(dest, exclusive ? "wx.ufdio" : "a.ufdio");
54
+ 	umask(old_umask);
55
++
56
++	/* If reopening, make sure the file is what we expect */
57
++	if (!exclusive && wfd != NULL && !linkSane(wfd, dest)) {
58
++	    rc = RPMERR_OPEN_FAILED;
59
++	    goto exit;
60
++	}
61
+     }
62
+     if (Ferror(wfd)) {
63
+ 	rc = RPMERR_OPEN_FAILED;
64
+@@ -248,7 +265,7 @@ static int fsmMkfile(rpmfi fi, const char *dest, rpmfiles files,
65
+ 	/* Create first hardlinked file empty */
66
+ 	if (*firsthardlink < 0) {
67
+ 	    *firsthardlink = rpmfiFX(fi);
68
+-	    rc = expandRegular(fi, dest, psm, nodigest, 1);
69
++	    rc = expandRegular(fi, dest, psm, 1, nodigest, 1);
70
+ 	} else {
71
+ 	    /* Create hard links for others */
72
+ 	    char *fn = rpmfilesFN(files, *firsthardlink);
73
+@@ -263,10 +280,10 @@ static int fsmMkfile(rpmfi fi, const char *dest, rpmfiles files,
74
+        existing) file with content */
75
+     if (numHardlinks<=1) {
76
+ 	if (!rc)
77
+-	    rc = expandRegular(fi, dest, psm, nodigest, 0);
78
++	    rc = expandRegular(fi, dest, psm, 1, nodigest, 0);
79
+     } else if (rpmfiArchiveHasContent(fi)) {
80
+ 	if (!rc)
81
+-	    rc = expandRegular(fi, dest, psm, nodigest, 0);
82
++	    rc = expandRegular(fi, dest, psm, 0, nodigest, 0);
83
+ 	*firsthardlink = -1;
84
+     } else {
85
+ 	*setmeta = 0;
86
+@@ -939,7 +956,7 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
87
+ 	    /* we skip the hard linked file containing the content */
88
+ 	    /* write the content to the first used instead */
89
+ 	    char *fn = rpmfilesFN(files, firsthardlink);
90
+-	    rc = expandRegular(fi, fn, psm, nodigest, 0);
91
++	    rc = expandRegular(fi, fn, psm, 0, nodigest, 0);
92
+ 	    firsthardlink = -1;
93
+ 	    free(fn);
94
+ 	}
... ...
@@ -4,7 +4,7 @@
4 4
 Summary:        Package manager
5 5
 Name:           rpm
6 6
 Version:        4.13.0.1
7
-Release:        6%{?dist}
7
+Release:        7%{?dist}
8 8
 License:        GPLv2+
9 9
 URL:            http://rpm.org
10 10
 Group:          Applications/System
... ...
@@ -17,6 +17,7 @@ Source2:        brp-strip-debug-symbols
17 17
 Source3:        brp-strip-unneeded
18 18
 Patch0:         find-debuginfo-do-not-generate-non-existing-build-id.patch
19 19
 Patch1:         find-debuginfo-do-not-generate-dir-entries.patch
20
+Patch2:         rpm-CVE-2017-7501.patch
20 21
 Requires:       bash
21 22
 Requires:       libdb
22 23
 Requires:       rpm-libs = %{version}-%{release}
... ...
@@ -88,6 +89,7 @@ Python3 rpm.
88 88
 %setup -n rpm-%{name}-%{version}-release
89 89
 %patch0 -p1
90 90
 %patch1 -p1
91
+%patch2 -p1
91 92
 
92 93
 %build
93 94
 sed -i '/define _GNU_SOURCE/a #include "../config.h"' tools/sepdebugcrcfix.c
... ...
@@ -258,6 +260,8 @@ rm -rf %{buildroot}
258 258
 %{python3_sitelib}/*
259 259
 
260 260
 %changelog
261
+*   Thu Dec 21 2017 Xiaolin Li <xiaolinl@vmware.com> 4.13.0.1-7
262
+-   Fix CVE-2017-7501
261 263
 *   Wed Oct 04 2017 Alexey Makhalov <amakhalov@vmware.com> 4.13.0.1-6
262 264
 -   make python{,3}-rpm depend on current version of librpm
263 265
 *   Wed Jun 28 2017 Xiaolin Li <xiaolinl@vmware.com> 4.13.0.1-5