From 9f0092874ff0186f6c5e1381dcbd8265b988f2f8 Mon Sep 17 00:00:00 2001 From: Ian A Mason Date: Fri, 30 Oct 2020 18:39:44 +0000 Subject: [PATCH] Another freeBSD file extension: nossppico (a position-independent relocatable object without stack smashing protection) --- shared/compiler.go | 140 ++++++++++++++++++++++++-------------------- shared/constants.go | 2 +- shared/filetypes.go | 4 +- shared/parser.go | 2 +- 4 files changed, 80 insertions(+), 68 deletions(-) diff --git a/shared/compiler.go b/shared/compiler.go index 1633f3b..1f85f62 100644 --- a/shared/compiler.go +++ b/shared/compiler.go @@ -133,8 +133,10 @@ func buildAndAttachBitcode(compilerExecName string, pr ParserResult, bcObjLinks } func attachBitcodePathToObject(bcFile, objFile string) (success bool) { + success = false // We can only attach a bitcode path to certain file types // this is too fragile, we need to look into a better way to do this. + // We probably should be using debug/macho and debug/elf according to the OS we are atop of. extension := filepath.Ext(objFile) switch extension { case @@ -142,75 +144,83 @@ func attachBitcodePathToObject(bcFile, objFile string) (success bool) { ".lo", ".os", ".So", - ".pico", //iam: pico is FreeBSD - ".po": + ".pico", //iam: pico is FreeBSD, ".pico" denotes a position-independent relocatable object. + ".nossppico", //iam: also FreeBSD, ".nossppico" denotes a position-independent relocatable object without stack smashing protection. + ".po": //iam: profiled object LogDebug("attachBitcodePathToObject recognized %v as something it can inject into.\n", extension) - // Store bitcode path to temp file - var absBcPath, _ = filepath.Abs(bcFile) - tmpContent := []byte(absBcPath + "\n") - tmpFile, err := ioutil.TempFile("", "gllvm") - if err != nil { - LogError("attachBitcodePathToObject: %v\n", err) - return - } - defer CheckDefer(func() error { return os.Remove(tmpFile.Name()) }) - if _, err := tmpFile.Write(tmpContent); err != nil { - LogError("attachBitcodePathToObject: %v\n", err) - return - } - if err := tmpFile.Close(); err != nil { - LogError("attachBitcodePathToObject: %v\n", err) - return - } - - // Let's write the bitcode section - var attachCmd string - var attachCmdArgs []string - if runtime.GOOS == osDARWIN { - if len(LLVMLd) > 0 { - attachCmd = LLVMLd - } else { - attachCmd = "ld" - } - attachCmdArgs = []string{"-r", "-keep_private_externs", objFile, "-sectcreate", DarwinSegmentName, DarwinSectionName, tmpFile.Name(), "-o", objFile} - } else { - if len(LLVMObjcopy) > 0 { - attachCmd = LLVMObjcopy - } else { - attachCmd = "objcopy" - } - attachCmdArgs = []string{"--add-section", ELFSectionName + "=" + tmpFile.Name(), objFile} - } - - // Run the attach command and ignore errors - _, nerr := execCmd(attachCmd, attachCmdArgs, "") - if nerr != nil { - LogWarning("attachBitcodePathToObject: %v %v failed because %v\n", attachCmd, attachCmdArgs, nerr) - return - } - - // Copy bitcode file to store, if necessary - if bcStorePath := LLVMBitcodeStorePath; bcStorePath != "" { - destFilePath := path.Join(bcStorePath, getHashedPath(absBcPath)) - in, _ := os.Open(absBcPath) - defer CheckDefer(func() error { return in.Close() }) - out, _ := os.Create(destFilePath) - defer CheckDefer(func() error { return out.Close() }) - _, err := io.Copy(out, in) - if err != nil { - LogWarning("Copying bc to bitcode archive %v failed because %v\n", destFilePath, err) - return - } - err = out.Sync() - if err != nil { - LogWarning("Syncing bitcode archive %v failed because %v\n", destFilePath, err) - return - } - - } + success = injectPath(extension, bcFile, objFile) default: LogWarning("attachBitcodePathToObject ignoring unrecognized extension: %v\n", extension) } + return +} + +// move this out to concentrate on the object path analysis above. +func injectPath(extension, bcFile, objFile string) (success bool) { + success = false + // Store bitcode path to temp file + var absBcPath, _ = filepath.Abs(bcFile) + tmpContent := []byte(absBcPath + "\n") + tmpFile, err := ioutil.TempFile("", "gllvm") + if err != nil { + LogError("attachBitcodePathToObject: %v\n", err) + return + } + defer CheckDefer(func() error { return os.Remove(tmpFile.Name()) }) + if _, err := tmpFile.Write(tmpContent); err != nil { + LogError("attachBitcodePathToObject: %v\n", err) + return + } + if err := tmpFile.Close(); err != nil { + LogError("attachBitcodePathToObject: %v\n", err) + return + } + + // Let's write the bitcode section + var attachCmd string + var attachCmdArgs []string + if runtime.GOOS == osDARWIN { + if len(LLVMLd) > 0 { + attachCmd = LLVMLd + } else { + attachCmd = "ld" + } + attachCmdArgs = []string{"-r", "-keep_private_externs", objFile, "-sectcreate", DarwinSegmentName, DarwinSectionName, tmpFile.Name(), "-o", objFile} + } else { + if len(LLVMObjcopy) > 0 { + attachCmd = LLVMObjcopy + } else { + attachCmd = "objcopy" + } + attachCmdArgs = []string{"--add-section", ELFSectionName + "=" + tmpFile.Name(), objFile} + } + + // Run the attach command and ignore errors + _, nerr := execCmd(attachCmd, attachCmdArgs, "") + if nerr != nil { + LogWarning("attachBitcodePathToObject: %v %v failed because %v\n", attachCmd, attachCmdArgs, nerr) + return + } + + // Copy bitcode file to store, if necessary + if bcStorePath := LLVMBitcodeStorePath; bcStorePath != "" { + destFilePath := path.Join(bcStorePath, getHashedPath(absBcPath)) + in, _ := os.Open(absBcPath) + defer CheckDefer(func() error { return in.Close() }) + out, _ := os.Create(destFilePath) + defer CheckDefer(func() error { return out.Close() }) + _, err := io.Copy(out, in) + if err != nil { + LogWarning("Copying bc to bitcode archive %v failed because %v\n", destFilePath, err) + return + } + err = out.Sync() + if err != nil { + LogWarning("Syncing bitcode archive %v failed because %v\n", destFilePath, err) + return + } + + } success = true return } diff --git a/shared/constants.go b/shared/constants.go index f2a2613..43866dc 100644 --- a/shared/constants.go +++ b/shared/constants.go @@ -59,7 +59,7 @@ package shared // 1.2.9 October 30 2020 FreeBSD bug fixes (@arrowd) (issue #41) const gllvmVersion = "1.2.9" -const gllvmReleaseDate = "October 30 13 2020" +const gllvmReleaseDate = "October 30 2020" const osDARWIN = "darwin" const osLINUX = "linux" diff --git a/shared/filetypes.go b/shared/filetypes.go index 6708ac9..0bfe79f 100644 --- a/shared/filetypes.go +++ b/shared/filetypes.go @@ -53,6 +53,9 @@ const ( fileTypeERROR ) +//iam: +// this is not that robust, because it depends on the file utility "file" which is +// often missing on docker images (the klee doker file had this problem) func getFileType(realPath string) (fileType int) { // We need the file command to guess the file type cmd := exec.Command("file", realPath) @@ -96,6 +99,5 @@ func getFileType(realPath string) (fileType int) { } else { fileType = fileTypeUNDEFINED } - return } diff --git a/shared/parser.go b/shared/parser.go index 5b2ddbe..930d8ad 100644 --- a/shared/parser.go +++ b/shared/parser.go @@ -397,7 +397,7 @@ func Parse(argList []string) ParserResult { //iam: it's a bit fragile as to what we recognize as an object file. // this also shows up in the compile function attachBitcodePathToObject, so additions // here, should also be additions there. - {`^.+\.(o|lo|So|so|po|a|dylib|pico)$`, flagInfo{0, pr.objectFileCallback}}, //iam: pico is FreeBSD + {`^.+\.(o|lo|So|so|po|a|dylib|pico|nossppico)$`, flagInfo{0, pr.objectFileCallback}}, //iam: pico and nossppico are FreeBSD {`^.+\.dylib(\.\d)+$`, flagInfo{0, pr.objectFileCallback}}, {`^.+\.(So|so)(\.\d)+$`, flagInfo{0, pr.objectFileCallback}}, }