Fix a possible sign-bit overwrite when a uint32_t integer is given to signed integral... 24/307424/2
authorSung-hun Kim <sfoon.kim@samsung.com>
Fri, 8 Mar 2024 02:00:54 +0000 (11:00 +0900)
committerSung-hun Kim <sfoon.kim@samsung.com>
Fri, 8 Mar 2024 07:32:16 +0000 (16:32 +0900)
Since std::streamoff is a typedef of signed integral type, the sign bit of std::streamoff can be
overwritten by the given uint32_t value. This patch handles the case in a separated manner.

This patch fixes svace issues (wgid: 706371, 704245).

Change-Id: Ib79e0af8af99dafb24336ed261d018ddf22be362
Signed-off-by: Sung-hun Kim <sfoon.kim@samsung.com>
src/livedumper/core.hpp

index d084b08648d597a91f3e361a16d19814701bcf3a..81b359ca4111eac8e31465bcf4c2a7057ea70962 100644 (file)
@@ -168,8 +168,14 @@ class Core {
                                logger.log_error("lseek64 error: %s", std::system_category().default_error_condition(errno).message().c_str());
                        if (!minicore || static_cast<ProgramTableEntryLoad<T>*>(record.get())->important)
                                CopyData(mem_fd, core_file, record->header.p_filesz);
-                       else
-                               core_file.seekp(record->header.p_filesz, std::ios_base::cur);
+                       else {
+                               if (sizeof(std::streamoff) == sizeof(uint32_t) && record->header.p_filesz > INT_MAX) {
+                                       core_file.seekp(INT_MAX, std::ios_base::cur);
+                                       core_file.seekp(static_cast<std::streamoff>(record->header.p_filesz - INT_MAX), std::ios_base::cur);
+                               } else {
+                                       core_file.seekp(static_cast<std::streamoff>(record->header.p_filesz), std::ios_base::cur);
+                               }
+                       }
                }
        }
 
@@ -237,7 +243,13 @@ class Core {
                        return;
                }
 
-               output.seekp(oaddress, std::ios_base::beg);
+               /* Since std::streamoff is signed type, unsigned typed value can overwrite signed bit */
+               if (sizeof(typename T::Addr) == sizeof(std::streamoff) && oaddress > INT_MAX) {
+                       output.seekp(INT_MAX, std::ios_base::beg);
+                       output.seekp(static_cast<std::streamoff>(oaddress - INT_MAX), std::ios_base::cur);
+               } else {
+                       output.seekp(static_cast<std::streamoff>(oaddress), std::ios_base::beg);
+               }
                constexpr const char * format = std::is_same<T, Elf64>::value ?
                                     "dumping %s: 0x%" PRIx64 "-0x%" PRIx64 " to 0x%" PRIx64 " (%zu bytes)" :
                                     "dumping %s: 0x%" PRIx32 "-0x%" PRIx32 " to 0x%" PRIx32 " (%zu bytes)";