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