CVE-2022-1987 (published 2022-06-03T08:15Z)

Buffer Over-read in GitHub repository bfabiszewski/libmobi prior to 0.11.

Severity: MEDIUM
CVSS v2 base score: 5.8 (AV:N/AC:M/Au:N/C:P/I:N/A:P)
CVSS v3 base score: 8.1, HIGH (CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:H)

Weakness information:
cwe_id: CWE-125
cwe_name: Out-of-bounds Read
description: The product reads data past the end, or before the beginning, of the intended buffer.
extended_description: 
            
            
             
			 
         
         

Fix information:
repo_url: https://github.com/bfabiszewski/libmobi
commit_details: repo_url: https://github.com/bfabiszewski/libmobi
author: Bartek Fabiszewski
author_date: 2022-05-05 20:54:11+02:00
msg: Fix: index entry label not being zero-terminated with corrupt input
repository: repo_url: https://github.com/bfabiszewski/libmobi
repo_name: bfabiszewski/libmobi
description: C library for handling Kindle (MOBI) formats of ebook documents
repo_language: C
owner: bfabiszewski
file_changes: filename: ChangeLog
change_type: ModificationType.MODIFY
diff: @@ -1,3 +1,4 @@
+2022-05-05: Fix: index entry label not being zero-terminated with corrupt input
 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

programming_language: Markdown
filename: index.c
change_type: ModificationType.MODIFY
diff: @@ -29,11 +29,11 @@
 /**
  @brief Read index entry label from buffer pointing at index record data
  
- @param[in,out] output Output string
+ @param[in,out] output Output buffer (INDX_LABEL_SIZEMAX + 1 bytes)
  @param[in,out] buf MOBIBuffer structure, offset pointing at index entry label
  @param[in] length Number of bytes to be read
  @param[in] has_ligatures Decode ligatures if true
- @return Size of read label
+ @return Length of output string (without null terminator), on error buf->error set to MOBI_RET status
  */
 size_t mobi_indx_get_label(unsigned char *output, MOBIBuffer *buf, const size_t length, const size_t has_ligatures) {
     if (!output) {
@@ -248,9 +248,9 @@ uint16_t mobi_ordt_lookup(const MOBIOrdt *ordt, const uint16_t offset) {
  
  @param[in] ordt MOBIOrdt structure (ORDT data and metadata)
  @param[in,out] buf MOBIBuffer structure with input string
- @param[in,out] output Output buffer (INDX_LABEL_SIZEMAX bytes)
+ @param[in,out] output Output buffer (INDX_LABEL_SIZEMAX + 1 bytes)
  @param[in] length Length of input string contained in buf
- @return Number of bytes read
+ @return Length of output string (without null terminator)
  */
 size_t mobi_getstring_ordt(const MOBIOrdt *ordt, MOBIBuffer *buf, unsigned char *output, size_t length) {
     size_t i = 0;
@@ -362,12 +362,16 @@ static MOBI_RET mobi_parse_index_entry(MOBIIndx *indx, const MOBIIdxt idxt, cons
         debug_print("Label length too long: %zu\n", label_length);
         return MOBI_DATA_CORRUPT;
     }
-    char text[INDX_LABEL_SIZEMAX];
+    char text[INDX_LABEL_SIZEMAX + 1];
     /* FIXME: what is ORDT1 for? */
     if (ordt->ordt2) {
         label_length = mobi_getstring_ordt(ordt, buf, (unsigned char*) text, label_length);
     } else {
         label_length = mobi_indx_get_label((unsigned char*) text, buf, label_length, indx->ligt_entries_count);
+        if (buf->error != MOBI_SUCCESS) {
+            debug_print("Buffer error reading label: %d\n", buf->error);
+            return MOBI_DATA_CORRUPT;
+        }
     }
     indx->entries[entry_number].label = malloc(label_length + 1);
     if (indx->entries[entry_number].label == NULL) {

programming_language: C