Skip to content

Commit 1b8d4a6

Browse files
committed
Merge #194: mpgen: Work around c++20 / capnproto 0.8 incompatibility
dc3ba22 cmake, doc: Add check for CVE-2022-46149 (Ryan Ofsky) 8ceeaa6 ci: Add olddeps job to test old dependencies versions (Ryan Ofsky) c4cb758 mpgen: Work around c++20 / capnproto 0.8 incompatibility (Ryan Ofsky) Pull request description: Fix ubuntu 22.04 compatibility issue reported by fanquake in bitcoin/bitcoin#33176 and add CI job to make sure libmultiprocess stays compatible with old versions of Cap'n Proto. Changes are described in more detail in commit messages. ACKs for top commit: Sjors: utACK dc3ba22 TheCharlatan: ACK dc3ba22 Tree-SHA512: 7c2301cc3f684bfaf8fbc2f02254c1bb28820be5bf0812a57a692428a37cf01e67bd521a58898c90a1e0d84e5e9a8c7c3e14ae05db230950c29369800c9e3e2d
2 parents f1fad39 + dc3ba22 commit 1b8d4a6

File tree

8 files changed

+92
-9
lines changed

8 files changed

+92
-9
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ jobs:
4040
strategy:
4141
fail-fast: false
4242
matrix:
43-
config: [default, llvm, gnu32, sanitize]
43+
config: [default, llvm, gnu32, sanitize, olddeps]
4444

4545
name: build • ${{ matrix.config }}
4646

CMakeLists.txt

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,29 @@ endif()
1212

1313
include("cmake/compat_find.cmake")
1414

15-
find_package(CapnProto 0.7.0 REQUIRED)
1615
find_package(Threads REQUIRED)
16+
find_package(CapnProto 0.7 REQUIRED)
17+
18+
# Check for list-of-pointers memory access bug from Nov 2022
19+
# https://nvd.nist.gov/vuln/detail/CVE-2022-46149
20+
# https://github.com/advisories/GHSA-qqff-4vw4-f6hx
21+
# https://github.com/capnproto/capnproto/security/advisories/GHSA-qqff-4vw4-f6hx
22+
# https://github.com/capnproto/capnproto/blob/master/security-advisories/2022-11-30-0-pointer-list-bounds.md
23+
# https://capnproto.org/news/2022-11-30-CVE-2022-46149-security-advisory.html
24+
# https://dwrensha.github.io/capnproto-rust/2022/11/30/out_of_bounds_memory_access_bug.html
25+
if(CapnProto_VERSION STREQUAL "0.7.0"
26+
OR CapnProto_VERSION STREQUAL "0.8.0"
27+
OR CapnProto_VERSION STREQUAL "0.9.0"
28+
OR CapnProto_VERSION STREQUAL "0.9.1"
29+
OR CapnProto_VERSION STREQUAL "0.10.0"
30+
OR CapnProto_VERSION STREQUAL "0.10.1"
31+
OR CapnProto_VERSION STREQUAL "0.10.2")
32+
message(FATAL_ERROR
33+
"Cap'n Proto ${CapnProto_VERSION} is affected by CVE-2022-46149.\n"
34+
"Please install an updated package.\n"
35+
"Details: https://github.com/advisories/GHSA-qqff-4vw4-f6hx
36+
")
37+
endif()
1738

1839
set(MPGEN_EXECUTABLE "" CACHE FILEPATH "If specified, should be full path to an external mpgen binary to use rather than the one built internally.")
1940

ci/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ CI_CONFIG=ci/configs/default.bash ci/scripts/run.sh
2020
CI_CONFIG=ci/configs/llvm.bash ci/scripts/run.sh
2121
CI_CONFIG=ci/configs/gnu32.bash ci/scripts/run.sh
2222
CI_CONFIG=ci/configs/sanitize.bash ci/scripts/run.sh
23+
CI_CONFIG=ci/configs/olddeps.bash ci/scripts/run.sh
2324
```
2425

2526
By default CI jobs will reuse their build directories. `CI_CLEAN=1` can be specified to delete them before running instead.

ci/configs/olddeps.bash

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
CI_DESC="CI job using old Cap'n Proto version"
2+
CI_DIR=build-olddeps
3+
export CXXFLAGS="-Werror -Wall -Wextra -Wpedantic -Wno-unused-parameter -Wno-error=array-bounds"
4+
NIX_ARGS=(--argstr capnprotoVersion "0.7.1")
5+
BUILD_ARGS=(-k)

ci/patches/spaceship.patch

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
commit e3da7da967b94f373c29a198ce45f30fb9f0e517
2+
Author: Ed Catmur <[email protected]>
3+
Date: Tue Jan 31 16:27:04 2023 +0000
4+
5+
Remove operator!= synthesized by spaceship
6+
7+
An operator!= suppresses the reversed equality comparison candidate generation.
8+
9+
This is visible in clang 16 (rc0 just released) and in gcc trunk (so probably gcc 13).
10+
11+
diff --git a/c++/src/kj/string.h b/c++/src/kj/string.h
12+
index 193442aa..17835892 100644
13+
--- a/c++/src/kj/string.h
14+
+++ b/c++/src/kj/string.h
15+
@@ -122,10 +122,14 @@ public:
16+
inline constexpr const char* end() const { return content.end() - 1; }
17+
18+
inline constexpr bool operator==(decltype(nullptr)) const { return content.size() <= 1; }
19+
+#if !__cpp_impl_three_way_comparison
20+
inline constexpr bool operator!=(decltype(nullptr)) const { return content.size() > 1; }
21+
+#endif
22+
23+
inline bool operator==(const StringPtr& other) const;
24+
+#if !__cpp_impl_three_way_comparison
25+
inline bool operator!=(const StringPtr& other) const { return !(*this == other); }
26+
+#endif
27+
inline bool operator< (const StringPtr& other) const;
28+
inline bool operator> (const StringPtr& other) const { return other < *this; }
29+
inline bool operator<=(const StringPtr& other) const { return !(other < *this); }

doc/install.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# libmultiprocess Installation
22

3-
Installation currently requires Cap'n Proto:
3+
Installation currently requires Cap'n Proto 0.7 or higher:
44

55
```sh
66
apt install libcapnp-dev capnproto

shell.nix

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,39 @@
22
, crossPkgs ? import <nixpkgs> {}
33
, enableLibcxx ? false # Whether to use libc++ toolchain and libraries instead of libstdc++
44
, minimal ? false # Whether to create minimal shell without extra tools (faster when cross compiling)
5+
, capnprotoVersion ? null
56
}:
67

78
let
89
lib = pkgs.lib;
910
llvm = crossPkgs.llvmPackages_20;
10-
capnproto = crossPkgs.capnproto.override (lib.optionalAttrs enableLibcxx { clangStdenv = llvm.libcxxStdenv; });
11+
capnprotoHashes = {
12+
"0.7.0" = "sha256-Y/7dUOQPDHjniuKNRw3j8dG1NI9f/aRWpf8V0WzV9k8=";
13+
"0.7.1" = "sha256-3cBpVmpvCXyqPUXDp12vCFCk32ZXWpkdOliNH37UwWE=";
14+
"0.8.0" = "sha256-rfiqN83begjJ9eYjtr21/tk1GJBjmeVfa3C3dZBJ93w=";
15+
"0.8.1" = "sha256-OZqNVYdyszro5rIe+w6YN00g6y8U/1b8dKYc214q/2o=";
16+
"0.9.0" = "sha256-yhbDcWUe6jp5PbIXzn5EoKabXiWN8lnS08hyfxUgEQ0=";
17+
"0.9.2" = "sha256-BspWOPZcP5nCTvmsDE62Zutox+aY5pw42d6hpH3v4cM=";
18+
"0.10.0" = "sha256-++F4l54OMTDnJ+FO3kV/Y/VLobKVRk461dopanuU3IQ=";
19+
"0.10.4" = "sha256-45sxnVyyYIw9i3sbFZ1naBMoUzkpP21WarzR5crg4X8=";
20+
"1.0.0" = "sha256-NLTFJdeOzqhk4ATvkc17Sh6g/junzqYBBEoXYGH/czo=";
21+
"1.0.2" = "sha256-LVdkqVBTeh8JZ1McdVNtRcnFVwEJRNjt0JV2l7RkuO8=";
22+
"1.1.0" = "sha256-gxkko7LFyJNlxpTS+CWOd/p9x/778/kNIXfpDGiKM2A=";
23+
"1.2.0" = "sha256-aDcn4bLZGq8915/NPPQsN5Jv8FRWd8cAspkG3078psc=";
24+
};
25+
capnprotoBase = if capnprotoVersion == null then crossPkgs.capnproto else crossPkgs.capnproto.overrideAttrs (old: {
26+
version = capnprotoVersion;
27+
src = crossPkgs.fetchFromGitHub {
28+
owner = "capnproto";
29+
repo = "capnproto";
30+
rev = "v${capnprotoVersion}";
31+
hash = lib.attrByPath [capnprotoVersion] "" capnprotoHashes;
32+
};
33+
patches = lib.optionals (lib.versionAtLeast capnprotoVersion "0.9.0" && lib.versionOlder capnprotoVersion "0.10.4") [ ./ci/patches/spaceship.patch ];
34+
} // (lib.optionalAttrs (lib.versionOlder capnprotoVersion "0.10") {
35+
env = { }; # Drop -std=c++20 flag forced by nixpkgs
36+
}));
37+
capnproto = capnprotoBase.override (lib.optionalAttrs enableLibcxx { clangStdenv = llvm.libcxxStdenv; });
1138
clang = if enableLibcxx then llvm.libcxxClang else llvm.clang;
1239
clang-tools = llvm.clang-tools.override { inherit enableLibcxx; };
1340
in crossPkgs.mkShell {

src/mp/gen.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ static void Generate(kj::StringPtr src_prefix,
146146
const std::vector<kj::Own<const kj::ReadableDirectory>>& import_dirs)
147147
{
148148
std::string output_path;
149-
if (src_prefix == ".") {
149+
if (src_prefix == kj::StringPtr{"."}) {
150150
output_path = src_file;
151151
} else if (!src_file.startsWith(src_prefix) || src_file.size() <= src_prefix.size() ||
152152
src_file[src_prefix.size()] != '/') {
@@ -156,7 +156,7 @@ static void Generate(kj::StringPtr src_prefix,
156156
}
157157

158158
std::string include_path;
159-
if (include_prefix == ".") {
159+
if (include_prefix == kj::StringPtr{"."}) {
160160
include_path = src_file;
161161
} else if (!src_file.startsWith(include_prefix) || src_file.size() <= include_prefix.size() ||
162162
src_file[include_prefix.size()] != '/') {
@@ -425,8 +425,8 @@ static void Generate(kj::StringPtr src_prefix,
425425

426426
const std::string method_prefix = Format() << message_namespace << "::" << method_interface.getShortDisplayName()
427427
<< "::" << Cap(method_name);
428-
const bool is_construct = method_name == "construct";
429-
const bool is_destroy = method_name == "destroy";
428+
const bool is_construct = method_name == kj::StringPtr{"construct"};
429+
const bool is_destroy = method_name == kj::StringPtr{"destroy"};
430430

431431
struct Field
432432
{
@@ -465,7 +465,7 @@ static void Generate(kj::StringPtr src_prefix,
465465
field.result_is_set = true;
466466
}
467467

468-
if (!param && field_name == "result") {
468+
if (!param && field_name == kj::StringPtr{"result"}) {
469469
field.retval = true;
470470
has_result = true;
471471
}

0 commit comments

Comments
 (0)