aboutsummaryrefslogtreecommitdiffstats
path: root/go
diff options
context:
space:
mode:
authorAndrew G. Morgan <morgan@kernel.org>2020-07-22 23:55:05 -0700
committerAndrew G. Morgan <morgan@kernel.org>2020-07-22 23:55:05 -0700
commitc7b5f2941a045df8cce3d59952817b8bdf0e1173 (patch)
tree8f8f7a9366c4ee767abdffcd5e305dba2c31687e /go
parentbe5aae2502e8e26964ffcfbf7cb9b238884dc29c (diff)
downloadplatform_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.go52
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)