Commit 51857449 authored by Matthew Dempsky's avatar Matthew Dempsky

cmd/compile: remove obsolete "safe" mode

Nowadays there are better ways to safely run untrusted Go programs, like
NaCl and gVisor.

Change-Id: I20c45f13a50dbcf35c343438b720eb93e7b4e13a
Reviewed-on: https://go-review.googlesource.com/c/142717
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: default avatarRuss Cox <rsc@golang.org>
parent f2a67653
...@@ -92,8 +92,6 @@ Flags: ...@@ -92,8 +92,6 @@ Flags:
Compile with race detector enabled. Compile with race detector enabled.
-trimpath prefix -trimpath prefix
Remove prefix from recorded source file paths. Remove prefix from recorded source file paths.
-u
Disallow importing packages not marked as safe; implies -nolocalimports.
There are also a number of debugging flags; run the command with no arguments There are also a number of debugging flags; run the command with no arguments
for a usage message. for a usage message.
......
...@@ -300,18 +300,8 @@ func genhash(sym *types.Sym, t *types.Type) { ...@@ -300,18 +300,8 @@ func genhash(sym *types.Sym, t *types.Type) {
testdclstack() testdclstack()
} }
// Disable safemode while compiling this code: the code we
// generate internally can refer to unsafe.Pointer.
// In this case it can happen if we need to generate an ==
// for a struct containing a reflect.Value, which itself has
// an unexported field of type unsafe.Pointer.
old_safemode := safemode
safemode = false
fn.Func.SetNilCheckDisabled(true) fn.Func.SetNilCheckDisabled(true)
funccompile(fn) funccompile(fn)
safemode = old_safemode
} }
func hashfor(t *types.Type) *Node { func hashfor(t *types.Type) *Node {
...@@ -484,22 +474,12 @@ func geneq(sym *types.Sym, t *types.Type) { ...@@ -484,22 +474,12 @@ func geneq(sym *types.Sym, t *types.Type) {
testdclstack() testdclstack()
} }
// Disable safemode while compiling this code: the code we
// generate internally can refer to unsafe.Pointer.
// In this case it can happen if we need to generate an ==
// for a struct containing a reflect.Value, which itself has
// an unexported field of type unsafe.Pointer.
old_safemode := safemode
safemode = false
// Disable checknils while compiling this code. // Disable checknils while compiling this code.
// We are comparing a struct or an array, // We are comparing a struct or an array,
// neither of which can be nil, and our comparisons // neither of which can be nil, and our comparisons
// are shallow. // are shallow.
fn.Func.SetNilCheckDisabled(true) fn.Func.SetNilCheckDisabled(true)
funccompile(fn) funccompile(fn)
safemode = old_safemode
} }
// eqfield returns the node // eqfield returns the node
......
...@@ -105,8 +105,6 @@ var nsyntaxerrors int ...@@ -105,8 +105,6 @@ var nsyntaxerrors int
var decldepth int32 var decldepth int32
var safemode bool
var nolocalimports bool var nolocalimports bool
var Debug [256]int var Debug [256]int
......
...@@ -87,9 +87,6 @@ func typecheckinl(fn *Node) { ...@@ -87,9 +87,6 @@ func typecheckinl(fn *Node) {
fmt.Printf("typecheck import [%v] %L { %#v }\n", fn.Sym, fn, asNodes(fn.Func.Inl.Body)) fmt.Printf("typecheck import [%v] %L { %#v }\n", fn.Sym, fn, asNodes(fn.Func.Inl.Body))
} }
save_safemode := safemode
safemode = false
savefn := Curfn savefn := Curfn
Curfn = fn Curfn = fn
typecheckslice(fn.Func.Inl.Body, Etop) typecheckslice(fn.Func.Inl.Body, Etop)
...@@ -102,8 +99,6 @@ func typecheckinl(fn *Node) { ...@@ -102,8 +99,6 @@ func typecheckinl(fn *Node) {
fn.Func.Inl.Dcl = append(fn.Func.Inl.Dcl, fn.Func.Dcl...) fn.Func.Inl.Dcl = append(fn.Func.Inl.Dcl, fn.Func.Dcl...)
fn.Func.Dcl = nil fn.Func.Dcl = nil
safemode = save_safemode
lineno = lno lineno = lno
} }
...@@ -803,23 +798,6 @@ func (v *reassignVisitor) visitList(l Nodes) *Node { ...@@ -803,23 +798,6 @@ func (v *reassignVisitor) visitList(l Nodes) *Node {
return nil return nil
} }
// The result of mkinlcall MUST be assigned back to n, e.g.
// n.Left = mkinlcall(n.Left, fn, isddd)
func mkinlcall(n *Node, fn *Node, maxCost int32) *Node {
save_safemode := safemode
// imported functions may refer to unsafe as long as the
// package was marked safe during import (already checked).
pkg := fnpkg(fn)
if pkg != localpkg && pkg != nil {
safemode = false
}
n = mkinlcall1(n, fn, maxCost)
safemode = save_safemode
return n
}
func tinlvar(t *types.Field, inlvars map[*Node]*Node) *Node { func tinlvar(t *types.Field, inlvars map[*Node]*Node) *Node {
if n := asNode(t.Nname); n != nil && !n.isBlank() { if n := asNode(t.Nname); n != nil && !n.isBlank() {
inlvar := inlvars[n] inlvar := inlvars[n]
...@@ -839,9 +817,9 @@ var inlgen int ...@@ -839,9 +817,9 @@ var inlgen int
// On return ninit has the parameter assignments, the nbody is the // On return ninit has the parameter assignments, the nbody is the
// inlined function body and list, rlist contain the input, output // inlined function body and list, rlist contain the input, output
// parameters. // parameters.
// The result of mkinlcall1 MUST be assigned back to n, e.g. // The result of mkinlcall MUST be assigned back to n, e.g.
// n.Left = mkinlcall1(n.Left, fn, isddd) // n.Left = mkinlcall(n.Left, fn, isddd)
func mkinlcall1(n, fn *Node, maxCost int32) *Node { func mkinlcall(n, fn *Node, maxCost int32) *Node {
if fn.Func.Inl == nil { if fn.Func.Inl == nil {
// No inlinable body. // No inlinable body.
return n return n
......
...@@ -228,7 +228,6 @@ func Main(archInit func(*Arch)) { ...@@ -228,7 +228,6 @@ func Main(archInit func(*Arch)) {
} }
objabi.Flagcount("s", "warn about composite literals that can be simplified", &Debug['s']) objabi.Flagcount("s", "warn about composite literals that can be simplified", &Debug['s'])
flag.StringVar(&pathPrefix, "trimpath", "", "remove `prefix` from recorded source file paths") flag.StringVar(&pathPrefix, "trimpath", "", "remove `prefix` from recorded source file paths")
flag.BoolVar(&safemode, "u", false, "reject unsafe code")
flag.BoolVar(&Debug_vlog, "v", false, "increase debug verbosity") flag.BoolVar(&Debug_vlog, "v", false, "increase debug verbosity")
objabi.Flagcount("w", "debug type checking", &Debug['w']) objabi.Flagcount("w", "debug type checking", &Debug['w'])
flag.BoolVar(&use_writebarrier, "wb", true, "enable write barrier") flag.BoolVar(&use_writebarrier, "wb", true, "enable write barrier")
...@@ -840,7 +839,7 @@ func islocalname(name string) bool { ...@@ -840,7 +839,7 @@ func islocalname(name string) bool {
func findpkg(name string) (file string, ok bool) { func findpkg(name string) (file string, ok bool) {
if islocalname(name) { if islocalname(name) {
if safemode || nolocalimports { if nolocalimports {
return "", false return "", false
} }
...@@ -982,11 +981,6 @@ func importfile(f *Val) *types.Pkg { ...@@ -982,11 +981,6 @@ func importfile(f *Val) *types.Pkg {
} }
if path_ == "unsafe" { if path_ == "unsafe" {
if safemode {
yyerror("cannot import package unsafe")
errorexit()
}
imported_unsafe = true imported_unsafe = true
return unsafepkg return unsafepkg
} }
...@@ -1060,7 +1054,6 @@ func importfile(f *Val) *types.Pkg { ...@@ -1060,7 +1054,6 @@ func importfile(f *Val) *types.Pkg {
} }
// process header lines // process header lines
safe := false
for { for {
p, err = imp.ReadString('\n') p, err = imp.ReadString('\n')
if err != nil { if err != nil {
...@@ -1070,13 +1063,6 @@ func importfile(f *Val) *types.Pkg { ...@@ -1070,13 +1063,6 @@ func importfile(f *Val) *types.Pkg {
if p == "\n" { if p == "\n" {
break // header ends with blank line break // header ends with blank line
} }
if strings.HasPrefix(p, "safe") {
safe = true
break // ok to ignore rest
}
}
if safemode && !safe {
yyerror("cannot import unsafe package %q", importpkg.Path)
} }
// assume files move (get installed) so don't record the full path // assume files move (get installed) so don't record the full path
......
...@@ -81,11 +81,6 @@ func printObjHeader(bout *bio.Writer) { ...@@ -81,11 +81,6 @@ func printObjHeader(bout *bio.Writer) {
if localpkg.Name == "main" { if localpkg.Name == "main" {
fmt.Fprintf(bout, "main\n") fmt.Fprintf(bout, "main\n")
} }
if safemode {
fmt.Fprintf(bout, "safe\n")
} else {
fmt.Fprintf(bout, "----\n") // room for some other tool to write "safe"
}
fmt.Fprintf(bout, "\n") // header ends with blank line fmt.Fprintf(bout, "\n") // header ends with blank line
} }
......
...@@ -670,13 +670,6 @@ func assignop(src *types.Type, dst *types.Type, why *string) Op { ...@@ -670,13 +670,6 @@ func assignop(src *types.Type, dst *types.Type, why *string) Op {
*why = "" *why = ""
} }
// TODO(rsc,lvd): This behaves poorly in the presence of inlining.
// https://golang.org/issue/2795
if safemode && !inimport && src != nil && src.Etype == TUNSAFEPTR {
yyerror("cannot use unsafe.Pointer")
errorexit()
}
if src == dst { if src == dst {
return OCONVNOP return OCONVNOP
} }
......
...@@ -2112,10 +2112,6 @@ func typecheck1(n *Node, top int) *Node { ...@@ -2112,10 +2112,6 @@ func typecheck1(n *Node, top int) *Node {
} }
} }
if safemode && !inimport && !compiling_wrappers && t != nil && t.Etype == TUNSAFEPTR {
yyerror("cannot use unsafe.Pointer")
}
evconst(n) evconst(n)
if n.Op == OTYPE && top&Etype == 0 { if n.Op == OTYPE && top&Etype == 0 {
if !n.Type.Broke() { if !n.Type.Broke() {
......
...@@ -3243,17 +3243,6 @@ func walkcompare(n *Node, init *Nodes) *Node { ...@@ -3243,17 +3243,6 @@ func walkcompare(n *Node, init *Nodes) *Node {
n.Left = walkexpr(n.Left, init) n.Left = walkexpr(n.Left, init)
n.Right = walkexpr(n.Right, init) n.Right = walkexpr(n.Right, init)
// Disable safemode while compiling this code: the code we
// generate internally can refer to unsafe.Pointer.
// In this case it can happen if we need to generate an ==
// for a struct containing a reflect.Value, which itself has
// an unexported field of type unsafe.Pointer.
old_safemode := safemode
safemode = false
defer func() {
safemode = old_safemode
}()
// Given interface value l and concrete value r, rewrite // Given interface value l and concrete value r, rewrite
// l == r // l == r
// into types-equal && data-equal. // into types-equal && data-equal.
......
// errorcheck -u -+
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Check that we cannot import a package that uses "unsafe" internally
// when -u is supplied.
package main
import "syscall" // ERROR "import unsafe package"
func main() {
print(syscall.Environ())
}
// errorcheck -u -+
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Check that we cannot import the "unsafe" package when -u is supplied.
package a
import "unsafe" // ERROR "import package unsafe"
func Float32bits(f float32) uint32 {
return *(*uint32)(unsafe.Pointer(&f))
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment