Ophestra Umiker
6232291cae
Fortify needs to internally resolve helper program sandbox config. They are considered trusted and runs under the privileged UID so ldd output is used to determine libraries they need inside the sandbox environment. Signed-off-by: Ophestra Umiker <cat@ophivana.moe>
85 lines
1.7 KiB
Go
85 lines
1.7 KiB
Go
package ldd
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"math"
|
|
"os"
|
|
"os/exec"
|
|
"path"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
var (
|
|
ErrUnexpectedSeparator = errors.New("unexpected separator")
|
|
ErrPathNotAbsolute = errors.New("path not absolute")
|
|
ErrBadLocationFormat = errors.New("bad location format")
|
|
)
|
|
|
|
type Entry struct {
|
|
Name string `json:"name,omitempty"`
|
|
Path string `json:"path,omitempty"`
|
|
Location uint64 `json:"location"`
|
|
}
|
|
|
|
func Exec(p string) ([]*Entry, error) {
|
|
t := exec.Command("ldd", p)
|
|
t.Stdout = new(strings.Builder)
|
|
t.Stderr = os.Stderr
|
|
|
|
if err := t.Run(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
out := t.Stdout.(fmt.Stringer).String()
|
|
payload := strings.Split(out, "\n")
|
|
|
|
result := make([]*Entry, len(payload))
|
|
|
|
for i, ent := range payload {
|
|
if len(ent) == 0 {
|
|
continue
|
|
}
|
|
|
|
segment := strings.SplitN(ent, " ", 5)
|
|
|
|
var iL int
|
|
|
|
switch len(segment) {
|
|
case 2: // /lib/ld-musl-x86_64.so.1 (0x7f04d14ef000)
|
|
iL = 1
|
|
result[i] = &Entry{Name: segment[0]}
|
|
case 4: // libc.musl-x86_64.so.1 => /lib/ld-musl-x86_64.so.1 (0x7f04d14ef000)
|
|
iL = 3
|
|
if segment[1] != "=>" {
|
|
return nil, ErrUnexpectedSeparator
|
|
}
|
|
if !path.IsAbs(segment[2]) {
|
|
return nil, ErrPathNotAbsolute
|
|
}
|
|
result[i] = &Entry{
|
|
Name: segment[0],
|
|
Path: segment[2],
|
|
}
|
|
default:
|
|
return nil, &EntryUnexpectedSegmentsError{ent}
|
|
}
|
|
|
|
if loc, err := parseLocation(segment[iL]); err != nil {
|
|
return nil, err
|
|
} else {
|
|
result[i].Location = loc
|
|
}
|
|
}
|
|
|
|
return result, nil
|
|
}
|
|
|
|
func parseLocation(s string) (uint64, error) {
|
|
if len(s) < 4 || s[len(s)-1] != ')' || s[:3] != "(0x" {
|
|
return math.MaxUint64, ErrBadLocationFormat
|
|
}
|
|
return strconv.ParseUint(s[3:len(s)-1], 16, 64)
|
|
}
|