Fix alignment issues when running under UBSan [crashpad/crashpad : main]

12 views
Skip to first unread message

David Benjamin (Gerrit)

unread,
Sep 8, 2024, 6:12:59 PM9/8/24
to Mark Mentovai, Crashpad LUCI CQ, crashp...@chromium.org
Attention needed from Mark Mentovai

David Benjamin added 1 comment

Patchset-level comments
File-level comment, Patchset 2 (Latest):
David Benjamin . resolved

CQ is kinda red, but judging by https://ci.chromium.org/p/crashpad/g/main/console I think that's pre-existing?

Open in Gerrit

Related details

Attention is currently required from:
  • Mark Mentovai
Submit Requirements:
  • requirement is not satisfiedCode-Review
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: crashpad/crashpad
Gerrit-Branch: main
Gerrit-Change-Id: If2e2cdc4528a0be7b42cc877a93f8672bd4818f5
Gerrit-Change-Number: 5843750
Gerrit-PatchSet: 2
Gerrit-Owner: David Benjamin <davi...@chromium.org>
Gerrit-Reviewer: David Benjamin <davi...@chromium.org>
Gerrit-Reviewer: Mark Mentovai <ma...@chromium.org>
Gerrit-Attention: Mark Mentovai <ma...@chromium.org>
Gerrit-Comment-Date: Sun, 08 Sep 2024 22:12:57 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
unsatisfied_requirement
open
diffy

Mark Mentovai (Gerrit)

unread,
Sep 10, 2024, 1:09:25 PM9/10/24
to David Benjamin, Crashpad LUCI CQ, crashp...@chromium.org
Attention needed from David Benjamin

Mark Mentovai added 8 comments

File client/simulate_crash_mac_test.cc
Line 133, Patchset 2 (Latest): // `old_state` is not sufficiently aligned, so make a copy first.
Mark Mentovai . unresolved

Why is this only needed for the test?

File util/mach/exc_server_variants.cc
Line 152, Patchset 2 (Latest): using ExceptionCodes = decltype(std::declval<Request>().code);
Mark Mentovai . unresolved

Not used beyond this class, should be private (although it means you’ll be private-public-private, but I think that’s OK).

Line 154, Patchset 2 (Latest): static constexpr size_t kMaxCodes = std::extent_v<ExceptionCodes>;
Mark Mentovai . unresolved

Should be private too.

Line 156, Patchset 2 (Latest): AlignedExceptionCodes(const Request& request) : size_(request.codeCnt) {
Mark Mentovai . unresolved

The constructor should be `explicit`.

Line 156, Patchset 2 (Latest): AlignedExceptionCodes(const Request& request) : size_(request.codeCnt) {
Mark Mentovai . unresolved

Since all callers hold a `Request*`, why not accept a `const Request*` here, and avoid the need for callers to use the awkward `*` dereference?

Line 157, Patchset 2 (Latest): CHECK(size_ <= kMaxCodes);
Mark Mentovai . unresolved

`CHECK_LE`

Line 167, Patchset 2 (Latest): ExceptionCode codes_[kMaxCodes] = {};
mach_msg_type_number_t size_ = 0;
Mark Mentovai . unresolved

You don’t need initializers for either of these.

Line 323, Patchset 2 (Latest): codes.data(),
codes.size(),
Mark Mentovai . unresolved

Alternatively, we could redefine these interfaces to pass a `const std::vector<mach_exception_data_type_t>&`.

Open in Gerrit

Related details

Attention is currently required from:
  • David Benjamin
Submit Requirements:
  • requirement is not satisfiedCode-Review
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: crashpad/crashpad
Gerrit-Branch: main
Gerrit-Change-Id: If2e2cdc4528a0be7b42cc877a93f8672bd4818f5
Gerrit-Change-Number: 5843750
Gerrit-PatchSet: 2
Gerrit-Owner: David Benjamin <davi...@chromium.org>
Gerrit-Reviewer: David Benjamin <davi...@chromium.org>
Gerrit-Reviewer: Mark Mentovai <ma...@chromium.org>
Gerrit-Attention: David Benjamin <davi...@chromium.org>
Gerrit-Comment-Date: Tue, 10 Sep 2024 17:09:22 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
unsatisfied_requirement
open
diffy

David Benjamin (Gerrit)

unread,
May 29, 2026, 11:27:17 AM (8 days ago) May 29
to Mark Mentovai, crashpa...@luci-project-accounts.iam.gserviceaccount.com, crashp...@chromium.org
Attention needed from Mark Mentovai

David Benjamin voted and added 2 comments

Votes added by David Benjamin

Commit-Queue+1

2 comments

Patchset-level comments
File-level comment, Patchset 3:
David Benjamin . resolved

Bah, sorry, it seems something was out of sync between my two repos and this doesn't build. Removing you from the attention set while I figure out what's going on.

David Benjamin

Okay, hopefully that's OK now.

File util/mach/exc_server_variants.cc
Line 580, Patchset 4 (Latest): codes.size()),
David Benjamin . unresolved

I believe this is what the old code was doing, but I'm pretty sure it's wrong. Thoughts?

Open in Gerrit

Related details

Attention is currently required from:
  • Mark Mentovai
Submit Requirements:
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: crashpad/crashpad
Gerrit-Branch: main
Gerrit-Change-Id: If2e2cdc4528a0be7b42cc877a93f8672bd4818f5
Gerrit-Change-Number: 5843750
Gerrit-PatchSet: 4
Gerrit-Owner: David Benjamin <davi...@chromium.org>
Gerrit-Reviewer: David Benjamin <davi...@chromium.org>
Gerrit-Reviewer: Mark Mentovai <ma...@chromium.org>
Gerrit-Attention: Mark Mentovai <ma...@chromium.org>
Gerrit-Comment-Date: Wed, 27 May 2026 23:37:30 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: Yes
Comment-In-Reply-To: David Benjamin <davi...@chromium.org>
unsatisfied_requirement
open
diffy

David Benjamin (Gerrit)

unread,
May 29, 2026, 11:27:17 AM (8 days ago) May 29
to Mark Mentovai, crashpa...@luci-project-accounts.iam.gserviceaccount.com, crashp...@chromium.org
Attention needed from David Benjamin

David Benjamin added 1 comment

Patchset-level comments
File-level comment, Patchset 3 (Latest):
David Benjamin . unresolved

Bah, sorry, it seems something was out of sync between my two repos and this doesn't build. Removing you from the attention set while I figure out what's going on.

Open in Gerrit

Related details

Attention is currently required from:
  • David Benjamin
Submit Requirements:
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: crashpad/crashpad
Gerrit-Branch: main
Gerrit-Change-Id: If2e2cdc4528a0be7b42cc877a93f8672bd4818f5
Gerrit-Change-Number: 5843750
Gerrit-PatchSet: 3
Gerrit-Owner: David Benjamin <davi...@chromium.org>
Gerrit-Reviewer: David Benjamin <davi...@chromium.org>
Gerrit-Reviewer: Mark Mentovai <ma...@chromium.org>
Gerrit-Attention: David Benjamin <davi...@chromium.org>
Gerrit-Comment-Date: Wed, 27 May 2026 23:28:57 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
unsatisfied_requirement
open
diffy

David Benjamin (Gerrit)

unread,
May 29, 2026, 11:27:17 AM (8 days ago) May 29
to Mark Mentovai, crashpa...@luci-project-accounts.iam.gserviceaccount.com, crashp...@chromium.org
Attention needed from Mark Mentovai

David Benjamin voted and added 11 comments

Votes added by David Benjamin

Commit-Queue+1

11 comments

Patchset-level comments
David Benjamin . resolved

Whoops, I lost track of this CL and only got back to it now. You probably want to review it with fresh eyes.

File client/simulate_crash_mac_test.cc
Line 133, Patchset 2: // `old_state` is not sufficiently aligned, so make a copy first.
Mark Mentovai . resolved

Why is this only needed for the test?

David Benjamin

Apparently it isn't, but only gwp_asan tests flagged this. Fixed in both.

File util/mach/exc_server_variants.cc
Line 152, Patchset 2: using ExceptionCodes = decltype(std::declval<Request>().code);
Mark Mentovai . resolved

Not used beyond this class, should be private (although it means you’ll be private-public-private, but I think that’s OK).

David Benjamin

Done

Line 154, Patchset 2: static constexpr size_t kMaxCodes = std::extent_v<ExceptionCodes>;
Mark Mentovai . resolved

Should be private too.

David Benjamin

Done

Line 156, Patchset 2: AlignedExceptionCodes(const Request& request) : size_(request.codeCnt) {
Mark Mentovai . resolved

The constructor should be `explicit`.

David Benjamin

Done

Line 156, Patchset 2: AlignedExceptionCodes(const Request& request) : size_(request.codeCnt) {
Mark Mentovai . resolved

Since all callers hold a `Request*`, why not accept a `const Request*` here, and avoid the need for callers to use the awkward `*` dereference?

David Benjamin

Done

Line 157, Patchset 2: CHECK(size_ <= kMaxCodes);
Mark Mentovai . resolved

`CHECK_LE`

David Benjamin

Done

Line 167, Patchset 2: ExceptionCode codes_[kMaxCodes] = {};
mach_msg_type_number_t size_ = 0;
Mark Mentovai . resolved

You don’t need initializers for either of these.

David Benjamin

Done

Line 323, Patchset 2: codes.data(),
codes.size(),
Mark Mentovai . resolved

Alternatively, we could redefine these interfaces to pass a `const std::vector<mach_exception_data_type_t>&`.

David Benjamin

Done, but with spans. Also made the funny class just be a helper function that returns a `std::vector`.

David Benjamin . unresolved

I believe this is what the old code was doing, but I'm pretty sure it's wrong. Thoughts?

Line 970, Patchset 3 (Latest): // span.
David Benjamin . resolved

Happy to do this in this CL if you'd like, but that would spread into many more files.

Open in Gerrit

Related details

Attention is currently required from:
  • Mark Mentovai
Submit Requirements:
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: crashpad/crashpad
Gerrit-Branch: main
Gerrit-Change-Id: If2e2cdc4528a0be7b42cc877a93f8672bd4818f5
Gerrit-Change-Number: 5843750
Gerrit-PatchSet: 3
Gerrit-Owner: David Benjamin <davi...@chromium.org>
Gerrit-Reviewer: David Benjamin <davi...@chromium.org>
Gerrit-Reviewer: Mark Mentovai <ma...@chromium.org>
Gerrit-Attention: Mark Mentovai <ma...@chromium.org>
Gerrit-Comment-Date: Wed, 27 May 2026 23:18:57 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: Yes
Comment-In-Reply-To: Mark Mentovai <ma...@chromium.org>
unsatisfied_requirement
open
diffy

Mark Mentovai (Gerrit)

unread,
May 29, 2026, 11:49:09 AM (8 days ago) May 29
to David Benjamin, Justin Cohen, crashpa...@luci-project-accounts.iam.gserviceaccount.com, crashp...@chromium.org
Attention needed from David Benjamin and Justin Cohen

Mark Mentovai added 9 comments

File client/length_delimited_ring_buffer.h
Line 340, Patchset 4 (Latest): Header other_header;
memcpy(&other_header, buffer, sizeof(other_header));
if (other_header.magic != kMagic || other_header.version != kVersion) {
return false;
}
header.data_range = other_header.data_range;
Mark Mentovai . unresolved

Do we need `other_header` or can we just do this all in-place with a `memcpy` into the `header` that we already have?

If it’s important for `header` to be untouched if `magic` or `verson` are wrong, then I guess `other_header` is necessary.

Still, I think I’d have written this with `bit_cast`s and the single `header` instead of holding a `memcpy` directly.

File client/simulate_crash_mac_test.cc
Line 146, Patchset 4 (Latest): auto state =
CopyUnalignedState<x86_thread_state>(old_state, old_state_count);
switch (state.tsh.flavor) {
Mark Mentovai . unresolved

1. No good reason to use `auto` here. Please put the proper type back.

2. Can these be `bit_cast`s too? That’s the standard way we have to handle this concern. `CopyUnalignedState` just seems to reinvent a specialized version of that.

File snapshot/mac/cpu_context_mac.cc
Line 26, Patchset 4 (Latest):namespace {
// The thread state passed to these functions is not necessarily sufficiently
// aligned for the destination struct. This helper copies it out before
// accessing the fields.
template <typename State>
State CopyUnalignedState(ConstThreadState state,
mach_msg_type_number_t state_count) {
CHECK_LE(sizeof(State), state_count * sizeof(*state));
State ret;
memcpy(&ret, state, sizeof(ret));
return ret;
}
} // namespace
Mark Mentovai . unresolved

If you find that you do need to introduce a helper, don’t do it once in each file that you need. Do it once in a more central location (util/mac?) and access that from where both client and snapshot.

Line 141, Patchset 4 (Latest): const auto x86_thread_state =
CopyUnalignedState<x86_thread_state_t>(state, state_count);
if (x86_thread_state.tsh.flavor != x86_THREAD_STATE32) {
Mark Mentovai . unresolved

Same.

File util/mach/exc_server_variants.cc
Line 204, Patchset 4 (Latest):auto CopyUnalignedExceptionCodes(const Request* request) {
Mark Mentovai . unresolved

Too much `auto`. These types aren’t so complex that you need to fall back on that. I don’t think you should have any `auto` in this change at all.

Line 207, Patchset 4 (Latest): std::vector<ExceptionCode> ret;
Mark Mentovai . unresolved

If we’re in full control of all of the code in here, this is the only place that what underlies the `span`s are ever made, and (per this line) we only ever make `vector`s, then why wouldn’t we just pass `vector&`s around instead of the `span`s?

Crashpad code doesn’t really use `span`. I see one use of it total right now, and it can probably be removed, which might cut down on Crashpad’s size.

Line 198, Patchset 4 (Latest):// When using `MachExcTraits`, `ExceptionCode` is a
// `mach_exception_data_type_t`, which is `int64_t`. Many of the request structs
// use `pack(4)`, so the `code` array may not be sufficiently aligned. This
// trips UBSan when taking a pointer to array. This utility function makes an
// aligned copy first.
template <typename Request>
auto CopyUnalignedExceptionCodes(const Request* request) {
using ExceptionCode =
std::remove_extent_t<decltype(std::declval<Request>().code)>;
std::vector<ExceptionCode> ret;
ret.reserve(request->codeCnt);
for (mach_msg_type_number_t i = 0; i < request->codeCnt; i++) {
// `request->code[i]` cannot be passed directly to `push_back`. `push_back`
// takes its input as a reference, which is enough to construct an unaligned
// pointer.
ExceptionCode code = request->code[i];
ret.push_back(code);
}
return ret;
}
Mark Mentovai . unresolved

Same: is there a way to use `bit_cast` here? (Maybe the array makes that trickier.)

Line 243, Patchset 4 (Latest): base::span<const typename Traits::ExceptionCode> codes,
Mark Mentovai . unresolved

I think that the reason that I didn’t do this initially was to allow for the possibility that `code` might be `nullptr`, and to not take a stance on that but to allow the implementer of this interface to decide how to handle it.

That shouldn’t happen in practice, but we’re not in total control of caller behavior. How do you handle that here? (Looks like you crash in `CopyUnalignedExceptionCodes`.)

Line 682, Patchset 3: codes.size()),
David Benjamin . unresolved

I believe this is what the old code was doing, but I'm pretty sure it's wrong. Thoughts?

Mark Mentovai

I believe this is what the old code was doing, but I'm pretty sure it's wrong. Thoughts?

+justincohen

Open in Gerrit

Related details

Attention is currently required from:
  • David Benjamin
  • Justin Cohen
Submit Requirements:
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: crashpad/crashpad
Gerrit-Branch: main
Gerrit-Change-Id: If2e2cdc4528a0be7b42cc877a93f8672bd4818f5
Gerrit-Change-Number: 5843750
Gerrit-PatchSet: 4
Gerrit-Owner: David Benjamin <davi...@chromium.org>
Gerrit-Reviewer: David Benjamin <davi...@chromium.org>
Gerrit-Reviewer: Justin Cohen <justi...@google.com>
Gerrit-Attention: Justin Cohen <justi...@google.com>
Gerrit-Attention: David Benjamin <davi...@chromium.org>
Gerrit-Comment-Date: Fri, 29 May 2026 15:49:06 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: David Benjamin <davi...@chromium.org>
unsatisfied_requirement
open
diffy

Mark Mentovai (Gerrit)

unread,
May 29, 2026, 11:50:23 AM (8 days ago) May 29
to David Benjamin, Justin Cohen, crashpa...@luci-project-accounts.iam.gserviceaccount.com, crashp...@chromium.org
Attention needed from David Benjamin and Justin Cohen

Mark Mentovai added 1 comment

File util/mach/exc_server_variants.cc
Line 323, Patchset 2: codes.data(),
codes.size(),
Mark Mentovai . resolved

Alternatively, we could redefine these interfaces to pass a `const std::vector<mach_exception_data_type_t>&`.

David Benjamin

Done, but with spans. Also made the funny class just be a helper function that returns a `std::vector`.

Mark Mentovai

Done, but with spans. Also made the funny class just be a helper function that returns a `std::vector`.

(look, 20+-month-ago me agreed!)

Gerrit-Comment-Date: Fri, 29 May 2026 15:50:21 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Mark Mentovai <ma...@chromium.org>
Comment-In-Reply-To: David Benjamin <davi...@chromium.org>
unsatisfied_requirement
open
diffy
Reply all
Reply to author
Forward
0 new messages