diff options
author | Adin Scannell <ascannell@google.com> | 2019-07-09 16:42:54 -0700 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2019-07-09 16:44:06 -0700 |
commit | dea3cb92f2c9fffb604cedde6998b3209c91e716 (patch) | |
tree | 41f1ac37d1f8b80861cfb63da9bbaca6c6a1c9da | |
parent | cceef9d2cfbf72a7ae4feac2e53e46179c33155d (diff) |
build: add nogo for static validation
PiperOrigin-RevId: 257297820
-rw-r--r-- | BUILD | 14 | ||||
-rw-r--r-- | WORKSPACE | 11 | ||||
-rw-r--r-- | pkg/sentry/kernel/BUILD | 4 | ||||
-rw-r--r-- | pkg/sentry/kernel/auth/BUILD | 4 | ||||
-rw-r--r-- | pkg/sentry/kernel/futex/BUILD | 4 | ||||
-rw-r--r-- | pkg/sentry/time/BUILD | 4 | ||||
-rw-r--r-- | third_party/gvsync/atomicptrtest/BUILD | 4 | ||||
-rw-r--r-- | third_party/gvsync/seqatomictest/BUILD | 4 | ||||
-rw-r--r-- | tools/checkunsafe/BUILD | 13 | ||||
-rw-r--r-- | tools/checkunsafe/check_unsafe.go | 56 | ||||
-rw-r--r-- | tools/nogo.js | 7 |
11 files changed, 111 insertions, 14 deletions
@@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_path") +load("@io_bazel_rules_go//go:def.bzl", "go_path", "nogo") load("@bazel_gazelle//:def.bzl", "gazelle") # The sandbox filegroup is used for sandbox-internal dependencies. @@ -29,3 +29,15 @@ go_path( # To update the WORKSPACE from go.mod, use: # bazel run //:gazelle -- update-repos -from_file=go.mod gazelle(name = "gazelle") + +# nogo applies checks to all Go source in this repository, enforcing code +# guidelines and restrictions. Note that the tool libraries themselves should +# live in the tools subdirectory (unless they are standard). +nogo( + name = "nogo", + config = "tools/nogo.js", + visibility = ["//visibility:public"], + deps = [ + "//tools/checkunsafe", + ], +) @@ -20,7 +20,10 @@ load("@io_bazel_rules_go//go:deps.bzl", "go_rules_dependencies", "go_register_to go_rules_dependencies() -go_register_toolchains(go_version = "1.12.6") +go_register_toolchains( + go_version = "1.12.6", + nogo = "@//:nogo", +) load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies", "go_repository") @@ -142,6 +145,12 @@ go_repository( ) go_repository( + name = "org_golang_x_tools", + commit = "aa82965741a9fecd12b026fbb3d3c6ed3231b8f8", + importpath = "golang.org/x/tools", +) + +go_repository( name = "com_github_google_btree", importpath = "github.com/google/btree", tag = "v1.0.0", diff --git a/pkg/sentry/kernel/BUILD b/pkg/sentry/kernel/BUILD index 7b92f1b8d..e61d39c82 100644 --- a/pkg/sentry/kernel/BUILD +++ b/pkg/sentry/kernel/BUILD @@ -31,7 +31,7 @@ go_template_instance( go_template_instance( name = "seqatomic_taskgoroutineschedinfo", - out = "seqatomic_taskgoroutineschedinfo.go", + out = "seqatomic_taskgoroutineschedinfo_unsafe.go", package = "kernel", suffix = "TaskGoroutineSchedInfo", template = "//third_party/gvsync:generic_seqatomic", @@ -112,7 +112,7 @@ go_library( "ptrace_arm64.go", "rseq.go", "seccomp.go", - "seqatomic_taskgoroutineschedinfo.go", + "seqatomic_taskgoroutineschedinfo_unsafe.go", "session_list.go", "sessions.go", "signal.go", diff --git a/pkg/sentry/kernel/auth/BUILD b/pkg/sentry/kernel/auth/BUILD index 42779baa9..1d00a6310 100644 --- a/pkg/sentry/kernel/auth/BUILD +++ b/pkg/sentry/kernel/auth/BUILD @@ -5,7 +5,7 @@ load("//tools/go_stateify:defs.bzl", "go_library") go_template_instance( name = "atomicptr_credentials", - out = "atomicptr_credentials.go", + out = "atomicptr_credentials_unsafe.go", package = "auth", suffix = "Credentials", template = "//third_party/gvsync:generic_atomicptr", @@ -45,7 +45,7 @@ go_template_instance( go_library( name = "auth", srcs = [ - "atomicptr_credentials.go", + "atomicptr_credentials_unsafe.go", "auth.go", "capability_set.go", "context.go", diff --git a/pkg/sentry/kernel/futex/BUILD b/pkg/sentry/kernel/futex/BUILD index a5cf1f627..6a31dc044 100644 --- a/pkg/sentry/kernel/futex/BUILD +++ b/pkg/sentry/kernel/futex/BUILD @@ -5,7 +5,7 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_template_instance( name = "atomicptr_bucket", - out = "atomicptr_bucket.go", + out = "atomicptr_bucket_unsafe.go", package = "futex", suffix = "Bucket", template = "//third_party/gvsync:generic_atomicptr", @@ -29,7 +29,7 @@ go_template_instance( go_library( name = "futex", srcs = [ - "atomicptr_bucket.go", + "atomicptr_bucket_unsafe.go", "futex.go", "waiter_list.go", ], diff --git a/pkg/sentry/time/BUILD b/pkg/sentry/time/BUILD index d2ede0353..8aa6a3017 100644 --- a/pkg/sentry/time/BUILD +++ b/pkg/sentry/time/BUILD @@ -6,7 +6,7 @@ load("//tools/go_generics:defs.bzl", "go_template_instance") go_template_instance( name = "seqatomic_parameters", - out = "seqatomic_parameters.go", + out = "seqatomic_parameters_unsafe.go", package = "time", suffix = "Parameters", template = "//third_party/gvsync:generic_seqatomic", @@ -27,7 +27,7 @@ go_library( "parameters.go", "sampler.go", "sampler_unsafe.go", - "seqatomic_parameters.go", + "seqatomic_parameters_unsafe.go", "tsc_amd64.s", "tsc_arm64.s", ], diff --git a/third_party/gvsync/atomicptrtest/BUILD b/third_party/gvsync/atomicptrtest/BUILD index 631b0b64c..6cf69ea91 100644 --- a/third_party/gvsync/atomicptrtest/BUILD +++ b/third_party/gvsync/atomicptrtest/BUILD @@ -6,7 +6,7 @@ load("//tools/go_generics:defs.bzl", "go_template_instance") go_template_instance( name = "atomicptr_int", - out = "atomicptr_int.go", + out = "atomicptr_int_unsafe.go", package = "atomicptr", suffix = "Int", template = "//third_party/gvsync:generic_atomicptr", @@ -17,7 +17,7 @@ go_template_instance( go_library( name = "atomicptr", - srcs = ["atomicptr_int.go"], + srcs = ["atomicptr_int_unsafe.go"], importpath = "gvisor.dev/gvisor/third_party/gvsync/atomicptr", ) diff --git a/third_party/gvsync/seqatomictest/BUILD b/third_party/gvsync/seqatomictest/BUILD index 9dd600148..9e87e0bc5 100644 --- a/third_party/gvsync/seqatomictest/BUILD +++ b/third_party/gvsync/seqatomictest/BUILD @@ -6,7 +6,7 @@ load("//tools/go_generics:defs.bzl", "go_template_instance") go_template_instance( name = "seqatomic_int", - out = "seqatomic_int.go", + out = "seqatomic_int_unsafe.go", package = "seqatomic", suffix = "Int", template = "//third_party/gvsync:generic_seqatomic", @@ -17,7 +17,7 @@ go_template_instance( go_library( name = "seqatomic", - srcs = ["seqatomic_int.go"], + srcs = ["seqatomic_int_unsafe.go"], importpath = "gvisor.dev/gvisor/third_party/gvsync/seqatomic", deps = [ "//third_party/gvsync", diff --git a/tools/checkunsafe/BUILD b/tools/checkunsafe/BUILD new file mode 100644 index 000000000..d85c56131 --- /dev/null +++ b/tools/checkunsafe/BUILD @@ -0,0 +1,13 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_tool_library") + +package(licenses = ["notice"]) + +go_tool_library( + name = "checkunsafe", + srcs = ["check_unsafe.go"], + importpath = "checkunsafe", + visibility = ["//visibility:public"], + deps = [ + "@org_golang_x_tools//go/analysis:go_tool_library", + ], +) diff --git a/tools/checkunsafe/check_unsafe.go b/tools/checkunsafe/check_unsafe.go new file mode 100644 index 000000000..4ccd7cc5a --- /dev/null +++ b/tools/checkunsafe/check_unsafe.go @@ -0,0 +1,56 @@ +// Copyright 2019 The gVisor Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package checkunsafe allows unsafe imports only in files named appropriately. +package checkunsafe + +import ( + "fmt" + "path" + "strconv" + "strings" + + "golang.org/x/tools/go/analysis" +) + +// Analyzer defines the entrypoint. +var Analyzer = &analysis.Analyzer{ + Name: "checkunsafe", + Doc: "allows unsafe use only in specified files", + Run: run, +} + +func run(pass *analysis.Pass) (interface{}, error) { + for _, f := range pass.Files { + for _, imp := range f.Imports { + // Is this an unsafe import? + pkg, err := strconv.Unquote(imp.Path.Value) + if err != nil || pkg != "unsafe" { + continue + } + + // Extract the filename. + filename := pass.Fset.File(imp.Pos()).Name() + + // Allow files named _unsafe.go or _test.go to opt out. + if strings.HasSuffix(filename, "_unsafe.go") || strings.HasSuffix(filename, "_test.go") { + continue + } + + // Throw the error. + pass.Reportf(imp.Pos(), fmt.Sprintf("package unsafe imported by %s; must end with _unsafe.go", path.Base(filename))) + } + } + return nil, nil +} diff --git a/tools/nogo.js b/tools/nogo.js new file mode 100644 index 000000000..fc0a4d1f0 --- /dev/null +++ b/tools/nogo.js @@ -0,0 +1,7 @@ +{ + "checkunsafe": { + "exclude_files": { + "/external/": "not subject to constraint" + } + } +} |