diff options
author | Andrew G. Morgan <morgan@kernel.org> | 2020-07-22 23:55:05 -0700 |
---|---|---|
committer | Andrew G. Morgan <morgan@kernel.org> | 2020-07-22 23:55:05 -0700 |
commit | c7b5f2941a045df8cce3d59952817b8bdf0e1173 (patch) | |
tree | 8f8f7a9366c4ee767abdffcd5e305dba2c31687e /go | |
parent | be5aae2502e8e26964ffcfbf7cb9b238884dc29c (diff) | |
download | platform_external_libcap-c7b5f2941a045df8cce3d59952817b8bdf0e1173.tar.gz platform_external_libcap-c7b5f2941a045df8cce3d59952817b8bdf0e1173.tar.bz2 platform_external_libcap-c7b5f2941a045df8cce3d59952817b8bdf0e1173.zip |
Make Go cap.String() and (*cap.Set).String() equal C equivalents.
Test and confirm that the two implementations agree.
Signed-off-by: Andrew G. Morgan <morgan@kernel.org>
Diffstat (limited to 'go')
-rw-r--r-- | go/compare-cap.go | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/go/compare-cap.go b/go/compare-cap.go index c874ad8..4424ebe 100644 --- a/go/compare-cap.go +++ b/go/compare-cap.go @@ -281,6 +281,58 @@ func main() { log.Fatalf("all decode failed in Go: got=%q, want=%q", got, want) } + // Validate some random values stringify consistently between + // libcap.cap_to_text() and (*cap.Set).String(). + mb := cap.MaxBits() + sample := cap.NewSet() + for c := cap.Value(0); c < 7*mb; c += 3 { + n := int(c) + raise, f := c%mb, cap.Flag(c/mb)%3 + sample.SetFlag(f, true, raise) + if v, err := cap.FromText(sample.String()); err != nil { + log.Fatalf("[%d] cap to text for %q not reversible: %v", n, sample, err) + } else if cf, err := v.Compare(sample); err != nil { + log.Fatalf("[%d] FromText generated bad capability from %q: %v", n, sample, err) + } else if cf != 0 { + log.Fatalf("[%d] text import got=%q want=%q", n, v, sample) + } + e, err := sample.Export() + if err != nil { + log.Fatalf("[%d] failed to export %q: %v", n, sample, err) + } + i, err := cap.Import(e) + if err != nil { + log.Fatalf("[%d] failed to import %q: %v", n, sample, err) + } + if cf, err := i.Compare(sample); err != nil { + log.Fatalf("[%d] failed to compare %q vs original:%q", n, i, sample) + } else if cf != 0 { + log.Fatalf("[%d] import got=%q want=%q", n, i, sample) + } + // Confirm that importing this portable binary + // representation in libcap and converting to text, + // generates the same text as Go generates. This was + // broken prior to v0.2.41. + cCap := C.cap_copy_int(unsafe.Pointer(&e[0])) + if cCap == nil { + log.Fatalf("[%d] C import failed for %q export", n, sample) + } + var tCLen C.ssize_t + tC := C.cap_to_text(cCap, &tCLen) + if tC == nil { + log.Fatalf("[%d] basic c init caps -> text failure", n) + } + C.cap_free(unsafe.Pointer(cCap)) + importT := C.GoString(tC) + C.cap_free(unsafe.Pointer(tC)) + if got, want := len(importT), int(tCLen); got != want { + log.Fatalf("[%d] C text generated wrong length: Go=%d, C=%d", n, got, want) + } + if got, want := importT, sample.String(); got != want { + log.Fatalf("[%d] C and Go text rep disparity: C=%q Go=%q", n, got, want) + } + } + iab, err := cap.IABFromText("cap_chown,!cap_setuid,^cap_setgid") if err != nil { log.Fatalf("failed to initialize iab from text: %v", err) |