All of lore.kernel.org
 help / color / mirror / Atom feed
* [dunfell][PATCH] rpm: fix CVE-2021-3421
@ 2021-06-24 13:29 Minjae Kim
  2021-06-25  1:29 ` [OE-core] " Anuj Mittal
  0 siblings, 1 reply; 5+ messages in thread
From: Minjae Kim @ 2021-06-24 13:29 UTC (permalink / raw)
  To: openembedded-core; +Cc: Minjae Kim

unsigned signature header leads to string injection into an rpm database

reference:
https://nvd.nist.gov/vuln/detail/CVE-2021-3421
https://github.com/rpm-software-management/rpm/commit/d6a86b5e69e46cc283b1e06c92343319beb42e21
---
 .../rpm/files/CVE-2021-3421.patch             | 197 ++++++++++++++++++
 meta/recipes-devtools/rpm/rpm_4.14.2.1.bb     |   1 +
 2 files changed, 198 insertions(+)
 create mode 100644 meta/recipes-devtools/rpm/files/CVE-2021-3421.patch

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 @@
+From 1e5b70cab83c95aa138107a38ecda75ff70e8985 Mon Sep 17 00:00:00 2001
+From: Minjae Kim <flowergom@gmail.com>
+Date: Thu, 24 Jun 2021 01:11:26 +0000
+Subject: [PATCH] Be much more careful about copying data from the signature
+ header
+
+Only look for known tags, and ensure correct type and size where known
+before copying over. Bump the old arbitrary 16k count limit to 16M limit
+though, it's not inconceivable that a package could have that many files.
+While at it, ensure none of these tags exist in the main header,
+which would confuse us greatly.
+
+This is optimized for backporting ease, upstream can remove redundancies
+and further improve checking later.
+
+Reported and initial patches by Demi Marie Obenour.
+
+Fixes: RhBug:1935049, RhBug:1933867, RhBug:1935035, RhBug:1934125, ...
+
+Fixes: CVE-2021-3421, CVE-2021-20271
+
+Upstream-Status: Backport [https://github.com/rpm-software-management/rpm/commit/d6a86b5e69e46cc283b1e06c92343319beb42e21]
+CVE: CVE-2021-3421
+Signed-off-by: Minjae Kim <flowergom@gmail.com>
+---
+ lib/package.c | 115 ++++++++++++++++++++++++--------------------------
+ lib/rpmtag.h  |   4 ++
+ 2 files changed, 58 insertions(+), 61 deletions(-)
+
+diff --git a/lib/package.c b/lib/package.c
+index 081123d84e..7c26ea323f 100644
+--- a/lib/package.c
++++ b/lib/package.c
+@@ -20,76 +20,68 @@
+ 
+ #include "debug.h"
+ 
++struct taglate_s {
++    rpmTagVal stag;
++    rpmTagVal xtag;
++    rpm_count_t count;
++} const xlateTags[] = {
++    { RPMSIGTAG_SIZE, RPMTAG_SIGSIZE, 1 },
++    { RPMSIGTAG_PGP, RPMTAG_SIGPGP, 0 },
++    { RPMSIGTAG_MD5, RPMTAG_SIGMD5, 16 },
++    { RPMSIGTAG_GPG, RPMTAG_SIGGPG, 0 },
++    /* { RPMSIGTAG_PGP5, RPMTAG_SIGPGP5, 0 }, */ /* long obsolete, dont use */
++    { RPMSIGTAG_PAYLOADSIZE, RPMTAG_ARCHIVESIZE, 1 },
++    { RPMSIGTAG_FILESIGNATURES, RPMTAG_FILESIGNATURES, 0 },
++    { RPMSIGTAG_FILESIGNATURELENGTH, RPMTAG_FILESIGNATURELENGTH, 1 },
++    { RPMSIGTAG_SHA1, RPMTAG_SHA1HEADER, 1 },
++    { RPMSIGTAG_SHA256, RPMTAG_SHA256HEADER, 1 },
++    { RPMSIGTAG_DSA, RPMTAG_DSAHEADER, 0 },
++    { RPMSIGTAG_RSA, RPMTAG_RSAHEADER, 0 },
++    { RPMSIGTAG_LONGSIZE, RPMTAG_LONGSIGSIZE, 1 },
++    { RPMSIGTAG_LONGARCHIVESIZE, RPMTAG_LONGARCHIVESIZE, 1 },
++    { 0 }
++};
++
+ /** \ingroup header
+  * Translate and merge legacy signature tags into header.
+  * @param h		header (dest)
+  * @param sigh		signature header (src)
+  */
+ static
+-void headerMergeLegacySigs(Header h, Header sigh)
++rpmTagVal headerMergeLegacySigs(Header h, Header sigh, char **msg)
+ {
+-    HeaderIterator hi;
++    const struct taglate_s *xl;
+     struct rpmtd_s td;
+ 
+-    hi = headerInitIterator(sigh);
+-    for (; headerNext(hi, &td); rpmtdFreeData(&td))
+-    {
+-	switch (td.tag) {
+-	/* XXX Translate legacy signature tag values. */
+-	case RPMSIGTAG_SIZE:
+-	    td.tag = RPMTAG_SIGSIZE;
+-	    break;
+-	case RPMSIGTAG_PGP:
+-	    td.tag = RPMTAG_SIGPGP;
+-	    break;
+-	case RPMSIGTAG_MD5:
+-	    td.tag = RPMTAG_SIGMD5;
+-	    break;
+-	case RPMSIGTAG_GPG:
+-	    td.tag = RPMTAG_SIGGPG;
+-	    break;
+-	case RPMSIGTAG_PGP5:
+-	    td.tag = RPMTAG_SIGPGP5;
+-	    break;
+-	case RPMSIGTAG_PAYLOADSIZE:
+-	    td.tag = RPMTAG_ARCHIVESIZE;
+-	    break;
+-	case RPMSIGTAG_SHA1:
+-	case RPMSIGTAG_SHA256:
+-	case RPMSIGTAG_DSA:
+-	case RPMSIGTAG_RSA:
+-	default:
+-	    if (!(td.tag >= HEADER_SIGBASE && td.tag < HEADER_TAGBASE))
+-		continue;
+-	    break;
+-	}
+-	if (!headerIsEntry(h, td.tag)) {
+-	    switch (td.type) {
+-	    case RPM_NULL_TYPE:
+-		continue;
+-		break;
+-	    case RPM_CHAR_TYPE:
+-	    case RPM_INT8_TYPE:
+-	    case RPM_INT16_TYPE:
+-	    case RPM_INT32_TYPE:
+-	    case RPM_INT64_TYPE:
+-		if (td.count != 1)
+-		    continue;
+-		break;
+-	    case RPM_STRING_TYPE:
+-	    case RPM_BIN_TYPE:
+-		if (td.count >= 16*1024)
+-		    continue;
+-		break;
+-	    case RPM_STRING_ARRAY_TYPE:
+-	    case RPM_I18NSTRING_TYPE:
+-		continue;
+-		break;
+-	    }
+-	    (void) headerPut(h, &td, HEADERPUT_DEFAULT);
+-	}
++    rpmtdReset(&td);
++    for (xl = xlateTags; xl->stag; xl++) {
++        /* There mustn't be one in the main header */
++        if (headerIsEntry(h, xl->xtag))
++            break;
++        if (headerGet(sigh, xl->stag, &td, HEADERGET_RAW|HEADERGET_MINMEM)) {
++            /* Translate legacy tags */
++            if (xl->stag != xl->xtag)
++                td.tag = xl->xtag;
++            /* Ensure type and tag size match expectations */
++            if (td.type != rpmTagGetTagType(td.tag))
++                break;
++            if (td.count < 1 || td.count > 16*1024*1024)
++                break;
++            if (xl->count && td.count != xl->count)
++                break;
++            if (!headerPut(h, &td, HEADERPUT_DEFAULT))
++                break;
++            rpmtdFreeData(&td);
++        }
++    }
++    rpmtdFreeData(&td);
++
++    if (xl->stag) {
++        rasprintf(msg, "invalid signature tag %s (%d)",
++                        rpmTagGetName(xl->xtag), xl->xtag);
+     }
+-    headerFreeIterator(hi);
++
++    return xl->stag;
+ }
+ 
+ /**
+@@ -337,7 +329,8 @@ rpmRC rpmReadPackageFile(rpmts ts, FD_t fd, const char * fn, Header * hdrp)
+ 		goto exit;
+ 
+ 	    /* Append (and remap) signature tags to the metadata. */
+-	    headerMergeLegacySigs(h, sigh);
++	    if (headerMergeLegacySigs(h, sigh,&msg))
++		    goto exit;
+ 	    applyRetrofits(h);
+ 
+ 	    /* Bump reference count for return. */
+diff --git a/lib/rpmtag.h b/lib/rpmtag.h
+index 8c718b31b5..d562572c6f 100644
+--- a/lib/rpmtag.h
++++ b/lib/rpmtag.h
+@@ -65,6 +65,8 @@ typedef enum rpmTag_e {
+     RPMTAG_LONGARCHIVESIZE	= RPMTAG_SIG_BASE+15,	/* l */
+     /* RPMTAG_SIG_BASE+16 reserved */
+     RPMTAG_SHA256HEADER		= RPMTAG_SIG_BASE+17,	/* s */
++    /* RPMTAG_SIG_BASE+18 reserved for RPMSIGTAG_FILESIGNATURES */
++    /* RPMTAG_SIG_BASE+19 reserved for RPMSIGTAG_FILESIGNATURELENGTH */
+ 
+     RPMTAG_NAME  		= 1000,	/* s */
+ #define	RPMTAG_N	RPMTAG_NAME	/* s */
+@@ -422,6 +424,8 @@ typedef enum rpmSigTag_e {
+     RPMSIGTAG_LONGSIZE	= RPMTAG_LONGSIGSIZE,	/*!< internal Header+Payload size (64bit) in bytes. */
+     RPMSIGTAG_LONGARCHIVESIZE = RPMTAG_LONGARCHIVESIZE, /*!< internal uncompressed payload size (64bit) in bytes. */
+     RPMSIGTAG_SHA256	= RPMTAG_SHA256HEADER,
++    RPMSIGTAG_FILESIGNATURES            = RPMTAG_SIG_BASE + 18,
++    RPMSIGTAG_FILESIGNATURELENGTH       = RPMTAG_SIG_BASE + 19,
+ } rpmSigTag;
+ 
+ 
+-- 
+2.17.1
+
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 \
            file://0001-mono-find-provides-requires-do-not-use-monodis-from-.patch \
            file://0001-Rip-out-partial-support-for-unused-MD2-and-RIPEMD160.patch \
            file://0001-rpmplugins.c-call-dlerror-prior-to-dlsym.patch \
+           file://CVE-2021-3421.patch \
            "
 
 PE = "1"
-- 
2.24.3 (Apple Git-128)


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [OE-core] [dunfell][PATCH] rpm: fix CVE-2021-3421
  2021-06-24 13:29 [dunfell][PATCH] rpm: fix CVE-2021-3421 Minjae Kim
@ 2021-06-25  1:29 ` Anuj Mittal
  2021-06-25  5:30   ` Minjae Kim
  0 siblings, 1 reply; 5+ messages in thread
From: Anuj Mittal @ 2021-06-25  1:29 UTC (permalink / raw)
  To: Minjae Kim, openembedded-core

> + 	    /* Bump reference count for return. */ diff --git a/lib/rpmtag.h
> +b/lib/rpmtag.h index 8c718b31b5..d562572c6f 100644
> +--- a/lib/rpmtag.h
> ++++ b/lib/rpmtag.h
> +@@ -65,6 +65,8 @@ typedef enum rpmTag_e {
> +     RPMTAG_LONGARCHIVESIZE	= RPMTAG_SIG_BASE+15,	/* l */
> +     /* RPMTAG_SIG_BASE+16 reserved */
> +     RPMTAG_SHA256HEADER		= RPMTAG_SIG_BASE+17,	/* s */
> ++    /* RPMTAG_SIG_BASE+18 reserved for RPMSIGTAG_FILESIGNATURES */
> ++    /* RPMTAG_SIG_BASE+19 reserved for
> RPMSIGTAG_FILESIGNATURELENGTH
> ++ */
> +
> +     RPMTAG_NAME  		= 1000,	/* s */
> + #define	RPMTAG_N	RPMTAG_NAME	/* s */
> +@@ -422,6 +424,8 @@ typedef enum rpmSigTag_e {
> +     RPMSIGTAG_LONGSIZE	= RPMTAG_LONGSIGSIZE,	/*!< internal
> Header+Payload size (64bit) in bytes. */
> +     RPMSIGTAG_LONGARCHIVESIZE = RPMTAG_LONGARCHIVESIZE, /*!<
> internal uncompressed payload size (64bit) in bytes. */
> +     RPMSIGTAG_SHA256	= RPMTAG_SHA256HEADER,
> ++    RPMSIGTAG_FILESIGNATURES            = RPMTAG_SIG_BASE + 18,
> ++    RPMSIGTAG_FILESIGNATURELENGTH       = RPMTAG_SIG_BASE + 19,
> + } rpmSigTag;
> +

Was this hunk added to make the backported patch compile? Considering 4.14.x version doesn't use RPMSIGTAG_FILESIGNATURES at all, I am wondering if this change works as intended?

Thanks,

Anuj    

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [dunfell][PATCH] rpm: fix CVE-2021-3421
  2021-06-25  1:29 ` [OE-core] " Anuj Mittal
@ 2021-06-25  5:30   ` Minjae Kim
  2021-06-25 15:07     ` [OE-core] " Steve Sakoman
  0 siblings, 1 reply; 5+ messages in thread
From: Minjae Kim @ 2021-06-25  5:30 UTC (permalink / raw)
  To: openembedded-core

[-- Attachment #1: Type: text/plain, Size: 178 bytes --]

In order to fix CVE-2021-3421, I added RPMSIGTAG_FILESIGNATURES and RPMSIGTAG_FILESIGNATURELENGTH in lib/rpmtag.h.
So It is possible to build. but I cannot test on target yet.

[-- Attachment #2: Type: text/html, Size: 275 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [OE-core] [dunfell][PATCH] rpm: fix CVE-2021-3421
  2021-06-25  5:30   ` Minjae Kim
@ 2021-06-25 15:07     ` Steve Sakoman
  2021-06-26  5:55       ` Minjae Kim
  0 siblings, 1 reply; 5+ messages in thread
From: Steve Sakoman @ 2021-06-25 15:07 UTC (permalink / raw)
  To: Minjae Kim; +Cc: Patches and discussions about the oe-core layer

On Thu, Jun 24, 2021 at 7:30 PM Minjae Kim <flowergom@gmail.com> wrote:
>
> In order to fix CVE-2021-3421, I added RPMSIGTAG_FILESIGNATURES and RPMSIGTAG_FILESIGNATURELENGTH in lib/rpmtag.h.
> So It is possible to build. but I cannot test on target yet.

FWIW, a-full test on the autobuilder passed with this patch included.

I'm not sure that is sufficient testing, so I won't include this patch
in a pull request until I hear back about the result of your testing.

Steve

> 
>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [dunfell][PATCH] rpm: fix CVE-2021-3421
  2021-06-25 15:07     ` [OE-core] " Steve Sakoman
@ 2021-06-26  5:55       ` Minjae Kim
  0 siblings, 0 replies; 5+ messages in thread
From: Minjae Kim @ 2021-06-26  5:55 UTC (permalink / raw)
  To: openembedded-core


[-- Attachment #1.1: Type: text/plain, Size: 225 bytes --]

Hi Steve and Anuj

I tested it on qemu, it works well.
- git package is installed by rpm command.

- git package is removed by rpm command.

Could you tell me what is needed to verify for RPM?

Thanks,
Minjae Kim.

[-- Attachment #1.2: Type: text/html, Size: 460 bytes --]

[-- Attachment #2: dummyfile.0.part --]
[-- Type: image/png, Size: 48745 bytes --]

[-- Attachment #3: dummyfile.1.part --]
[-- Type: image/png, Size: 3091 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-06-26  5:55 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-24 13:29 [dunfell][PATCH] rpm: fix CVE-2021-3421 Minjae Kim
2021-06-25  1:29 ` [OE-core] " Anuj Mittal
2021-06-25  5:30   ` Minjae Kim
2021-06-25 15:07     ` [OE-core] " Steve Sakoman
2021-06-26  5:55       ` Minjae Kim

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.