CVE-2022-1908: Out-of-bounds Read (CWE-125)
value: Buffer Over-read in GitHub repository bfabiszewski/libmobi prior to 0.11.
CWE description: The product reads data past the end, or before the beginning, of the intended buffer.
CVSS v3 base score: 8.1
Published: 2022-05-27T09:15Z
Repository: https://github.com/bfabiszewski/libmobi
Language: Other
Files changed: ChangeLog, src/parse_rawml.c
Commit date: 2022-05-03 09:54:25 +0200
Commit message: Fix boundary checking error in markup search, that could cause buffer over-read with corrupt input

Diff: diff --git a/ChangeLog b/ChangeLog
index 571ac3b..3f93455 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,6 @@
+2022-05-03: Fix boundary checking error in markup search, that could cause buffer over-read with corrupt input
 2022-05-02: Fix typo in macro name
 2022-04-27: Fix undefined behavior when passing null to strdup
 2022-04-27: Fix wrong boundary checks in inflections parser resulting in stack buffer over-read with corrupt input
 2022-04-26: Fix text formatting
 2022-04-26: Fix array boundary check when parsing inflections which could result in buffer over-read with corrupt input
diff --git a/src/parse_rawml.c b/src/parse_rawml.c
index 6b6c9d7..41ba9a3 100644
--- a/src/parse_rawml.c
+++ b/src/parse_rawml.c
@@ -105,11 +105,11 @@ MOBI_RET mobi_search_links_kf7(MOBIResult *result, const unsigned char *data_sta
                 int i = 0;
                 while (data <= data_end && !isspace(*data) && *data != tag_close && i < MOBI_ATTRVALUE_MAXSIZE) {
                     result->value[i++] = (char) *data++;
                 }
                 /* self closing tag '/>' */
-                if (*(data - 1) == '/' && *data == '>') {
+                if (data <= data_end && *(data - 1) == '/' && *data == '>') {
                     --data; --i;
                 }
                 result->end = data;
                 result->value[i] = '\0';
                 return MOBI_SUCCESS;
@@ -180,11 +180,11 @@ MOBI_RET mobi_find_attrvalue(MOBIResult *result, const unsigned char *data_start
             int i = 0;
             while (data <= data_end && !isspace(*data) && *data != tag_close && *data != ')' && i < MOBI_ATTRVALUE_MAXSIZE) {
                 result->value[i++] = (char) *data++;
             }
             /* self closing tag '/>' */
-            if (*(data - 1) == '/' && *data == '>') {
+            if (data <= data_end && *(data - 1) == '/' && *data == '>') {
                 --data; --i;
             }
             result->end = data;
             result->value[i] = '\0';
             return MOBI_SUCCESS;
@@ -352,11 +352,11 @@ size_t mobi_get_attribute_value(char *value, const unsigned char *data, const si
             for (j = 0; j < MOBI_ATTRVALUE_MAXSIZE && length && *data != separator && *data != '>'; j++) {
                 *value++ = (char) *data++;
                 length--;
             }
             /* self closing tag '/>' */
-            if (*(data - 1) == '/' && *data == '>') {
+            if (length && *(data - 1) == '/' && *data == '>') {
                 value--;
             }
             *value = '\0';
             /* return offset to the beginning of the attribute value string */
             return size - length - j;

Vulnerable code:                 if (*(data - 1) == '/' && *data == '>') {
            if (*(data - 1) == '/' && *data == '>') {
            if (*(data - 1) == '/' && *data == '>') {
Fixed code: 2022-05-03: Fix boundary checking error in markup search, that could cause buffer over-read with corrupt input
                if (data <= data_end && *(data - 1) == '/' && *data == '>') {
            if (data <= data_end && *(data - 1) == '/' && *data == '>') {
            if (length && *(data - 1) == '/' && *data == '>') {