Fix CVE-2021-3421: Be much more careful about copying data from the signature header 75/288875/1 accepted/tizen_7.0_base_tool accepted/tizen/7.0/base/20230714.003114 accepted/tizen/7.0/base/tool/20230227.052718 submit/tizen_7.0_base/20230223.123040
authorwang biao <biao716.wang@samsung.com>
Fri, 24 Feb 2023 03:37:58 +0000 (11:37 +0800)
committerwang biao <biao716.wang@samsung.com>
Fri, 24 Feb 2023 03:38:00 +0000 (11:38 +0800)
https://github.com/rpm-software-management/rpm/commit/d6a86b5e69e46cc283b1e06c92343319beb42e21
have to change something to apply this patch.
Change-Id: I7a9ca96884f5a6181bfe156b1dd59a6cf10f36f7
Signed-off-by: wang biao <biao716.wang@samsung.com>
lib/header_internal.h
lib/package.c
lib/rpmchecksig.c

index 81c8c1e..76b7ed5 100644 (file)
@@ -88,7 +88,7 @@ ssize_t Freadall(FD_t fd, void * buf, ssize_t size);
 
 /* XXX here only temporarily */
 RPM_GNUC_INTERNAL
-void headerMergeLegacySigs(Header h, Header sigh);
+rpmTagVal headerMergeLegacySigs(Header h, Header sigh, char **msg);
 RPM_GNUC_INTERNAL
 void applyRetrofits(Header h, int leadtype);
 RPM_GNUC_INTERNAL
index 1d9e9e1..74cd9f4 100644 (file)
 
 #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_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)
  */
-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;
+    rpmtdReset(&td);
+    for (xl = xlateTags; xl->stag; xl++) {
+       /* There mustn't be one in the main header */
+       if (headerIsEntry(h, xl->xtag))
            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;
+       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;
-           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;
+           if (td.count < 1 || td.count > 16*1024*1024)
                break;
-           case RPM_STRING_TYPE:
-           case RPM_BIN_TYPE:
-               if (td.count >= 16*1024)
-                   continue;
+           if (xl->count && td.count != xl->count)
                break;
-           case RPM_STRING_ARRAY_TYPE:
-           case RPM_I18NSTRING_TYPE:
-               continue;
+           if (!headerPut(h, &td, HEADERPUT_DEFAULT))
                break;
-           }
-           (void) headerPut(h, &td, HEADERPUT_DEFAULT);
+           rpmtdFreeData(&td);
        }
     }
-    headerFreeIterator(hi);
+    rpmtdFreeData(&td);
+
+    if (xl->stag) {
+       rasprintf(msg, "invalid signature tag %s (%d)",
+                       rpmTagGetName(xl->xtag), xl->xtag);
+    }
+
+    return xl->stag;
 }
 
 /**
index 196bb1c..26a81ef 100644 (file)
@@ -226,7 +226,8 @@ rpmRC rpmpkgRead(rpmPlugins plugins, rpmKeyring keyring, rpmVSFlags flags, FD_t
                goto exit;
 
            /* Append (and remap) signature tags to the metadata. */
-           headerMergeLegacySigs(h, sigh);
+           if (headerMergeLegacySigs(h, sigh, &msg))
+               goto exit;
            applyRetrofits(h, leadtype);
 
            /* Bump reference count for return. */