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