xref: /aosp_15_r20/external/toolchain-utils/compiler_wrapper/sanitizer_flags_test.go (revision 760c253c1ed00ce9abd48f8546f08516e57485fe)
1// Copyright 2019 The ChromiumOS Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5package main
6
7import (
8	"testing"
9)
10
11func TestFortifyIsKeptIfSanitizerIsTrivial(t *testing.T) {
12	withTestContext(t, func(ctx *testContext) {
13		cmd := ctx.must(callCompiler(ctx, ctx.cfg,
14			ctx.newCommand(gccX86_64, "-fsanitize=return", "-D_FORTIFY_SOURCE=1", mainCc)))
15		if err := verifyArgCount(cmd, 1, "-D_FORTIFY_SOURCE=1"); err != nil {
16			t.Error(err)
17		}
18
19		cmd = ctx.must(callCompiler(ctx, ctx.cfg,
20			ctx.newCommand(gccX86_64, "-fsanitize=return,address", "-D_FORTIFY_SOURCE=1", mainCc)))
21		if err := verifyArgCount(cmd, 0, "-D_FORTIFY_SOURCE=1"); err != nil {
22			t.Error(err)
23		}
24
25		cmd = ctx.must(callCompiler(ctx, ctx.cfg,
26			ctx.newCommand(gccX86_64, "-fsanitize=address,return", "-D_FORTIFY_SOURCE=1", mainCc)))
27		if err := verifyArgCount(cmd, 0, "-D_FORTIFY_SOURCE=1"); err != nil {
28			t.Error(err)
29		}
30	})
31}
32
33func TestFilterUnsupportedSanitizerFlagsIfSanitizeGiven(t *testing.T) {
34	withTestContext(t, func(ctx *testContext) {
35		cmd := ctx.must(callCompiler(ctx, ctx.cfg,
36			ctx.newCommand(gccX86_64, "-fsanitize=kernel-address", "-Wl,--no-undefined", mainCc)))
37		if err := verifyArgCount(cmd, 0, "-Wl,--no-undefined"); err != nil {
38			t.Error(err)
39		}
40
41		cmd = ctx.must(callCompiler(ctx, ctx.cfg,
42			ctx.newCommand(gccX86_64, "-fsanitize=kernel-address", "-Wl,-z,defs", mainCc)))
43		if err := verifyArgCount(cmd, 0, "-Wl,-z,defs"); err != nil {
44			t.Error(err)
45		}
46
47		cmd = ctx.must(callCompiler(ctx, ctx.cfg,
48			ctx.newCommand(gccX86_64, "-fsanitize=kernel-address", "-Wl,-z,defs,relro", mainCc)))
49		if err := verifyArgCount(cmd, 1, "-Wl,relro"); err != nil {
50			t.Error(err)
51		}
52
53		cmd = ctx.must(callCompiler(ctx, ctx.cfg,
54			ctx.newCommand(gccX86_64, "-fsanitize=kernel-address", "-Wl,-z -Wl,defs", mainCc)))
55		if err := verifyArgCount(cmd, 0, "-Wl,-z"); err != nil {
56			t.Error(err)
57		}
58		if err := verifyArgCount(cmd, 0, "-Wl,defs"); err != nil {
59			t.Error(err)
60		}
61
62		cmd = ctx.must(callCompiler(ctx, ctx.cfg,
63			ctx.newCommand(gccX86_64, "-fsanitize=kernel-address", "-D_FORTIFY_SOURCE=1", mainCc)))
64		if err := verifyArgCount(cmd, 0, "-D_FORTIFY_SOURCE=1"); err != nil {
65			t.Error(err)
66		}
67
68		cmd = ctx.must(callCompiler(ctx, ctx.cfg,
69			ctx.newCommand(gccX86_64, "-fsanitize=kernel-address", "-D_FORTIFY_SOURCE=2", mainCc)))
70		if err := verifyArgCount(cmd, 0, "-D_FORTIFY_SOURCE=2"); err != nil {
71			t.Error(err)
72		}
73	})
74}
75
76func TestAllFortifyEnableFlagsAreRemoved(t *testing.T) {
77	withTestContext(t, func(ctx *testContext) {
78		flagsToRemove := []string{
79			"-D_FORTIFY_SOURCE=1",
80			"-D_FORTIFY_SOURCE=2",
81			"-D_FORTIFY_SOURCE=3",
82		}
83		for _, fortifyFlag := range flagsToRemove {
84			ctx.cfg.commonFlags = []string{fortifyFlag}
85			cmd := ctx.must(callCompiler(ctx, ctx.cfg,
86				ctx.newCommand(clangX86_64, "-fsanitize=kernel-address", mainCc)))
87			if err := verifyArgCount(cmd, 0, fortifyFlag); err != nil {
88				t.Errorf("Verifying FORTIFY flag %q is removed: %v", fortifyFlag, err)
89			}
90		}
91	})
92}
93
94func TestFortifyDisableFlagsAreKept(t *testing.T) {
95	withTestContext(t, func(ctx *testContext) {
96		flagsToKeep := []string{
97			"-D_FORTIFY_SOURCE",
98			"-D_FORTIFY_SOURCE=",
99			"-D_FORTIFY_SOURCE=0",
100		}
101		for _, fortifyFlag := range flagsToKeep {
102			ctx.cfg.commonFlags = []string{fortifyFlag}
103			cmd := ctx.must(callCompiler(ctx, ctx.cfg,
104				ctx.newCommand(clangX86_64, "-fsanitize=kernel-address", mainCc)))
105			if err := verifyArgCount(cmd, 1, fortifyFlag); err != nil {
106				t.Errorf("Verifying FORTIFY flag %q is kept: %v", fortifyFlag, err)
107			}
108		}
109	})
110}
111
112func TestFilterUnsupportedDefaultSanitizerFlagsIfSanitizeGivenForClang(t *testing.T) {
113	withTestContext(t, func(ctx *testContext) {
114		ctx.cfg.commonFlags = []string{"-D_FORTIFY_SOURCE=1"}
115		cmd := ctx.must(callCompiler(ctx, ctx.cfg,
116			ctx.newCommand(clangX86_64, "-fsanitize=kernel-address", mainCc)))
117		if err := verifyArgCount(cmd, 0, "-D_FORTIFY_SOURCE=1"); err != nil {
118			t.Error(err)
119		}
120	})
121}
122
123func TestKeepUnsupportedDefaultSanitizerFlagsIfSanitizeGivenForGcc(t *testing.T) {
124	withTestContext(t, func(ctx *testContext) {
125		ctx.cfg.commonFlags = []string{"-D_FORTIFY_SOURCE=1"}
126		cmd := ctx.must(callCompiler(ctx, ctx.cfg,
127			ctx.newCommand(gccX86_64, "-fsanitize=kernel-address", mainCc)))
128		if err := verifyArgCount(cmd, 1, "-D_FORTIFY_SOURCE=1"); err != nil {
129			t.Error(err)
130		}
131	})
132}
133
134// TODO: This is a bug in the old wrapper to not filter
135// non user args for gcc. Fix this once we don't compare to the old wrapper anymore.
136func TestKeepSanitizerFlagsIfNoSanitizeGiven(t *testing.T) {
137	withTestContext(t, func(ctx *testContext) {
138		cmd := ctx.must(callCompiler(ctx, ctx.cfg,
139			ctx.newCommand(gccX86_64, "-Wl,--no-undefined", mainCc)))
140		if err := verifyArgCount(cmd, 1, "-Wl,--no-undefined"); err != nil {
141			t.Error(err)
142		}
143
144		cmd = ctx.must(callCompiler(ctx, ctx.cfg,
145			ctx.newCommand(gccX86_64, "-Wl,-z,defs", mainCc)))
146		if err := verifyArgCount(cmd, 1, "-Wl,-z,defs"); err != nil {
147			t.Error(err)
148		}
149
150		cmd = ctx.must(callCompiler(ctx, ctx.cfg,
151			ctx.newCommand(gccX86_64, "-Wl,-z", "-Wl,defs", mainCc)))
152		if err := verifyArgCount(cmd, 1, "-Wl,-z"); err != nil {
153			t.Error(err)
154		}
155		if err := verifyArgCount(cmd, 1, "-Wl,defs"); err != nil {
156			t.Error(err)
157		}
158
159		cmd = ctx.must(callCompiler(ctx, ctx.cfg,
160			ctx.newCommand(gccX86_64, "-D_FORTIFY_SOURCE=1", mainCc)))
161		if err := verifyArgCount(cmd, 1, "-D_FORTIFY_SOURCE=1"); err != nil {
162			t.Error(err)
163		}
164
165		cmd = ctx.must(callCompiler(ctx, ctx.cfg,
166			ctx.newCommand(gccX86_64, "-D_FORTIFY_SOURCE=2", mainCc)))
167		if err := verifyArgCount(cmd, 1, "-D_FORTIFY_SOURCE=2"); err != nil {
168			t.Error(err)
169		}
170	})
171}
172
173func TestKeepSanitizerFlagsIfSanitizeGivenInCommonFlags(t *testing.T) {
174	withTestContext(t, func(ctx *testContext) {
175		ctx.cfg.commonFlags = []string{"-fsanitize=kernel-address"}
176		cmd := ctx.must(callCompiler(ctx, ctx.cfg,
177			ctx.newCommand(gccX86_64, "-Wl,--no-undefined", mainCc)))
178		if err := verifyArgCount(cmd, 1, "-Wl,--no-undefined"); err != nil {
179			t.Error(err)
180		}
181	})
182}
183