Another freeBSD file extension: nossppico (a position-independent relocatable object without stack smashing protection)

This commit is contained in:
Ian A Mason 2020-10-30 18:39:44 +00:00
parent 405cd117c3
commit 9f0092874f
4 changed files with 80 additions and 68 deletions

View File

@ -133,8 +133,10 @@ func buildAndAttachBitcode(compilerExecName string, pr ParserResult, bcObjLinks
} }
func attachBitcodePathToObject(bcFile, objFile string) (success bool) { func attachBitcodePathToObject(bcFile, objFile string) (success bool) {
success = false
// We can only attach a bitcode path to certain file types // 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. // 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) extension := filepath.Ext(objFile)
switch extension { switch extension {
case case
@ -142,75 +144,83 @@ func attachBitcodePathToObject(bcFile, objFile string) (success bool) {
".lo", ".lo",
".os", ".os",
".So", ".So",
".pico", //iam: pico is FreeBSD ".pico", //iam: pico is FreeBSD, ".pico" denotes a position-independent relocatable object.
".po": ".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) LogDebug("attachBitcodePathToObject recognized %v as something it can inject into.\n", extension)
// Store bitcode path to temp file success = injectPath(extension, bcFile, objFile)
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
}
}
default: default:
LogWarning("attachBitcodePathToObject ignoring unrecognized extension: %v\n", extension) 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 success = true
return return
} }

View File

@ -59,7 +59,7 @@ package shared
// 1.2.9 October 30 2020 FreeBSD bug fixes (@arrowd) (issue #41) // 1.2.9 October 30 2020 FreeBSD bug fixes (@arrowd) (issue #41)
const gllvmVersion = "1.2.9" const gllvmVersion = "1.2.9"
const gllvmReleaseDate = "October 30 13 2020" const gllvmReleaseDate = "October 30 2020"
const osDARWIN = "darwin" const osDARWIN = "darwin"
const osLINUX = "linux" const osLINUX = "linux"

View File

@ -53,6 +53,9 @@ const (
fileTypeERROR 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) { func getFileType(realPath string) (fileType int) {
// We need the file command to guess the file type // We need the file command to guess the file type
cmd := exec.Command("file", realPath) cmd := exec.Command("file", realPath)
@ -96,6 +99,5 @@ func getFileType(realPath string) (fileType int) {
} else { } else {
fileType = fileTypeUNDEFINED fileType = fileTypeUNDEFINED
} }
return return
} }

View File

@ -397,7 +397,7 @@ func Parse(argList []string) ParserResult {
//iam: it's a bit fragile as to what we recognize as an object file. //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 // this also shows up in the compile function attachBitcodePathToObject, so additions
// here, should also be additions there. // 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}}, {`^.+\.dylib(\.\d)+$`, flagInfo{0, pr.objectFileCallback}},
{`^.+\.(So|so)(\.\d)+$`, flagInfo{0, pr.objectFileCallback}}, {`^.+\.(So|so)(\.\d)+$`, flagInfo{0, pr.objectFileCallback}},
} }