Bug#1109386: unblock: protozero/1.8.1-1 (pre-approval)
Bas Couwenberg
sebastic at xs4all.nl
Wed Jul 16 11:57:07 BST 2025
Package: release.debian.org
Severity: normal
X-Debbugs-Cc: protozero at packages.debian.org
Control: affects -1 + src:protozero
User: release.debian.org at packages.debian.org
Usertags: unblock
Please unblock package protozero
The new upstream release has been uploaded to experimental for now, but I'd like to move it to unstable and have it migrate to testing too.
[ Reason ]
Fixes a buffer overrun security issue.
[ Impact ]
Unfixed security issue.
[ Tests ]
Upstream test suite.
[ Risks ]
Low, only three rdeps (libosmium, mapnik, qtlocation-opensource-src).
[ Checklist ]
[x] all changes are documented in the d/changelog
[x] I reviewed all changes and I approve them
[x] attach debdiff against the package in testing
[ Other info ]
Upstream reported the issue on the debian-gis list:
https://lists.debian.org/debian-gis/2025/07/msg00002.html
unblock protozero/1.8.1-1
-------------- next part --------------
diff -Nru protozero-1.8.0/CHANGELOG.md protozero-1.8.1/CHANGELOG.md
--- protozero-1.8.0/CHANGELOG.md 2025-01-13 10:42:19.000000000 +0100
+++ protozero-1.8.1/CHANGELOG.md 2025-07-15 19:28:17.000000000 +0200
@@ -14,7 +14,15 @@
### Fixed
-## [1.8.0] - 2024-01-13
+## [1.8.1] - 2025-07-15
+
+### Fixed
+
+- Fix buffer overrun in `get_bool()`
+- Fix test that checks that protozero also works with `std::string_view`
+
+
+## [1.8.0] - 2025-01-13
### Changed
diff -Nru protozero-1.8.0/CMakeLists.txt protozero-1.8.1/CMakeLists.txt
--- protozero-1.8.0/CMakeLists.txt 2025-01-13 10:42:19.000000000 +0100
+++ protozero-1.8.1/CMakeLists.txt 2025-07-15 19:28:17.000000000 +0200
@@ -10,7 +10,7 @@
#-----------------------------------------------------------------------------
-project(protozero VERSION 1.8.0 LANGUAGES CXX C)
+project(protozero VERSION 1.8.1 LANGUAGES CXX C)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
@@ -40,9 +40,13 @@
include_directories("${CMAKE_SOURCE_DIR}/include")
+# Used for testing
set(PROTOZERO_DATA_VIEW "" CACHE STRING "Type used for protozero::data_view")
if(NOT PROTOZERO_DATA_VIEW STREQUAL "")
- add_definitions(-DPROTOZERO_DATA_VIEW=${PROTOZERO_DATA_VIEW})
+ message(STATUS "Using ${PROTOZERO_DATA_VIEW} as data_view")
+ add_definitions(-DPROTOZERO_USE_VIEW=${PROTOZERO_DATA_VIEW})
+else()
+ message(STATUS "Using built-in data_view")
endif()
diff -Nru protozero-1.8.0/debian/changelog protozero-1.8.1/debian/changelog
--- protozero-1.8.0/debian/changelog 2025-01-14 05:33:36.000000000 +0100
+++ protozero-1.8.1/debian/changelog 2025-07-16 12:48:27.000000000 +0200
@@ -1,3 +1,17 @@
+protozero (1.8.1-1) unstable; urgency=medium
+
+ * Move from experimental to unstable.
+
+ -- Bas Couwenberg <sebastic at debian.org> Wed, 16 Jul 2025 12:48:27 +0200
+
+protozero (1.8.1-1~exp1) experimental; urgency=medium
+
+ * New upstream release.
+ * Bump Standards-Version to 4.7.2, no changes.
+ * Fix old FSF address in copyright file.
+
+ -- Bas Couwenberg <sebastic at debian.org> Wed, 16 Jul 2025 12:44:43 +0200
+
protozero (1.8.0-1) unstable; urgency=medium
* New upstream release.
diff -Nru protozero-1.8.0/debian/control protozero-1.8.1/debian/control
--- protozero-1.8.0/debian/control 2024-07-28 19:52:33.000000000 +0200
+++ protozero-1.8.1/debian/control 2025-07-16 12:48:08.000000000 +0200
@@ -10,7 +10,7 @@
libprotobuf-dev <!nocheck>,
protobuf-compiler <!nocheck>,
pkgconf
-Standards-Version: 4.7.0
+Standards-Version: 4.7.2
Vcs-Browser: https://salsa.debian.org/debian-gis-team/protozero/
Vcs-Git: https://salsa.debian.org/debian-gis-team/protozero.git
Homepage: https://github.com/mapbox/protozero
diff -Nru protozero-1.8.0/debian/copyright protozero-1.8.1/debian/copyright
--- protozero-1.8.0/debian/copyright 2025-01-14 05:32:16.000000000 +0100
+++ protozero-1.8.1/debian/copyright 2025-03-29 07:28:35.000000000 +0100
@@ -92,10 +92,6 @@
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- .
On Debian systems, the complete text of version 2 of the GNU General
Public License can be found in `/usr/share/common-licenses/GPL-2'.
diff -Nru protozero-1.8.0/doc/CMakeLists.txt protozero-1.8.1/doc/CMakeLists.txt
--- protozero-1.8.0/doc/CMakeLists.txt 2025-01-13 10:42:19.000000000 +0100
+++ protozero-1.8.1/doc/CMakeLists.txt 2025-07-15 19:28:17.000000000 +0200
@@ -11,7 +11,7 @@
message(STATUS "Looking for doxygen")
find_package(Doxygen)
-if(DOXYGEN_FOUND)
+if(DOXYGEN_FOUND AND DOXYGEN_DOT_FOUND)
message(STATUS "Looking for doxygen - found")
configure_file(Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY)
diff -Nru protozero-1.8.0/FUZZING.md protozero-1.8.1/FUZZING.md
--- protozero-1.8.0/FUZZING.md 2025-01-13 10:42:19.000000000 +0100
+++ protozero-1.8.1/FUZZING.md 2025-07-15 19:28:17.000000000 +0200
@@ -18,5 +18,16 @@
See the AFL documentation for more information.
+For increased speed, you can also use the dedicated pbf-fuzzer tool, which skips reading
+data from files or stdin:
+
+ clang++ -O2 -std=c++17 -g -DNDEBUG -Iinclude -fsanitize=address,fuzzer tools/pbf-fuzzer.cpp -o tools/pbf-fuzzer
+ ./tools/pbf-fuzzer
+
+or using AFL++
+
+ afl-clang-fast++ -O2 -std=c++17 -g -DNDEBUG -Iinclude -fsanitize=address,fuzzer tools/pbf-fuzzer.cpp -o tools/pbf-fuzzer
+ afl-fuzz -i testcase_dir -o findings_dir -- tools/pbf-fuzzer
+
This only checkes the reading side of Protozero!
diff -Nru protozero-1.8.0/.github/actions/install-ubuntu/action.yml protozero-1.8.1/.github/actions/install-ubuntu/action.yml
--- protozero-1.8.0/.github/actions/install-ubuntu/action.yml 2025-01-13 10:42:19.000000000 +0100
+++ protozero-1.8.1/.github/actions/install-ubuntu/action.yml 2025-07-15 19:28:17.000000000 +0200
@@ -7,6 +7,8 @@
run: |
sudo apt-get update -qq
sudo apt-get install -yq \
+ doxygen \
+ graphviz \
libprotobuf-dev \
protobuf-compiler
shell: bash
diff -Nru protozero-1.8.0/.github/workflows/ci.yml protozero-1.8.1/.github/workflows/ci.yml
--- protozero-1.8.0/.github/workflows/ci.yml 2025-01-13 10:42:19.000000000 +0100
+++ protozero-1.8.1/.github/workflows/ci.yml 2025-07-15 19:28:17.000000000 +0200
@@ -51,6 +51,7 @@
- image: "debian:bookworm"
c_compiler: clang
cpp_compiler: clang++
+ cpp_version: 17
data_view: std::string_view
- image: "debian:testing"
c_compiler: clang
@@ -136,7 +137,7 @@
CXX: clang++
BUILD_TYPE: ${{ matrix.build_type }}
steps:
- - run: brew install protobuf
+ - run: brew install doxygen graphviz protobuf
- uses: actions/checkout at v4
- uses: ./.github/actions/cmake
- uses: ./.github/actions/build
@@ -149,8 +150,8 @@
fail-fast: false
matrix:
os:
- - windows-2019
- windows-2022
+ - windows-2025
steps:
- run: |
vcpkg install \
diff -Nru protozero-1.8.0/include/protozero/pbf_reader.hpp protozero-1.8.1/include/protozero/pbf_reader.hpp
--- protozero-1.8.0/include/protozero/pbf_reader.hpp 2025-01-13 10:42:19.000000000 +0100
+++ protozero-1.8.1/include/protozero/pbf_reader.hpp 2025-07-15 19:28:17.000000000 +0200
@@ -494,9 +494,9 @@
bool get_bool() {
protozero_assert(tag() != 0 && "call next() before accessing field value");
protozero_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
- const bool result = m_data[0] != 0;
+ const char* value = m_data;
skip_varint(&m_data, m_end);
- return result;
+ return *value != 0;
}
/**
diff -Nru protozero-1.8.0/include/protozero/version.hpp protozero-1.8.1/include/protozero/version.hpp
--- protozero-1.8.0/include/protozero/version.hpp 2025-01-13 10:42:19.000000000 +0100
+++ protozero-1.8.1/include/protozero/version.hpp 2025-07-15 19:28:17.000000000 +0200
@@ -23,12 +23,12 @@
#define PROTOZERO_VERSION_MINOR 8
/// The patch number
-#define PROTOZERO_VERSION_PATCH 0
+#define PROTOZERO_VERSION_PATCH 1
/// The complete version number
#define PROTOZERO_VERSION_CODE (PROTOZERO_VERSION_MAJOR * 10000 + PROTOZERO_VERSION_MINOR * 100 + PROTOZERO_VERSION_PATCH)
/// Version number as string
-#define PROTOZERO_VERSION_STRING "1.8.0"
+#define PROTOZERO_VERSION_STRING "1.8.1"
#endif // PROTOZERO_VERSION_HPP
diff -Nru protozero-1.8.0/test/t/bool/reader_test_cases.cpp protozero-1.8.1/test/t/bool/reader_test_cases.cpp
--- protozero-1.8.0/test/t/bool/reader_test_cases.cpp 2025-01-13 10:42:19.000000000 +0100
+++ protozero-1.8.1/test/t/bool/reader_test_cases.cpp 2025-07-15 19:28:17.000000000 +0200
@@ -139,3 +139,11 @@
}
}
+TEST_CASE("read bool from using pbf_reader: truncated message") {
+ std::vector<char> buffer = { 0x08 };
+
+ protozero::pbf_reader item{buffer.data(), buffer.size()};
+
+ REQUIRE(item.next());
+ REQUIRE_THROWS_AS(item.get_bool(), protozero::end_of_buffer_exception);
+}
diff -Nru protozero-1.8.0/test/unit/test_data_view.cpp protozero-1.8.1/test/unit/test_data_view.cpp
--- protozero-1.8.0/test/unit/test_data_view.cpp 2025-01-13 10:42:19.000000000 +0100
+++ protozero-1.8.1/test/unit/test_data_view.cpp 2025-07-15 19:28:17.000000000 +0200
@@ -53,7 +53,9 @@
const std::string s = std::string(view);
REQUIRE(s == "foobar");
REQUIRE(std::string(view) == "foobar");
+#ifndef PROTOZERO_USE_VIEW
REQUIRE(view.to_string() == "foobar");
+#endif
}
#ifndef PROTOZERO_USE_VIEW
@@ -69,14 +71,14 @@
protozero::data_view view1{"foo"};
protozero::data_view view2{"bar"};
- REQUIRE(view1.to_string() == "foo");
- REQUIRE(view2.to_string() == "bar");
+ REQUIRE(std::string(view1) == "foo");
+ REQUIRE(std::string(view2) == "bar");
using std::swap;
swap(view1, view2);
- REQUIRE(view2.to_string() == "foo");
- REQUIRE(view1.to_string() == "bar");
+ REQUIRE(std::string(view2) == "foo");
+ REQUIRE(std::string(view1) == "bar");
}
TEST_CASE("comparing data_views") {
diff -Nru protozero-1.8.0/tools/pbf-decoder.cpp protozero-1.8.1/tools/pbf-decoder.cpp
--- protozero-1.8.0/tools/pbf-decoder.cpp 2025-01-13 10:42:19.000000000 +0100
+++ protozero-1.8.1/tools/pbf-decoder.cpp 2025-07-15 19:28:17.000000000 +0200
@@ -32,6 +32,7 @@
#include <sstream>
#include <stdexcept>
#include <string>
+#include <vector>
namespace {
@@ -194,15 +195,15 @@
<< " -o, --offset=OFFSET Start reading from OFFSET bytes\n";
}
-std::string read_from_file(const char* filename) {
+std::vector<char> read_from_file(const char* filename) {
const std::ifstream file{filename, std::ios::binary};
- return std::string{std::istreambuf_iterator<char>(file.rdbuf()),
- std::istreambuf_iterator<char>()};
+ return std::vector<char>{std::istreambuf_iterator<char>(file.rdbuf()),
+ std::istreambuf_iterator<char>()};
}
-std::string read_from_stdin() {
- return std::string{std::istreambuf_iterator<char>(std::cin.rdbuf()),
- std::istreambuf_iterator<char>()};
+std::vector<char> read_from_stdin() {
+ return std::vector<char>{std::istreambuf_iterator<char>(std::cin.rdbuf()),
+ std::istreambuf_iterator<char>()};
}
} // anonymous namespace
@@ -251,15 +252,15 @@
const std::string filename{argv[optind]};
try {
- std::string buffer{filename == "-" ? read_from_stdin() :
- read_from_file(argv[optind])};
+ std::vector<char> buffer{filename == "-" ? read_from_stdin() :
+ read_from_file(argv[optind])};
if (offset > buffer.size()) {
throw std::runtime_error{"offset is larger than file size"};
}
if (offset > 0) {
- buffer.erase(0, offset);
+ buffer.erase(buffer.begin(), buffer.begin() + offset);
}
if (length < buffer.size()) {
diff -Nru protozero-1.8.0/tools/pbf-fuzzer.cpp protozero-1.8.1/tools/pbf-fuzzer.cpp
--- protozero-1.8.0/tools/pbf-fuzzer.cpp 1970-01-01 01:00:00.000000000 +0100
+++ protozero-1.8.1/tools/pbf-fuzzer.cpp 2025-07-15 19:28:17.000000000 +0200
@@ -0,0 +1,85 @@
+#include <protozero/pbf_reader.hpp>
+
+// From Google Benchmark library.
+// See https://github.com/google/benchmark/blob/main/LICENSE
+template <class Tp>
+inline __attribute__((always_inline)) void DoNotOptimize(Tp const& value) {
+ asm volatile("" : : "r,m"(value) : "memory");
+}
+
+template <typename T>
+int read_packed(protozero::iterator_range<T> range) {
+ try {
+ for (const auto& item : range) {
+ DoNotOptimize(item);
+ }
+ } catch (const protozero::exception&) {
+ // no-op. This is probably not a packed field of that type.
+ }
+ return 0;
+}
+
+template <typename Fn>
+void try_field(const protozero::pbf_reader& reader, Fn&& fn) {
+ try {
+ DoNotOptimize(fn(reader));
+ } catch (const protozero::exception&) {
+ // no-op. This is probably not a field of that type.
+ }
+}
+
+int try_message(protozero::pbf_reader reader) {
+ try {
+ while (reader.next()) {
+ if (reader.has_wire_type(protozero::pbf_wire_type::varint)) {
+ // Try to decode this field as any of the types that can be encoded as varint.
+ try_field(reader, [](protozero::pbf_reader r) { return r.get_bool(); });
+ try_field(reader, [](protozero::pbf_reader r) { return r.get_enum(); });
+ try_field(reader, [](protozero::pbf_reader r) { return r.get_int32(); });
+ try_field(reader, [](protozero::pbf_reader r) { return r.get_sint32(); });
+ try_field(reader, [](protozero::pbf_reader r) { return r.get_uint32(); });
+ try_field(reader, [](protozero::pbf_reader r) { return r.get_int64(); });
+ try_field(reader, [](protozero::pbf_reader r) { return r.get_sint64(); });
+ try_field(reader, [](protozero::pbf_reader r) { return r.get_uint64(); });
+ } else if (reader.has_wire_type(protozero::pbf_wire_type::length_delimited)) {
+ // Try to decode this field as any of the types that can be encoded as length-delimited.
+ try_field(reader, [](protozero::pbf_reader r) { return try_message(r.get_message()); });
+ try_field(reader, [](protozero::pbf_reader r) { return read_packed(r.get_packed_bool()); });
+ try_field(reader, [](protozero::pbf_reader r) { return read_packed(r.get_packed_double()); });
+ try_field(reader, [](protozero::pbf_reader r) { return read_packed(r.get_packed_enum()); });
+ try_field(reader, [](protozero::pbf_reader r) { return read_packed(r.get_packed_fixed32()); });
+ try_field(reader, [](protozero::pbf_reader r) { return read_packed(r.get_packed_fixed64()); });
+ try_field(reader, [](protozero::pbf_reader r) { return read_packed(r.get_packed_float()); });
+ try_field(reader, [](protozero::pbf_reader r) { return read_packed(r.get_packed_int32()); });
+ try_field(reader, [](protozero::pbf_reader r) { return read_packed(r.get_packed_int64()); });
+ try_field(reader, [](protozero::pbf_reader r) { return read_packed(r.get_packed_sfixed32()); });
+ try_field(reader, [](protozero::pbf_reader r) { return read_packed(r.get_packed_sfixed64()); });
+ try_field(reader, [](protozero::pbf_reader r) { return read_packed(r.get_packed_sint32()); });
+ try_field(reader, [](protozero::pbf_reader r) { return read_packed(r.get_packed_sint64()); });
+ try_field(reader, [](protozero::pbf_reader r) { return read_packed(r.get_packed_uint32()); });
+ try_field(reader, [](protozero::pbf_reader r) { return read_packed(r.get_packed_uint64()); });
+ } else if (reader.has_wire_type(protozero::pbf_wire_type::fixed64)) {
+ // Try to decode this field as any of the types that can be encoded as fixed64.
+ try_field(reader, [](protozero::pbf_reader r) { return r.get_double(); });
+ try_field(reader, [](protozero::pbf_reader r) { return r.get_fixed64(); });
+ try_field(reader, [](protozero::pbf_reader r) { return r.get_sfixed64(); });
+ } else if (reader.has_wire_type(protozero::pbf_wire_type::fixed32)) {
+ // Try to decode this field as any of the types that can be encoded as fixed32.
+ try_field(reader, [](protozero::pbf_reader r) { return r.get_float(); });
+ try_field(reader, [](protozero::pbf_reader r) { return r.get_fixed32(); });
+ try_field(reader, [](protozero::pbf_reader r) { return r.get_sfixed32(); });
+ }
+
+ reader.skip();
+ }
+ } catch (const protozero::exception&) {
+ // no-op. This is probably not a valid message.
+ }
+
+ return 0;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ try_message(protozero::pbf_reader{reinterpret_cast<const char*>(data), size});
+ return 0;
+}
More information about the Pkg-grass-devel
mailing list