diff --git a/ports/gifdec/CMakeLists.txt b/ports/gifdec/CMakeLists.txt new file mode 100644 index 00000000000000..4c4a46fb731a9c --- /dev/null +++ b/ports/gifdec/CMakeLists.txt @@ -0,0 +1,32 @@ +cmake_minimum_required(VERSION 3.15) +project(gifdec LANGUAGES C) + +add_library(gifdec gifdec.c) +target_include_directories(gifdec PUBLIC + "$" + "$") + +install(TARGETS gifdec + EXPORT gifdec_targets + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib + RUNTIME DESTINATION bin +) +install(FILES gifdec.h DESTINATION include) + +include(CMakePackageConfigHelpers) +set(PACKAGE_CONFIG_FILE "${CMAKE_CURRENT_BINARY_DIR}/unofficial-gifdec-config.cmake") +set(INSTALL_CONFIG_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/unofficial-gifdec") + +configure_package_config_file(unofficial-gifdec-config.cmake.in + "${PACKAGE_CONFIG_FILE}" + INSTALL_DESTINATION "${INSTALL_CONFIG_DIR}" +) + +install(EXPORT gifdec_targets + NAMESPACE unofficial::gifdec:: + FILE unofficial-gifdec-targets.cmake + DESTINATION "${INSTALL_CONFIG_DIR}" +) + +install(FILES "${PACKAGE_CONFIG_FILE}" DESTINATION "${INSTALL_CONFIG_DIR}") diff --git a/ports/gifdec/FIX-CVE-2022-43359.patch b/ports/gifdec/FIX-CVE-2022-43359.patch new file mode 100644 index 00000000000000..8be87c989d54c3 --- /dev/null +++ b/ports/gifdec/FIX-CVE-2022-43359.patch @@ -0,0 +1,201 @@ +From 777d74f806f7e9241336efd1c76865c07e2f0436 Mon Sep 17 00:00:00 2001 +From: everestsummer +Date: Sat, 20 Aug 2022 13:21:07 +0800 +Subject: [PATCH 1/6] Fix: Security: Uninitialized variables may cause SIGSEGV + +--- + gifdec.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/gifdec.c b/gifdec.c +index 83c2d0f5b4ba5fa45e70d3decab2b133d3cc6ce3..61448ecc5ef710615f534a69c99f64bf90e40714 100644 +--- a/gifdec.c ++++ b/gifdec.c +@@ -333,12 +333,12 @@ static int + read_image_data(gd_GIF *gif, int interlace) + { + uint8_t sub_len, shift, byte; +- int init_key_size, key_size, table_is_full; +- int frm_off, frm_size, str_len, i, p, x, y; ++ int init_key_size, key_size, table_is_full = 0; ++ int frm_off, frm_size, str_len = 0, i, p, x, y; + uint16_t key, clear, stop; + int ret; + Table *table; +- Entry entry; ++ Entry entry = { 0 }; + off_t start, end; + + read(gif->fd, &byte, 1); + +From f29dc41102ea62f4d6a1c9e9438e8addf81fb1ab Mon Sep 17 00:00:00 2001 +From: everestsummer +Date: Sat, 20 Aug 2022 13:25:23 +0800 +Subject: [PATCH 2/6] Fix: Security: 'key' maybe a value bigger than + table->nentries, causing out of bounds read access. + +--- + gifdec.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/gifdec.c b/gifdec.c +index 61448ecc5ef710615f534a69c99f64bf90e40714..8f0e2db3fc4ae416df190b9d6ae5c174d92bedc8 100644 +--- a/gifdec.c ++++ b/gifdec.c +@@ -379,6 +379,7 @@ read_image_data(gd_GIF *gif, int interlace) + key = get_key(gif, key_size, &sub_len, &shift, &byte); + if (key == clear) continue; + if (key == stop || key == 0x1000) break; ++ if (key >= table->nentries) break; + if (ret == 1) key_size++; + entry = table->entries[key]; + str_len = entry.length; + +From 970558212348b60359f967a5d999078b6f9efe04 Mon Sep 17 00:00:00 2001 +From: everestsummer +Date: Sat, 20 Aug 2022 13:36:15 +0800 +Subject: [PATCH 3/6] Fix: Security: entry.prefix may be a bigger value than + table->nentries, causing oob read. + +--- + gifdec.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gifdec.c b/gifdec.c +index 8f0e2db3fc4ae416df190b9d6ae5c174d92bedc8..c6718e147dc710534cd3423c5807adde730150fc 100644 +--- a/gifdec.c ++++ b/gifdec.c +@@ -390,7 +390,7 @@ read_image_data(gd_GIF *gif, int interlace) + if (interlace) + y = interlaced_line_index((int) gif->fh, y); + gif->frame[(gif->fy + y) * gif->width + gif->fx + x] = entry.suffix; +- if (entry.prefix == 0xFFF) ++ if (entry.prefix == 0xFFF || entry.prefix >= table->nentries) + break; + else + entry = table->entries[entry.prefix]; + +From bdfad6b169f758a0c74cf7ddde7f591cfd8ef248 Mon Sep 17 00:00:00 2001 +From: everestsummer +Date: Sat, 20 Aug 2022 15:43:10 +0800 +Subject: [PATCH 4/6] Fix: Security: Infinite loop in discard_sub_blocks + +--- + gifdec.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/gifdec.c b/gifdec.c +index c6718e147dc710534cd3423c5807adde730150fc..de1e303d46f4127af0161be9177253ac55045a65 100644 +--- a/gifdec.c ++++ b/gifdec.c +@@ -121,11 +121,17 @@ gd_open_gif(const char *fname) + static void + discard_sub_blocks(gd_GIF *gif) + { ++ uint8_t first_try = 1; ++ uint8_t seek_pos; + uint8_t size; + + do { + read(gif->fd, &size, 1); ++ if (!first_try && size == seek_pos) //To prevent infinite loop ++ break; + lseek(gif->fd, size, SEEK_CUR); ++ seek_pos = size; ++ first_try = 0; + } while (size); + } + + +From 271d1d22ce3d86ecddbd0f9205f0b70fa9fd7529 Mon Sep 17 00:00:00 2001 +From: everestsummer +Date: Sat, 20 Aug 2022 15:43:58 +0800 +Subject: [PATCH 5/6] Fix: Security: Infinite loop in read_ext + +--- + gifdec.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/gifdec.c b/gifdec.c +index de1e303d46f4127af0161be9177253ac55045a65..dd2d5b3e77a88129823be9dec6bc6a1e9683a0ef 100644 +--- a/gifdec.c ++++ b/gifdec.c +@@ -224,7 +224,8 @@ read_ext(gd_GIF *gif) + { + uint8_t label; + +- read(gif->fd, &label, 1); ++ if(read(gif->fd, &label, 1) < 1) ++ return; + switch (label) { + case 0x01: + read_plain_text_ext(gif); +@@ -502,7 +503,8 @@ gd_get_frame(gd_GIF *gif) + if (sep == '!') + read_ext(gif); + else return -1; +- read(gif->fd, &sep, 1); ++ if(read(gif->fd, &sep, 1) < 1) ++ return -1; + } + if (read_image(gif) == -1) + return -1; + +From b17f41093397ef0b698dd718ab109625716414fe Mon Sep 17 00:00:00 2001 +From: everestsummer +Date: Sat, 20 Aug 2022 16:44:41 +0800 +Subject: [PATCH 6/6] Fix: Security: Prevent i from being overflowed to + negative value (and SIGSEGV) + +--- + gifdec.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/gifdec.c b/gifdec.c +index dd2d5b3e77a88129823be9dec6bc6a1e9683a0ef..75bfc7d4af628389a4f362bb9728fd581e4dabf0 100644 +--- a/gifdec.c ++++ b/gifdec.c +@@ -44,7 +44,7 @@ gd_open_gif(const char *fname) + uint8_t sigver[3]; + uint16_t width, height, depth; + uint8_t fdsz, bgidx, aspect; +- int i; ++ size_t i; + uint8_t *bgcolor; + int gct_sz; + gd_GIF *gif; +@@ -121,13 +121,13 @@ gd_open_gif(const char *fname) + static void + discard_sub_blocks(gd_GIF *gif) + { +- uint8_t first_try = 1; ++ uint8_t first_try = 1; + uint8_t seek_pos; + uint8_t size; + + do { + read(gif->fd, &size, 1); +- if (!first_try && size == seek_pos) //To prevent infinite loop ++ if (!first_try && size == seek_pos) //To prevent infinite loop + break; + lseek(gif->fd, size, SEEK_CUR); + seek_pos = size; +@@ -225,7 +225,8 @@ read_ext(gd_GIF *gif) + uint8_t label; + + if(read(gif->fd, &label, 1) < 1) +- return; ++ return; ++ + switch (label) { + case 0x01: + read_plain_text_ext(gif); +@@ -504,7 +505,7 @@ gd_get_frame(gd_GIF *gif) + read_ext(gif); + else return -1; + if(read(gif->fd, &sep, 1) < 1) +- return -1; ++ return -1; + } + if (read_image(gif) == -1) + return -1; diff --git a/ports/gifdec/portfile.cmake b/ports/gifdec/portfile.cmake new file mode 100644 index 00000000000000..33fa02beb53fda --- /dev/null +++ b/ports/gifdec/portfile.cmake @@ -0,0 +1,29 @@ +if(VCPKG_TARGET_IS_WINDOWS) + vcpkg_check_linkage(ONLY_STATIC_LIBRARY) +endif() + +vcpkg_from_github( + OUT_SOURCE_PATH SOURCE_PATH + REPO lecram/gifdec + REF 1dcbae19363597314f6623010cc80abad4e47f7c + SHA512 2756004cb7dd8be5560a32c188001da503b97f1b8e3eed908787563b7e36edf8cbca3605e2e75b2ebbc69b329e16d89b3237028dfd7a772d2763bf78b1675ad2 + HEAD_REF master + PATCHES + FIX-CVE-2022-43359.patch +) + +file(COPY + "${CMAKE_CURRENT_LIST_DIR}/CMakeLists.txt" + "${CMAKE_CURRENT_LIST_DIR}/unofficial-gifdec-config.cmake.in" + DESTINATION "${SOURCE_PATH}" +) + +vcpkg_cmake_configure( + SOURCE_PATH "${SOURCE_PATH}" +) + +vcpkg_cmake_install() +vcpkg_cmake_config_fixup(PACKAGE_NAME unofficial-gifdec CONFIG_PATH lib/cmake/unofficial-gifdec) + +file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/include") +vcpkg_install_copyright(FILE_LIST "${SOURCE_PATH}/README") diff --git a/ports/gifdec/unofficial-gifdec-config.cmake.in b/ports/gifdec/unofficial-gifdec-config.cmake.in new file mode 100644 index 00000000000000..e71a55e6692763 --- /dev/null +++ b/ports/gifdec/unofficial-gifdec-config.cmake.in @@ -0,0 +1,3 @@ +@PACKAGE_INIT@ +include("${CMAKE_CURRENT_LIST_DIR}/unofficial-gifdec-targets.cmake") +check_required_components("unofficial-gifdec") diff --git a/ports/gifdec/vcpkg.json b/ports/gifdec/vcpkg.json new file mode 100644 index 00000000000000..a22d553304b837 --- /dev/null +++ b/ports/gifdec/vcpkg.json @@ -0,0 +1,17 @@ +{ + "name": "gifdec", + "version-date": "2021-12-04", + "description": "Small C library for reading GIF files", + "homepage": "https://github.com/lecram/gifdec", + "license": "LicenseRef-Public-Domain", + "dependencies": [ + { + "name": "vcpkg-cmake", + "host": true + }, + { + "name": "vcpkg-cmake-config", + "host": true + } + ] +} diff --git a/scripts/test_ports/vcpkg-ci-gifdec/portfile.cmake b/scripts/test_ports/vcpkg-ci-gifdec/portfile.cmake new file mode 100644 index 00000000000000..8a2079b2178d36 --- /dev/null +++ b/scripts/test_ports/vcpkg-ci-gifdec/portfile.cmake @@ -0,0 +1,5 @@ +set(VCPKG_POLICY_EMPTY_PACKAGE enabled) +vcpkg_cmake_configure( + SOURCE_PATH "${CURRENT_PORT_DIR}/project" +) +vcpkg_cmake_build() diff --git a/scripts/test_ports/vcpkg-ci-gifdec/project/CMakeLists.txt b/scripts/test_ports/vcpkg-ci-gifdec/project/CMakeLists.txt new file mode 100644 index 00000000000000..958f3a23adbe7e --- /dev/null +++ b/scripts/test_ports/vcpkg-ci-gifdec/project/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.22) +project(gifdec-test LANGUAGES C) +find_package(unofficial-gifdec CONFIG REQUIRED) +add_executable(main main.c) +target_link_libraries(main PRIVATE unofficial::gifdec::gifdec) diff --git a/scripts/test_ports/vcpkg-ci-gifdec/project/main.c b/scripts/test_ports/vcpkg-ci-gifdec/project/main.c new file mode 100644 index 00000000000000..b1e33caeb7b681 --- /dev/null +++ b/scripts/test_ports/vcpkg-ci-gifdec/project/main.c @@ -0,0 +1,8 @@ +#include +int main() +{ + gd_GIF *gif; + gif = gd_open_gif("test.gif"); + gd_close_gif(gif); + return 0; +} diff --git a/scripts/test_ports/vcpkg-ci-gifdec/vcpkg.json b/scripts/test_ports/vcpkg-ci-gifdec/vcpkg.json new file mode 100644 index 00000000000000..d94771b1e1372d --- /dev/null +++ b/scripts/test_ports/vcpkg-ci-gifdec/vcpkg.json @@ -0,0 +1,12 @@ +{ + "name": "vcpkg-ci-gifdec", + "version-string": "ci", + "description": "Validates gifdec", + "dependencies": [ + "gifdec", + { + "name": "vcpkg-cmake", + "host": true + } + ] +} diff --git a/versions/baseline.json b/versions/baseline.json index 5254fd4e2a74f4..dc326056f98c81 100644 --- a/versions/baseline.json +++ b/versions/baseline.json @@ -3436,6 +3436,10 @@ "baseline": "2019-01-06", "port-version": 0 }, + "gifdec": { + "baseline": "2021-12-04", + "port-version": 0 + }, "giflib": { "baseline": "6.1.3", "port-version": 0 diff --git a/versions/g-/gifdec.json b/versions/g-/gifdec.json new file mode 100644 index 00000000000000..2cad706308e221 --- /dev/null +++ b/versions/g-/gifdec.json @@ -0,0 +1,9 @@ +{ + "versions": [ + { + "git-tree": "2f4b99fdebaf7c596a86c52b3ed2fe86b8fae885", + "version-date": "2021-12-04", + "port-version": 0 + } + ] +}