CVE-2022-2279 (published 2022-07-01T09:15Z)

NULL Pointer Dereference in GitHub repository bfabiszewski/libmobi prior to 0.11.

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

Weakness information:
cwe_id: CWE-476
cwe_name: NULL Pointer Dereference
description: The product dereferences a pointer that it expects to be valid but is NULL.
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-04-27 12:35:39+02:00
msg: Fix undefined behavior when passing null to strdup
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-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

programming_language: Markdown
filename: opf.c
change_type: ModificationType.MODIFY
diff: @@ -1152,24 +1152,30 @@ MOBI_RET mobi_build_opf_metadata(OPF *opf,  const MOBIData *m, const MOBIRawml *
     if (mobi_is_dictionary(m)) {
         if (opf->metadata->x_meta->dictionary_in_lang == NULL) {
             if (m->mh && m->mh->dict_input_lang) {
-                opf->metadata->x_meta->dictionary_in_lang = calloc(OPF_META_MAX_TAGS, sizeof(char*));
-                if (opf->metadata->x_meta->dictionary_in_lang == NULL) {
-                    debug_print("%s\n", "Memory allocation failed");
-                    return MOBI_MALLOC_FAILED;
-                }
                 uint32_t dict_lang_in = *m->mh->dict_input_lang;
-                opf->metadata->x_meta->dictionary_in_lang[0] = strdup(mobi_get_locale_string(dict_lang_in));
+                const char *lang = mobi_get_locale_string(dict_lang_in);
+                if (lang) {
+                    opf->metadata->x_meta->dictionary_in_lang = calloc(OPF_META_MAX_TAGS, sizeof(char*));
+                    if (opf->metadata->x_meta->dictionary_in_lang == NULL) {
+                        debug_print("%s\n", "Memory allocation failed");
+                        return MOBI_MALLOC_FAILED;
+                    }
+                    opf->metadata->x_meta->dictionary_in_lang[0] = strdup(lang);
+                }
             }
         }
         if (opf->metadata->x_meta->dictionary_out_lang == NULL) {
             if (m->mh && m->mh->dict_output_lang) {
-                opf->metadata->x_meta->dictionary_out_lang = calloc(OPF_META_MAX_TAGS, sizeof(char*));
-                if (opf->metadata->x_meta->dictionary_out_lang == NULL) {
-                    debug_print("%s\n", "Memory allocation failed");
-                    return MOBI_MALLOC_FAILED;
+                uint32_t dict_lang_out = *m->mh->dict_output_lang;
+                const char *lang = mobi_get_locale_string(dict_lang_out);
+                if (lang) {
+                    opf->metadata->x_meta->dictionary_out_lang = calloc(OPF_META_MAX_TAGS, sizeof(char*));
+                    if (opf->metadata->x_meta->dictionary_out_lang == NULL) {
+                        debug_print("%s\n", "Memory allocation failed");
+                        return MOBI_MALLOC_FAILED;
+                    }
+                    opf->metadata->x_meta->dictionary_out_lang[0] = strdup(lang);
                 }
-                uint32_t dict_lang_in = *m->mh->dict_output_lang;
-                opf->metadata->x_meta->dictionary_out_lang[0] = strdup(mobi_get_locale_string(dict_lang_in));
             }
         }
         if (rawml->orth->orth_index_name) {

programming_language: C
filename: util.c
change_type: ModificationType.MODIFY
diff: @@ -641,7 +641,7 @@ static const char *mobi_locale[MOBI_LANG_MAX][MOBI_REGION_MAX] = {
  See mobi_locale array.
  
  @param[in] locale_number Mobipocket locale number (as stored in MOBI header)
- @return Pointer to locale string in mobi_locale array
+ @return Pointer to locale string in mobi_locale array or NULL on error
  */
 const char * mobi_get_locale_string(const uint32_t locale_number) {
     uint8_t lang_code = locale_number & 0xffU;

programming_language: C
filename: common.c
change_type: ModificationType.MODIFY
diff: @@ -330,7 +330,7 @@ void print_summary(const MOBIData *m) {
             *m->mh->dict_input_lang && *m->mh->dict_output_lang) {
             const char *locale_in = mobi_get_locale_string(*m->mh->dict_input_lang);
             const char *locale_out = mobi_get_locale_string(*m->mh->dict_output_lang);
-            printf(": %s => %s", locale_in, locale_out);
+            printf(": %s => %s", locale_in ? locale_in : "unknown", locale_out ? locale_out : "unknown");
         }
         printf("\n");
     }

programming_language: C