Skip to content

Commit 91d7ab2

Browse files
committed
cmd/internal/obj: handle static assembly symbols correctly in FIPS check
Static symbols don't have the package prefix, so we need to identify them specially. Change-Id: Iaa0456de802478f6a257164e9703f18f8dc7eb50 Reviewed-on: https://go-review.googlesource.com/c/go/+/631975 Reviewed-by: Cherry Mui <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent 4f78aa9 commit 91d7ab2

File tree

8 files changed

+167
-34
lines changed

8 files changed

+167
-34
lines changed

src/cmd/internal/obj/fips140.go

Lines changed: 42 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -221,47 +221,55 @@ func (s *LSym) setFIPSType(ctxt *Link) {
221221
return
222222
}
223223

224-
// Name must begin with crypto/internal/fips140, then dot or slash.
225-
// The quick check for 'c' before the string compare is probably overkill,
226-
// but this function is called a fair amount, and we don't want to
227-
// slow down all the non-FIPS compilations.
228-
const prefix = "crypto/internal/fips140"
229-
name := s.Name
230-
if len(name) <= len(prefix) || (name[len(prefix)] != '.' && name[len(prefix)] != '/') || name[0] != 'c' || name[:len(prefix)] != prefix {
231-
return
232-
}
233-
234-
if strings.Contains(name, "_test.") {
235-
// External test packages are not in the scope.
224+
// External test packages are not in scope.
225+
if strings.HasSuffix(ctxt.Pkgpath, "_test") {
236226
return
237227
}
238228

239-
// Now we're at least handling a FIPS symbol.
240-
// It's okay to be slower now, since this code only runs when compiling a few packages.
241-
// Text symbols are always okay, since they can use PC-relative relocations,
242-
// but some data symbols are not.
243-
if s.Type != objabi.STEXT && s.Type != objabi.STEXTFIPS {
244-
// Even in the crypto/internal/fips140 packages,
245-
// we exclude various Go runtime metadata,
246-
// so that it can be allowed to contain data relocations.
247-
if strings.Contains(name, ".inittask") ||
248-
strings.Contains(name, ".dict") ||
249-
strings.Contains(name, ".typeAssert") ||
250-
strings.HasSuffix(name, ".arginfo0") ||
251-
strings.HasSuffix(name, ".arginfo1") ||
252-
strings.HasSuffix(name, ".argliveinfo") ||
253-
strings.HasSuffix(name, ".args_stackmap") ||
254-
strings.HasSuffix(name, ".opendefer") ||
255-
strings.HasSuffix(name, ".stkobj") ||
256-
strings.HasSuffix(name, "·f") {
229+
if s.Attribute.Static() {
230+
// Static (file-scoped) symbol does not have name prefix,
231+
// but must be local to package; rely on whether package is FIPS.
232+
if !ctxt.IsFIPS() {
257233
return
258234
}
259-
260-
// This symbol is linknamed to go:fipsinfo,
261-
// so we shouldn't see it, but skip it just in case.
262-
if s.Name == "crypto/internal/fips140/check.linkinfo" {
235+
} else {
236+
// Name must begin with crypto/internal/fips140, then dot or slash.
237+
// The quick check for 'c' before the string compare is probably overkill,
238+
// but this function is called a fair amount, and we don't want to
239+
// slow down all the non-FIPS compilations.
240+
const prefix = "crypto/internal/fips140"
241+
name := s.Name
242+
if len(name) <= len(prefix) || (name[len(prefix)] != '.' && name[len(prefix)] != '/') || name[0] != 'c' || name[:len(prefix)] != prefix {
263243
return
264244
}
245+
246+
// Now we're at least handling a FIPS symbol.
247+
// It's okay to be slower now, since this code only runs when compiling a few packages.
248+
// Text symbols are always okay, since they can use PC-relative relocations,
249+
// but some data symbols are not.
250+
if s.Type != objabi.STEXT && s.Type != objabi.STEXTFIPS {
251+
// Even in the crypto/internal/fips140 packages,
252+
// we exclude various Go runtime metadata,
253+
// so that it can be allowed to contain data relocations.
254+
if strings.Contains(name, ".inittask") ||
255+
strings.Contains(name, ".dict") ||
256+
strings.Contains(name, ".typeAssert") ||
257+
strings.HasSuffix(name, ".arginfo0") ||
258+
strings.HasSuffix(name, ".arginfo1") ||
259+
strings.HasSuffix(name, ".argliveinfo") ||
260+
strings.HasSuffix(name, ".args_stackmap") ||
261+
strings.HasSuffix(name, ".opendefer") ||
262+
strings.HasSuffix(name, ".stkobj") ||
263+
strings.HasSuffix(name, "·f") {
264+
return
265+
}
266+
267+
// This symbol is linknamed to go:fipsinfo,
268+
// so we shouldn't see it, but skip it just in case.
269+
if s.Name == "crypto/internal/fips140/check.linkinfo" {
270+
return
271+
}
272+
}
265273
}
266274

267275
// This is a FIPS symbol! Convert its type to FIPS.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2024 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
//go:build !purego
6+
7+
#include "textflag.h"
8+
9+
DATA StaticData<>(SB)/4, $10
10+
GLOBL StaticData<>(SB), NOPTR, $4
11+
12+
TEXT StaticText<>(SB), $0
13+
RET
14+
15+
TEXT ·PtrStaticData(SB), $0-4
16+
MOVL $StaticData<>(SB), AX
17+
MOVL AX, ret+0(FP)
18+
RET
19+
20+
TEXT ·PtrStaticText(SB), $0-4
21+
MOVL $StaticText<>(SB), AX
22+
MOVL AX, ret+0(FP)
23+
RET
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2024 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
//go:build !purego
6+
7+
#include "textflag.h"
8+
9+
DATA StaticData<>(SB)/4, $10
10+
GLOBL StaticData<>(SB), NOPTR, $4
11+
12+
TEXT StaticText<>(SB), $0
13+
RET
14+
15+
TEXT ·PtrStaticData(SB), $0-8
16+
MOVQ $StaticData<>(SB), AX
17+
MOVQ AX, ret+0(FP)
18+
RET
19+
20+
TEXT ·PtrStaticText(SB), $0-8
21+
MOVQ $StaticText<>(SB), AX
22+
MOVQ AX, ret+0(FP)
23+
RET
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2024 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
//go:build !purego
6+
7+
#include "textflag.h"
8+
9+
DATA StaticData<>(SB)/4, $10
10+
GLOBL StaticData<>(SB), NOPTR, $4
11+
12+
TEXT StaticText<>(SB), $0
13+
RET
14+
15+
TEXT ·PtrStaticData(SB), $0-4
16+
MOVW $StaticData<>(SB), R1
17+
MOVW R1, ret+0(FP)
18+
RET
19+
20+
TEXT ·PtrStaticText(SB), $0-4
21+
MOVW $StaticText<>(SB), R1
22+
MOVW R1, ret+0(FP)
23+
RET
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2024 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
//go:build !purego
6+
7+
#include "textflag.h"
8+
9+
DATA StaticData<>(SB)/4, $10
10+
GLOBL StaticData<>(SB), NOPTR, $4
11+
12+
TEXT StaticText<>(SB), $0
13+
RET
14+
15+
TEXT ·PtrStaticData(SB), $0-8
16+
MOVD $StaticData<>(SB), R1
17+
MOVD R1, ret+0(FP)
18+
RET
19+
20+
TEXT ·PtrStaticText(SB), $0-8
21+
MOVD $StaticText<>(SB), R1
22+
MOVD R1, ret+0(FP)
23+
RET
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Copyright 2024 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
//go:build (!386 && !amd64 && !arm && !arm64) || purego
6+
7+
package checktest
8+
9+
import "unsafe"
10+
11+
func PtrStaticData() *uint32 { return nil }
12+
func PtrStaticText() unsafe.Pointer { return nil }
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Copyright 2024 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
//go:build (386 || amd64 || arm || arm64) && !purego
6+
7+
package checktest
8+
9+
import "unsafe"
10+
11+
func PtrStaticData() *uint32
12+
func PtrStaticText() unsafe.Pointer

src/crypto/internal/fips140test/check_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ func TestFIPSCheckInfo(t *testing.T) {
8080
if checktest.BSS != nil {
8181
t.Errorf("checktest.BSS = %p, want nil", checktest.BSS)
8282
}
83+
if p := checktest.PtrStaticData(); p != nil && *p != 10 {
84+
t.Errorf("*checktest.PtrStaticData() = %d, want 10", *p)
85+
}
8386

8487
// Check that the checktest symbols are in the right go:fipsinfo sections.
8588
sect := func(i int, name string, p unsafe.Pointer) {
@@ -89,8 +92,14 @@ func TestFIPSCheckInfo(t *testing.T) {
8992
}
9093
}
9194
sect(0, "TEXT", unsafe.Pointer(abi.FuncPCABIInternal(checktest.TEXT)))
95+
if p := checktest.PtrStaticText(); p != nil {
96+
sect(0, "StaticText", p)
97+
}
9298
sect(1, "RODATA", unsafe.Pointer(&checktest.RODATA))
9399
sect(2, "NOPTRDATA", unsafe.Pointer(&checktest.NOPTRDATA))
100+
if p := checktest.PtrStaticData(); p != nil {
101+
sect(2, "StaticData", unsafe.Pointer(p))
102+
}
94103
sect(3, "DATA", unsafe.Pointer(&checktest.DATA))
95104

96105
// Check that some symbols are not in FIPS sections.

0 commit comments

Comments
 (0)