Skip to content

Commit

Permalink
Fix unaligned map key access
Browse files Browse the repository at this point in the history
If we have a map with key type [string[9], int64], then the int64 should
be treated as an unaligned access.

Previously the alignment calculations worked off the length of the
string value, not the maximum size allocated for the string key.

Example:
  @mapa["ccccdddd", 0] = 1;
  @mapa["aaaabbb", 0] = 1;

The string key's size is taken from the maximum string length, which is
9 bytes. Fields after this key should be considered unaligned.

The second line contains a string of 8 bytes. Padding was not taken
into account and the following key(s) were incorrectly treated as
aligned.
  • Loading branch information
ajor authored and viktormalik committed Jul 8, 2024
1 parent c8b4cd2 commit af32e6b
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 2 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ and this project adheres to
#### Fixed
- Fix segfault for multi-tracepoint probes
- [#3274](https://github.com/bpftrace/bpftrace/pull/3274)
- Fix verifier error from misaligned stack access when using strings as map keys
- [#3294](https://github.com/bpftrace/bpftrace/issues/3294)
#### Security
#### Docs
- Remove mention of unsupported character literals
Expand Down
4 changes: 2 additions & 2 deletions src/ast/passes/codegen_llvm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2844,13 +2844,13 @@ AllocaInst *CodegenLLVM::getMultiMapKey(Map &map,
if (expr->type.IsStringTy() && expr->type.GetSize() < map_key_size)
b_.CreateMemsetBPF(offset_val, b_.getInt8(0), map_key_size);
b_.CREATE_MEMCPY(offset_val, expr_, expr->type.GetSize(), 1);
if ((expr->type.GetSize() % 8) != 0)
if ((map_key_size % 8) != 0)
aligned = false;
} else {
if (expr->type.IsArrayTy() || expr->type.IsRecordTy()) {
// Read the array/struct into the key
b_.CreateProbeRead(ctx_, offset_val, expr->type, expr_, expr->loc);
if ((expr->type.GetSize() % 8) != 0)
if ((map_key_size % 8) != 0)
aligned = false;
} else {
// promote map key to 64-bit:
Expand Down
5 changes: 5 additions & 0 deletions tests/runtime/regression
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,8 @@ PROG kfunc:__module_get { print(args.module->trace_events[1]->flags); exit(); }
AFTER lsmod
EXPECT Attaching 1 probe...
TIMEOUT 1

NAME unaligned key with aligned value
PROG BEGIN { @mapA["aaaabbb", 0] = 1; @mapA["ccccdddd", 0] = 1; }
EXPECT Attaching 1 probe...
TIMEOUT 1

0 comments on commit af32e6b

Please sign in to comment.