diff options
| -rw-r--r-- | meta/recipes-devtools/rpm/files/CVE-2021-3421.patch | 197 | ||||
| -rw-r--r-- | meta/recipes-devtools/rpm/rpm_4.14.2.1.bb | 1 |
2 files changed, 198 insertions, 0 deletions
diff --git a/meta/recipes-devtools/rpm/files/CVE-2021-3421.patch b/meta/recipes-devtools/rpm/files/CVE-2021-3421.patch new file mode 100644 index 0000000000..b1a05b6863 --- /dev/null +++ b/meta/recipes-devtools/rpm/files/CVE-2021-3421.patch | |||
| @@ -0,0 +1,197 @@ | |||
| 1 | From 1e5b70cab83c95aa138107a38ecda75ff70e8985 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Minjae Kim <flowergom@gmail.com> | ||
| 3 | Date: Thu, 24 Jun 2021 01:11:26 +0000 | ||
| 4 | Subject: [PATCH] Be much more careful about copying data from the signature | ||
| 5 | header | ||
| 6 | |||
| 7 | Only look for known tags, and ensure correct type and size where known | ||
| 8 | before copying over. Bump the old arbitrary 16k count limit to 16M limit | ||
| 9 | though, it's not inconceivable that a package could have that many files. | ||
| 10 | While at it, ensure none of these tags exist in the main header, | ||
| 11 | which would confuse us greatly. | ||
| 12 | |||
| 13 | This is optimized for backporting ease, upstream can remove redundancies | ||
| 14 | and further improve checking later. | ||
| 15 | |||
| 16 | Reported and initial patches by Demi Marie Obenour. | ||
| 17 | |||
| 18 | Fixes: RhBug:1935049, RhBug:1933867, RhBug:1935035, RhBug:1934125, ... | ||
| 19 | |||
| 20 | Fixes: CVE-2021-3421, CVE-2021-20271 | ||
| 21 | |||
| 22 | Upstream-Status: Backport [https://github.com/rpm-software-management/rpm/commit/d6a86b5e69e46cc283b1e06c92343319beb42e21] | ||
| 23 | CVE: CVE-2021-3421 | ||
| 24 | Signed-off-by: Minjae Kim <flowergom@gmail.com> | ||
| 25 | --- | ||
| 26 | lib/package.c | 115 ++++++++++++++++++++++++-------------------------- | ||
| 27 | lib/rpmtag.h | 4 ++ | ||
| 28 | 2 files changed, 58 insertions(+), 61 deletions(-) | ||
| 29 | |||
| 30 | diff --git a/lib/package.c b/lib/package.c | ||
| 31 | index 081123d84e..7c26ea323f 100644 | ||
| 32 | --- a/lib/package.c | ||
| 33 | +++ b/lib/package.c | ||
| 34 | @@ -20,76 +20,68 @@ | ||
| 35 | |||
| 36 | #include "debug.h" | ||
| 37 | |||
| 38 | +struct taglate_s { | ||
| 39 | + rpmTagVal stag; | ||
| 40 | + rpmTagVal xtag; | ||
| 41 | + rpm_count_t count; | ||
| 42 | +} const xlateTags[] = { | ||
| 43 | + { RPMSIGTAG_SIZE, RPMTAG_SIGSIZE, 1 }, | ||
| 44 | + { RPMSIGTAG_PGP, RPMTAG_SIGPGP, 0 }, | ||
| 45 | + { RPMSIGTAG_MD5, RPMTAG_SIGMD5, 16 }, | ||
| 46 | + { RPMSIGTAG_GPG, RPMTAG_SIGGPG, 0 }, | ||
| 47 | + /* { RPMSIGTAG_PGP5, RPMTAG_SIGPGP5, 0 }, */ /* long obsolete, dont use */ | ||
| 48 | + { RPMSIGTAG_PAYLOADSIZE, RPMTAG_ARCHIVESIZE, 1 }, | ||
| 49 | + { RPMSIGTAG_FILESIGNATURES, RPMTAG_FILESIGNATURES, 0 }, | ||
| 50 | + { RPMSIGTAG_FILESIGNATURELENGTH, RPMTAG_FILESIGNATURELENGTH, 1 }, | ||
| 51 | + { RPMSIGTAG_SHA1, RPMTAG_SHA1HEADER, 1 }, | ||
| 52 | + { RPMSIGTAG_SHA256, RPMTAG_SHA256HEADER, 1 }, | ||
| 53 | + { RPMSIGTAG_DSA, RPMTAG_DSAHEADER, 0 }, | ||
| 54 | + { RPMSIGTAG_RSA, RPMTAG_RSAHEADER, 0 }, | ||
| 55 | + { RPMSIGTAG_LONGSIZE, RPMTAG_LONGSIGSIZE, 1 }, | ||
| 56 | + { RPMSIGTAG_LONGARCHIVESIZE, RPMTAG_LONGARCHIVESIZE, 1 }, | ||
| 57 | + { 0 } | ||
| 58 | +}; | ||
| 59 | + | ||
| 60 | /** \ingroup header | ||
| 61 | * Translate and merge legacy signature tags into header. | ||
| 62 | * @param h header (dest) | ||
| 63 | * @param sigh signature header (src) | ||
| 64 | */ | ||
| 65 | static | ||
| 66 | -void headerMergeLegacySigs(Header h, Header sigh) | ||
| 67 | +rpmTagVal headerMergeLegacySigs(Header h, Header sigh, char **msg) | ||
| 68 | { | ||
| 69 | - HeaderIterator hi; | ||
| 70 | + const struct taglate_s *xl; | ||
| 71 | struct rpmtd_s td; | ||
| 72 | |||
| 73 | - hi = headerInitIterator(sigh); | ||
| 74 | - for (; headerNext(hi, &td); rpmtdFreeData(&td)) | ||
| 75 | - { | ||
| 76 | - switch (td.tag) { | ||
| 77 | - /* XXX Translate legacy signature tag values. */ | ||
| 78 | - case RPMSIGTAG_SIZE: | ||
| 79 | - td.tag = RPMTAG_SIGSIZE; | ||
| 80 | - break; | ||
| 81 | - case RPMSIGTAG_PGP: | ||
| 82 | - td.tag = RPMTAG_SIGPGP; | ||
| 83 | - break; | ||
| 84 | - case RPMSIGTAG_MD5: | ||
| 85 | - td.tag = RPMTAG_SIGMD5; | ||
| 86 | - break; | ||
| 87 | - case RPMSIGTAG_GPG: | ||
| 88 | - td.tag = RPMTAG_SIGGPG; | ||
| 89 | - break; | ||
| 90 | - case RPMSIGTAG_PGP5: | ||
| 91 | - td.tag = RPMTAG_SIGPGP5; | ||
| 92 | - break; | ||
| 93 | - case RPMSIGTAG_PAYLOADSIZE: | ||
| 94 | - td.tag = RPMTAG_ARCHIVESIZE; | ||
| 95 | - break; | ||
| 96 | - case RPMSIGTAG_SHA1: | ||
| 97 | - case RPMSIGTAG_SHA256: | ||
| 98 | - case RPMSIGTAG_DSA: | ||
| 99 | - case RPMSIGTAG_RSA: | ||
| 100 | - default: | ||
| 101 | - if (!(td.tag >= HEADER_SIGBASE && td.tag < HEADER_TAGBASE)) | ||
| 102 | - continue; | ||
| 103 | - break; | ||
| 104 | - } | ||
| 105 | - if (!headerIsEntry(h, td.tag)) { | ||
| 106 | - switch (td.type) { | ||
| 107 | - case RPM_NULL_TYPE: | ||
| 108 | - continue; | ||
| 109 | - break; | ||
| 110 | - case RPM_CHAR_TYPE: | ||
| 111 | - case RPM_INT8_TYPE: | ||
| 112 | - case RPM_INT16_TYPE: | ||
| 113 | - case RPM_INT32_TYPE: | ||
| 114 | - case RPM_INT64_TYPE: | ||
| 115 | - if (td.count != 1) | ||
| 116 | - continue; | ||
| 117 | - break; | ||
| 118 | - case RPM_STRING_TYPE: | ||
| 119 | - case RPM_BIN_TYPE: | ||
| 120 | - if (td.count >= 16*1024) | ||
| 121 | - continue; | ||
| 122 | - break; | ||
| 123 | - case RPM_STRING_ARRAY_TYPE: | ||
| 124 | - case RPM_I18NSTRING_TYPE: | ||
| 125 | - continue; | ||
| 126 | - break; | ||
| 127 | - } | ||
| 128 | - (void) headerPut(h, &td, HEADERPUT_DEFAULT); | ||
| 129 | - } | ||
| 130 | + rpmtdReset(&td); | ||
| 131 | + for (xl = xlateTags; xl->stag; xl++) { | ||
| 132 | + /* There mustn't be one in the main header */ | ||
| 133 | + if (headerIsEntry(h, xl->xtag)) | ||
| 134 | + break; | ||
| 135 | + if (headerGet(sigh, xl->stag, &td, HEADERGET_RAW|HEADERGET_MINMEM)) { | ||
| 136 | + /* Translate legacy tags */ | ||
| 137 | + if (xl->stag != xl->xtag) | ||
| 138 | + td.tag = xl->xtag; | ||
| 139 | + /* Ensure type and tag size match expectations */ | ||
| 140 | + if (td.type != rpmTagGetTagType(td.tag)) | ||
| 141 | + break; | ||
| 142 | + if (td.count < 1 || td.count > 16*1024*1024) | ||
| 143 | + break; | ||
| 144 | + if (xl->count && td.count != xl->count) | ||
| 145 | + break; | ||
| 146 | + if (!headerPut(h, &td, HEADERPUT_DEFAULT)) | ||
| 147 | + break; | ||
| 148 | + rpmtdFreeData(&td); | ||
| 149 | + } | ||
| 150 | + } | ||
| 151 | + rpmtdFreeData(&td); | ||
| 152 | + | ||
| 153 | + if (xl->stag) { | ||
| 154 | + rasprintf(msg, "invalid signature tag %s (%d)", | ||
| 155 | + rpmTagGetName(xl->xtag), xl->xtag); | ||
| 156 | } | ||
| 157 | - headerFreeIterator(hi); | ||
| 158 | + | ||
| 159 | + return xl->stag; | ||
| 160 | } | ||
| 161 | |||
| 162 | /** | ||
| 163 | @@ -337,7 +329,8 @@ rpmRC rpmReadPackageFile(rpmts ts, FD_t fd, const char * fn, Header * hdrp) | ||
| 164 | goto exit; | ||
| 165 | |||
| 166 | /* Append (and remap) signature tags to the metadata. */ | ||
| 167 | - headerMergeLegacySigs(h, sigh); | ||
| 168 | + if (headerMergeLegacySigs(h, sigh,&msg)) | ||
| 169 | + goto exit; | ||
| 170 | applyRetrofits(h); | ||
| 171 | |||
| 172 | /* Bump reference count for return. */ | ||
| 173 | diff --git a/lib/rpmtag.h b/lib/rpmtag.h | ||
| 174 | index 8c718b31b5..d562572c6f 100644 | ||
| 175 | --- a/lib/rpmtag.h | ||
| 176 | +++ b/lib/rpmtag.h | ||
| 177 | @@ -65,6 +65,8 @@ typedef enum rpmTag_e { | ||
| 178 | RPMTAG_LONGARCHIVESIZE = RPMTAG_SIG_BASE+15, /* l */ | ||
| 179 | /* RPMTAG_SIG_BASE+16 reserved */ | ||
| 180 | RPMTAG_SHA256HEADER = RPMTAG_SIG_BASE+17, /* s */ | ||
| 181 | + /* RPMTAG_SIG_BASE+18 reserved for RPMSIGTAG_FILESIGNATURES */ | ||
| 182 | + /* RPMTAG_SIG_BASE+19 reserved for RPMSIGTAG_FILESIGNATURELENGTH */ | ||
| 183 | |||
| 184 | RPMTAG_NAME = 1000, /* s */ | ||
| 185 | #define RPMTAG_N RPMTAG_NAME /* s */ | ||
| 186 | @@ -422,6 +424,8 @@ typedef enum rpmSigTag_e { | ||
| 187 | RPMSIGTAG_LONGSIZE = RPMTAG_LONGSIGSIZE, /*!< internal Header+Payload size (64bit) in bytes. */ | ||
| 188 | RPMSIGTAG_LONGARCHIVESIZE = RPMTAG_LONGARCHIVESIZE, /*!< internal uncompressed payload size (64bit) in bytes. */ | ||
| 189 | RPMSIGTAG_SHA256 = RPMTAG_SHA256HEADER, | ||
| 190 | + RPMSIGTAG_FILESIGNATURES = RPMTAG_SIG_BASE + 18, | ||
| 191 | + RPMSIGTAG_FILESIGNATURELENGTH = RPMTAG_SIG_BASE + 19, | ||
| 192 | } rpmSigTag; | ||
| 193 | |||
| 194 | |||
| 195 | -- | ||
| 196 | 2.17.1 | ||
| 197 | |||
diff --git a/meta/recipes-devtools/rpm/rpm_4.14.2.1.bb b/meta/recipes-devtools/rpm/rpm_4.14.2.1.bb index 4029217d08..018b2f8700 100644 --- a/meta/recipes-devtools/rpm/rpm_4.14.2.1.bb +++ b/meta/recipes-devtools/rpm/rpm_4.14.2.1.bb | |||
| @@ -44,6 +44,7 @@ SRC_URI = "git://github.com/rpm-software-management/rpm;branch=rpm-4.14.x \ | |||
| 44 | file://0001-mono-find-provides-requires-do-not-use-monodis-from-.patch \ | 44 | file://0001-mono-find-provides-requires-do-not-use-monodis-from-.patch \ |
| 45 | file://0001-Rip-out-partial-support-for-unused-MD2-and-RIPEMD160.patch \ | 45 | file://0001-Rip-out-partial-support-for-unused-MD2-and-RIPEMD160.patch \ |
| 46 | file://0001-rpmplugins.c-call-dlerror-prior-to-dlsym.patch \ | 46 | file://0001-rpmplugins.c-call-dlerror-prior-to-dlsym.patch \ |
| 47 | file://CVE-2021-3421.patch \ | ||
| 47 | " | 48 | " |
| 48 | 49 | ||
| 49 | PE = "1" | 50 | PE = "1" |
