alignedbuff: fix alignment test issue on 32-bit machines (#211)

- fixes issue #209 where two unit tests for alignedbuff were incorrectly calculating the expected marshalled data length on 32bit machines (whereas actual padding/alignment itself was done correctly).
- adds documentation reference to kernel's xtables.h UAPI regarding alignment.
This commit is contained in:
TheDiveO 2022-12-12 08:51:36 +01:00 committed by GitHub
parent 1aef2ba20e
commit d1d398adb7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 3 deletions

View File

@ -1,5 +1,16 @@
// Package alignedbuff implements encoding and decoding aligned data elements // Package alignedbuff implements encoding and decoding aligned data elements
// to/from buffers in native endianess. // to/from buffers in native endianess.
//
// # Note
//
// The alignment/padding as implemented in this package must match that of
// kernel's and user space C implementations for a particular architecture (bit
// size). Please see also the "dummy structure" _xt_align
// (https://elixir.bootlin.com/linux/v5.17.7/source/include/uapi/linux/netfilter/x_tables.h#L93)
// as well as the associated XT_ALIGN C preprocessor macro.
//
// In particular, we rely on the Go compiler to follow the same architecture
// alignments as the C compiler(s) on Linux.
package alignedbuff package alignedbuff
import ( import (
@ -144,7 +155,8 @@ func (a *AlignedBuff) String() (string, error) {
return v, nil return v, nil
} }
// Unmarshals a string of a given length (for non-null terminated strings) // StringWithLength unmarshals a string of a given length (for non-null
// terminated strings)
func (a *AlignedBuff) StringWithLength(len int) (string, error) { func (a *AlignedBuff) StringWithLength(len int) (string, error) {
v := binaryutil.String(a.data[a.pos : a.pos+len]) v := binaryutil.String(a.data[a.pos : a.pos+len])
a.pos += len a.pos += len

View File

@ -103,7 +103,15 @@ func TestAlignedBuff32(t *testing.T) {
b := NewWithData(b0.data) b := NewWithData(b0.data)
if len(b0.Data()) != 4*4 { // Sigh. The Linux kernel expects certain nftables payloads to be padded to
// the uint64 next alignment. Now, on 64bit platforms this will be a 64bit
// alignment, yet on 32bit platforms this will be a 32bit alignment. So, we
// should calculate the expected data length here separately from our
// implementation to be fail safe! However, this might be rather a recipe
// for a safe fail...
expectedlen := 2*(uint32AlignMask+1) + (uint64AlignMask + 1)
if len(b0.Data()) != expectedlen {
t.Fatalf("alignment padding failed") t.Fatalf("alignment padding failed")
} }
@ -214,7 +222,15 @@ func TestAlignedBuffInt32(t *testing.T) {
b := NewWithData(b0.data) b := NewWithData(b0.data)
if len(b0.Data()) != 4*4 { // Sigh. The Linux kernel expects certain nftables payloads to be padded to
// the uint64 next alignment. Now, on 64bit platforms this will be a 64bit
// alignment, yet on 32bit platforms this will be a 32bit alignment. So, we
// should calculate the expected data length here separately from our
// implementation to be fail safe! However, this might be rather a recipe
// for a safe fail...
expectedlen := 2*(uint32AlignMask+1) + (uint64AlignMask + 1)
if len(b0.Data()) != expectedlen {
t.Fatalf("alignment padding failed") t.Fatalf("alignment padding failed")
} }