diff --git a/meta-oe/recipes-support/exiv2/exiv2/CVE-2021-37620-1.patch b/meta-oe/recipes-support/exiv2/exiv2/CVE-2021-37620-1.patch
new file mode 100644
index 0000000000..f072ea6ab0
--- /dev/null
+++ b/meta-oe/recipes-support/exiv2/exiv2/CVE-2021-37620-1.patch
@@ -0,0 +1,26 @@
+From 672bb4c98a98911f91834617e8a7374acb903206 Mon Sep 17 00:00:00 2001
+From: Kevin Backhouse <kevinbackhouse@github.com>
+Date: Sat, 10 Jul 2021 10:42:24 +0100
+Subject: [PATCH] Check that `type` isn't an empty string.
+
+CVE: CVE-2021-37620
+Upstream-Status: Backport [https://github.com/Exiv2/exiv2/commit/2e7bb581a234bfb0d0c9e16a1dbf037a8c30681e]
+Signed-off-by: Gyorgy Sarvari <skandigraun@gmail.com>
+---
+ src/value.cpp | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/src/value.cpp b/src/value.cpp
+index 95eb05a..2536b84 100644
+--- a/src/value.cpp
++++ b/src/value.cpp
+@@ -714,6 +714,9 @@ namespace Exiv2 {
+         if (buf.length() > 5 && buf.substr(0, 5) == "type=") {
+             std::string::size_type pos = buf.find_first_of(' ');
+             type = buf.substr(5, pos-5);
++            if (type.empty()) {
++                throw Error(kerInvalidXmpText, type);
++            }
+             // Strip quotes (so you can also specify the type without quotes)
+             if (type[0] == '"') type = type.substr(1);
+             if (type[type.length()-1] == '"') type = type.substr(0, type.length()-1);
diff --git a/meta-oe/recipes-support/exiv2/exiv2/CVE-2021-37620-2.patch b/meta-oe/recipes-support/exiv2/exiv2/CVE-2021-37620-2.patch
new file mode 100644
index 0000000000..bbb4176aa5
--- /dev/null
+++ b/meta-oe/recipes-support/exiv2/exiv2/CVE-2021-37620-2.patch
@@ -0,0 +1,305 @@
+From 13fb2c4f55a268f0ad864005428e93f80d813b8a Mon Sep 17 00:00:00 2001
+From: Kevin Backhouse <kevinbackhouse@github.com>
+Date: Sun, 11 Jul 2021 12:04:53 +0100
+Subject: [PATCH] Safer std::vector indexing.
+
+CVE: CVE-2021-37620
+Upstream-Status: Backport [https://github.com/Exiv2/exiv2/commit/76e313745e813f80e8910aceb2210af3ad8cf897]
+Signed-off-by: Gyorgy Sarvari <skandigraun@gmail.com>
+---
+ samples/addmoddel.cpp   |  2 +-
+ samples/exiv2json.cpp   |  6 +++---
+ src/actions.cpp         | 20 +++++++++++---------
+ src/basicio.cpp         |  6 +++---
+ src/exiv2.cpp           |  4 ++--
+ src/minoltamn_int.cpp   |  2 +-
+ src/properties.cpp      |  2 +-
+ src/sigmamn_int.cpp     |  6 +++---
+ src/tags_int.cpp        |  2 +-
+ src/tiffvisitor_int.cpp |  2 +-
+ src/utils.cpp           |  4 ++--
+ src/value.cpp           |  6 ++++--
+ src/xmp.cpp             |  3 +--
+ 13 files changed, 34 insertions(+), 31 deletions(-)
+
+diff --git a/samples/addmoddel.cpp b/samples/addmoddel.cpp
+index e171edd..215e432 100644
+--- a/samples/addmoddel.cpp
++++ b/samples/addmoddel.cpp
+@@ -77,7 +77,7 @@ try {
+     if (prv == 0) throw Exiv2::Error(Exiv2::kerErrorMessage, "Downcast failed");
+     rv = Exiv2::URationalValue::AutoPtr(prv);
+     // Modify the value directly through the interface of URationalValue
+-    rv->value_[2] = std::make_pair(88,77);
++    rv->value_.at(2) = std::make_pair(88,77);
+     // Copy the modified value back to the metadatum
+     pos->setValue(rv.get());
+     std::cout << "Modified key \"" << key
+diff --git a/samples/exiv2json.cpp b/samples/exiv2json.cpp
+index fe5a014..91dee73 100644
+--- a/samples/exiv2json.cpp
++++ b/samples/exiv2json.cpp
+@@ -57,7 +57,7 @@ bool getToken(std::string& in,Token& token,Exiv2::StringSet* pNS=NULL)
+ 
+     while ( !result && in.length() ) {
+         std::string c = in.substr(0,1);
+-        char        C = c[0];
++        char        C = c.at(0);
+         in            = in.substr(1,std::string::npos);
+         if ( in.length() == 0 && C != ']' ) token.n += c;
+         if ( C == '/' || C == '[' || C == ':' || C == '.' || C == ']' || in.length() == 0 ) {
+@@ -97,7 +97,7 @@ Jzon::Node& addToTree(Jzon::Node& r1,Token token)
+ 
+ Jzon::Node& recursivelyBuildTree(Jzon::Node& root,Tokens& tokens,size_t k)
+ {
+-    return addToTree( k==0 ? root : recursivelyBuildTree(root,tokens,k-1), tokens[k] );
++    return addToTree( k==0 ? root : recursivelyBuildTree(root,tokens,k-1), tokens.at(k) );
+ }
+ 
+ // build the json tree for this key.  return location and discover the name
+@@ -109,7 +109,7 @@ Jzon::Node& objectForKey(const std::string& Key,Jzon::Object& root,std::string&
+     std::string input  = Key ; // Example: "XMP.xmp.MP.RegionInfo/MPRI:Regions[1]/MPReg:Rectangle"
+     while ( getToken(input,token,pNS) ) tokens.push_back(token);
+     size_t      l      = tokens.size()-1; // leave leaf name to push()
+-    name               = tokens[l].n ;
++    name               = tokens.at(l).n ;
+ 
+     // The second token.  For example: XMP.dc is a namespace
+     if ( pNS && tokens.size() > 1 ) pNS->insert(tokens[1].n);
+diff --git a/src/actions.cpp b/src/actions.cpp
+index 97acac7..a771e21 100644
+--- a/src/actions.cpp
++++ b/src/actions.cpp
+@@ -1108,19 +1108,21 @@ namespace Action {
+ 
+         const Params::PreviewNumbers& numbers = Params::instance().previewNumbers_;
+         for (Params::PreviewNumbers::const_iterator n = numbers.begin(); n != numbers.end(); ++n) {
+-            if (*n == 0) {
++            size_t num = static_cast<size_t>(*n);
++            if (num == 0) {
+                 // Write all previews
+-                for (int num = 0; num < static_cast<int>(pvList.size()); ++num) {
+-                    writePreviewFile(pvMgr.getPreviewImage(pvList[num]), num + 1);
++                for (num = 0; num < pvList.size(); ++num) {
++                    writePreviewFile(pvMgr.getPreviewImage(pvList[num]), static_cast<int>(num + 1));
+                 }
+                 break;
+             }
+-            if (*n > static_cast<int>(pvList.size())) {
++            num--;
++            if (num >= pvList.size()) {
+                 std::cerr << path_ << ": " << _("Image does not have preview")
+-                          << " " << *n << "\n";
++                          << " " << num + 1 << "\n";
+                 continue;
+             }
+-            writePreviewFile(pvMgr.getPreviewImage(pvList[*n - 1]), *n);
++            writePreviewFile(pvMgr.getPreviewImage(pvList[num]), static_cast<int>(num + 1));
+         }
+         return 0;
+     } // Extract::writePreviews
+@@ -1680,7 +1682,7 @@ namespace Action {
+             return 0;
+         }
+         std::string timeStr = md->toString();
+-        if (timeStr == "" || timeStr[0] == ' ') {
++        if (timeStr.empty() || timeStr[0] == ' ') {
+             std::cerr << path << ": " << _("Timestamp of metadatum with key") << " `"
+                       << ek << "' " << _("not set\n");
+             return 1;
+@@ -2240,7 +2242,7 @@ namespace {
+                               << "' " << _("exists. [O]verwrite, [r]ename or [s]kip?")
+                               << " ";
+                     std::cin >> s;
+-                    switch (s[0]) {
++                    switch (s.at(0)) {
+                     case 'o':
+                     case 'O':
+                         go = false;
+@@ -2305,7 +2307,7 @@ namespace {
+                       << ": " << _("Overwrite") << " `" << path << "'? ";
+             std::string s;
+             std::cin >> s;
+-            if (s[0] != 'y' && s[0] != 'Y') return 1;
++            if (s.at(0) != 'y' && s.at(0) != 'Y') return 1;
+         }
+         return 0;
+     }
+diff --git a/src/basicio.cpp b/src/basicio.cpp
+index 7b707e1..ad24938 100644
+--- a/src/basicio.cpp
++++ b/src/basicio.cpp
+@@ -190,11 +190,11 @@ namespace Exiv2 {
+         case opRead:
+             // Flush if current mode allows reading, else reopen (in mode "r+b"
+             // as in this case we know that we can write to the file)
+-            if (openMode_[0] == 'r' || openMode_[1] == '+') reopen = false;
++            if (openMode_.at(0) == 'r' || openMode_.at(1) == '+') reopen = false;
+             break;
+         case opWrite:
+             // Flush if current mode allows writing, else reopen
+-            if (openMode_[0] != 'r' || openMode_[1] == '+') reopen = false;
++            if (openMode_.at(0) != 'r' || openMode_.at(1) == '+') reopen = false;
+             break;
+         case opSeek:
+             reopen = false;
+@@ -2131,7 +2131,7 @@ namespace Exiv2 {
+     void HttpIo::HttpImpl::writeRemote(const byte* data, size_t size, long from, long to)
+     {
+         std::string scriptPath(getEnv(envHTTPPOST));
+-        if (scriptPath == "") {
++        if (scriptPath.empty()) {
+             throw Error(kerErrorMessage, "Please set the path of the server script to handle http post data to EXIV2_HTTP_POST environmental variable.");
+         }
+ 
+diff --git a/src/exiv2.cpp b/src/exiv2.cpp
+index 3d9fa4f..69077c9 100644
+--- a/src/exiv2.cpp
++++ b/src/exiv2.cpp
+@@ -1460,8 +1460,8 @@ namespace {
+             if (valStart != std::string::npos) {
+                 value = parseEscapes(line.substr(valStart, valEnd+1-valStart));
+                 std::string::size_type last = value.length()-1;
+-                if (   (value[0] == '"' && value[last] == '"')
+-                       || (value[0] == '\'' && value[last] == '\'')) {
++                if (   (value.at(0) == '"' && value.at(last) == '"')
++                       || (value.at(0) == '\'' && value.at(last) == '\'')) {
+                     value = value.substr(1, value.length()-2);
+                 }
+             }
+diff --git a/src/minoltamn_int.cpp b/src/minoltamn_int.cpp
+index 77521fc..fc3a73c 100644
+--- a/src/minoltamn_int.cpp
++++ b/src/minoltamn_int.cpp
+@@ -2037,7 +2037,7 @@ namespace Exiv2 {
+     {
+         const TagDetails* td = find(minoltaSonyLensID, lensID);
+         std::vector<std::string> tokens = split(td[0].label_,"|");
+-        return os << exvGettext(trim(tokens[index-1]).c_str());
++        return os << exvGettext(trim(tokens.at(index-1)).c_str());
+     }
+ 
+     static std::ostream& resolveLens0x1c(std::ostream& os, const Value& value,
+diff --git a/src/properties.cpp b/src/properties.cpp
+index c6ebd34..af09f0f 100644
+--- a/src/properties.cpp
++++ b/src/properties.cpp
+@@ -2612,7 +2612,7 @@ namespace Exiv2 {
+         // If property is a path for a nested property, determines the innermost element
+         std::string::size_type i = property.find_last_of('/');
+         if (i != std::string::npos) {
+-            for (; i != std::string::npos && !isalpha(property[i]); ++i) {}
++            for (; i != std::string::npos && !isalpha(property.at(i)); ++i) {}
+             property = property.substr(i);
+             i = property.find_first_of(':');
+             if (i != std::string::npos) {
+diff --git a/src/sigmamn_int.cpp b/src/sigmamn_int.cpp
+index da1beaa..62077bb 100644
+--- a/src/sigmamn_int.cpp
++++ b/src/sigmamn_int.cpp
+@@ -134,7 +134,7 @@ namespace Exiv2 {
+         std::string v = value.toString();
+         std::string::size_type pos = v.find(':');
+         if (pos != std::string::npos) {
+-            if (v[pos + 1] == ' ') ++pos;
++            if (v.at(pos + 1) == ' ') ++pos;
+             v = v.substr(pos + 1);
+         }
+         return os << v;
+@@ -144,7 +144,7 @@ namespace Exiv2 {
+                                               const Value& value,
+                                               const ExifData*)
+     {
+-        switch (value.toString()[0]) {
++        switch (value.toString().at(0)) {
+         case 'P': os << _("Program"); break;
+         case 'A': os << _("Aperture priority"); break;
+         case 'S': os << _("Shutter priority"); break;
+@@ -158,7 +158,7 @@ namespace Exiv2 {
+                                               const Value& value,
+                                               const ExifData*)
+     {
+-        switch (value.toString()[0]) {
++        switch (value.toString().at(0)) {
+         case 'A': os << _("Average"); break;
+         case 'C': os << _("Center"); break;
+         case '8': os << _("8-Segment"); break;
+diff --git a/src/tags_int.cpp b/src/tags_int.cpp
+index df05522..4a4a555 100644
+--- a/src/tags_int.cpp
++++ b/src/tags_int.cpp
+@@ -2867,7 +2867,7 @@ namespace Exiv2 {
+         }
+ 
+         std::string stringValue = value.toString();
+-        if (stringValue[19] == 'Z') {
++        if (stringValue.at(19) == 'Z') {
+             stringValue = stringValue.substr(0, 19);
+         }
+         for (size_t i = 0; i < stringValue.length(); ++i) {
+diff --git a/src/tiffvisitor_int.cpp b/src/tiffvisitor_int.cpp
+index cca9679..5b9addf 100644
+--- a/src/tiffvisitor_int.cpp
++++ b/src/tiffvisitor_int.cpp
+@@ -482,7 +482,7 @@ namespace Exiv2 {
+             uint.push_back((uint16_t) object->pValue()->toLong(i));
+         }
+         // Check this is AFInfo2 (ints[0] = bytes in object)
+-        if ( ints[0] != object->pValue()->count()*2 ) return ;
++        if ( ints.at(0) != object->pValue()->count()*2 ) return ;
+ 
+         std::string familyGroup(std::string("Exif.") + groupName(object->group()) + ".");
+ 
+diff --git a/src/utils.cpp b/src/utils.cpp
+index 66e9898..6b06074 100644
+--- a/src/utils.cpp
++++ b/src/utils.cpp
+@@ -65,7 +65,7 @@ namespace Util {
+         if (p.length() == 2 && p[1] == ':') return p; // For Windows paths
+         std::string::size_type idx = p.find_last_of("\\/");
+         if (idx == std::string::npos) return ".";
+-        if (idx == 1 && p[0] == '\\' && p[1] == '\\') return p; // For Windows paths
++        if (idx == 1 && p.at(0) == '\\' && p.at(1) == '\\') return p; // For Windows paths
+         p = p.substr(0, idx == 0 ? 1 : idx);
+         while (   p.length() > 1
+                && (p[p.length()-1] == '\\' || p[p.length()-1] == '/')) {
+@@ -85,7 +85,7 @@ namespace Util {
+         }
+         if (p.length() == 2 && p[1] == ':') return ""; // For Windows paths
+         std::string::size_type idx = p.find_last_of("\\/");
+-        if (idx == 1 && p[0] == '\\' && p[1] == '\\') return ""; // For Windows paths
++        if (idx == 1 && p.at(0) == '\\' && p.at(1) == '\\') return ""; // For Windows paths
+         if (idx != std::string::npos) p = p.substr(idx+1);
+         if (delsuffix) p = p.substr(0, p.length() - suffix(p).length());
+         return p;
+diff --git a/src/value.cpp b/src/value.cpp
+index 2536b84..470b864 100644
+--- a/src/value.cpp
++++ b/src/value.cpp
+@@ -497,8 +497,10 @@ namespace Exiv2 {
+             std::string::size_type pos = comment.find_first_of(' ');
+             std::string name = comment.substr(8, pos-8);
+             // Strip quotes (so you can also specify the charset without quotes)
+-            if (name[0] == '"') name = name.substr(1);
+-            if (name[name.length()-1] == '"') name = name.substr(0, name.length()-1);
++            if (!name.empty()) {
++                if (name[0] == '"') name = name.substr(1);
++                if (name[name.length()-1] == '"') name = name.substr(0, name.length()-1);
++            }
+             charsetId = CharsetInfo::charsetIdByName(name);
+             if (charsetId == invalidCharsetId) {
+ #ifndef SUPPRESS_WARNINGS
+diff --git a/src/xmp.cpp b/src/xmp.cpp
+index 03ce7e0..40b8f8c 100644
+--- a/src/xmp.cpp
++++ b/src/xmp.cpp
+@@ -500,8 +500,7 @@ namespace Exiv2 {
+         bool bNS  = out.find(':') != std::string::npos && !bURI;
+ 
+         // pop trailing ':' on a namespace
+-        if ( bNS ) {
+-        std::size_t length = out.length();
++        if ( bNS && !out.empty() ) {
+             if ( out[length-1] == ':' ) out = out.substr(0,length-1);
+         }
+ 
diff --git a/meta-oe/recipes-support/exiv2/exiv2_0.27.3.bb b/meta-oe/recipes-support/exiv2/exiv2_0.27.3.bb
index e7eac337dc..4001f1b639 100644
--- a/meta-oe/recipes-support/exiv2/exiv2_0.27.3.bb
+++ b/meta-oe/recipes-support/exiv2/exiv2_0.27.3.bb
@@ -26,6 +26,8 @@ SRC_URI = "https://github.com/Exiv2/${BPN}/releases/download/v${PV}/${BP}-Source
            file://CVE-2021-37615-2.patch \
            file://CVE-2021-37618.patch \
            file://CVE-2021-37619.patch \
+           file://CVE-2021-37620-1.patch \
+           file://CVE-2021-37620-2.patch \
            "
 SRC_URI[sha256sum] = "a79f5613812aa21755d578a297874fb59a85101e793edc64ec2c6bd994e3e778"
 
