Skip to content

Commit a0b7ae1

Browse files
committed
pkg/sca/sca.go: Implement getLdSoConfDLibPaths
This commit implements the machinery necessary for SCA to consider files under /etc/ld.so.conf.d/. The idea is that, if there is a configuration for ld.so.conf.d being installed by the package on hand, then the libraries shipped by the package should be listed as "provides" if they're installed inside the paths listed in the ld.so.conf.d configuration file. This commit also implements a simple test to make sure that the new function is properly parsing the configuration file inside /etc/ld.so.conf.d/. Signed-off-by: Sergio Durigan Junior <sergiodj@chainguard.dev>
1 parent d53f720 commit a0b7ae1

File tree

4 files changed

+137
-0
lines changed

4 files changed

+137
-0
lines changed

pkg/sca/sca.go

+94
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package sca
1616

1717
import (
18+
"bufio"
1819
"bytes"
1920
"context"
2021
"debug/buildinfo"
@@ -86,6 +87,84 @@ func isInDir(path string, dirs []string) bool {
8687
return false
8788
}
8889

90+
// getLdSoConfDLibPaths will iterate over the files being installed by
91+
// the package and all its subpackages, and for each configuration
92+
// file found under /etc/ld.so.conf.d/ it will parse the file and add
93+
// its contents to a string vector. This vector will ultimately
94+
// contain all extra paths that will be considered by ld when doing
95+
// symbol resolution.
96+
func getLdSoConfDLibPaths(ctx context.Context, hdl SCAHandle) ([]string, error) {
97+
var extraLibPaths []string
98+
targetPackageNames := hdl.RelativeNames()
99+
100+
log := clog.FromContext(ctx)
101+
102+
log.Info("scanning for ld.so.conf.d files...")
103+
104+
for _, pkgName := range targetPackageNames {
105+
fsys, err := hdl.FilesystemForRelative(pkgName)
106+
if err != nil {
107+
return nil, err
108+
}
109+
110+
if err := fs.WalkDir(fsys, ".", func(path string, d fs.DirEntry, err error) error {
111+
if err != nil {
112+
return err
113+
}
114+
115+
// We're only interested in files inside /etc/ld.so.conf.d/...
116+
if !isInDir(path, []string{"etc/ld.so.conf.d"}) {
117+
return nil
118+
}
119+
120+
// ... and whose suffix is ".conf"...
121+
if !strings.HasSuffix(path, ".conf") {
122+
return nil
123+
}
124+
125+
fi, err := d.Info()
126+
if err != nil {
127+
return err
128+
}
129+
130+
if !fi.Mode().IsRegular() {
131+
return nil
132+
}
133+
134+
log.Infof(" found ld.so.conf.d file %s", path)
135+
136+
fd, err := fsys.Open(path)
137+
if err != nil {
138+
return err
139+
}
140+
defer fd.Close()
141+
142+
scanner := bufio.NewScanner(fd)
143+
for scanner.Scan() {
144+
line := scanner.Text()
145+
if line[0] != '/' {
146+
continue
147+
}
148+
// Strip the initial slash since
149+
// libDirs paths need to be relative.
150+
line = line[1:]
151+
log.Infof(" found extra lib path %s", line)
152+
extraLibPaths = append(extraLibPaths, line)
153+
}
154+
155+
if err := scanner.Err(); err != nil {
156+
return err
157+
}
158+
159+
return nil
160+
}); err != nil {
161+
return nil, err
162+
}
163+
}
164+
165+
return extraLibPaths, nil
166+
}
167+
89168
func generateCmdProviders(ctx context.Context, hdl SCAHandle, generated *config.Dependencies) error {
90169
log := clog.FromContext(ctx)
91170

@@ -766,6 +845,17 @@ func generateShbangDeps(ctx context.Context, hdl SCAHandle, generated *config.De
766845
// Analyze runs the SCA analyzers on a given SCA handle, modifying the generated dependencies
767846
// set as needed.
768847
func Analyze(ctx context.Context, hdl SCAHandle, generated *config.Dependencies) error {
848+
var oldLibDirs []string
849+
850+
extraLibPaths, err := getLdSoConfDLibPaths(ctx, hdl)
851+
if err != nil {
852+
return err
853+
}
854+
if extraLibPaths != nil {
855+
oldLibDirs = libDirs
856+
libDirs = append(libDirs, extraLibPaths...)
857+
}
858+
769859
generators := []DependencyGenerator{
770860
generateSharedObjectNameDeps,
771861
generateCmdProviders,
@@ -804,5 +894,9 @@ func Analyze(ctx context.Context, hdl SCAHandle, generated *config.Dependencies)
804894
generated.Provides = nil
805895
}
806896

897+
if oldLibDirs != nil {
898+
libDirs = oldLibDirs
899+
}
900+
807901
return nil
808902
}

pkg/sca/sca_test.go

+18
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
//go:generate go run ./../../ build --generate-index=false --out-dir=./testdata/generated ./testdata/ld-so-conf-d-test.yaml --arch=x86_64
1516
//go:generate go run ./../../ build --generate-index=false --out-dir=./testdata/generated ./testdata/shbang-test.yaml --arch=x86_64
1617
//go:generate go run ./../../ build --generate-index=false --source-dir=./testdata/go-fips-bin/ --out-dir=./testdata/generated ./testdata/go-fips-bin/go-fips-bin.yaml --arch=x86_64
1718
//go:generate curl -s -o ./testdata/py3-seaborn.yaml https://raw.githubusercontent.com/wolfi-dev/os/7a39ac1d0603a3561790ea2201dd8ad7c2b7e51e/py3-seaborn.yaml
@@ -337,3 +338,20 @@ func TestGetShbang(t *testing.T) {
337338
}
338339
}
339340
}
341+
342+
func TestLdSoConfD(t *testing.T) {
343+
ctx := slogtest.Context(t)
344+
// Generated with `go generate ./...`
345+
th := handleFromApk(ctx, t, "generated/x86_64/ld-so-conf-d-test-1-r1.apk", "ld-so-conf-d-test.yaml")
346+
defer th.exp.Close()
347+
348+
if extraLibPaths, err := getLdSoConfDLibPaths(ctx, th); err != nil {
349+
t.Fatal(err)
350+
} else if extraLibPaths == nil {
351+
t.Error("getLdSoConfDLibPaths: expected 'my/lib/test', got nil")
352+
} else {
353+
if extraLibPaths[0] != "my/lib/test" {
354+
t.Errorf("getLdSoConfDLibPaths: expected 'my/lib/test', got '%s'", extraLibPaths[0])
355+
}
356+
}
357+
}
Binary file not shown.
+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package:
2+
name: ld-so-conf-d-test
3+
version: 1
4+
epoch: 1
5+
description: ld.so.conf.d test
6+
copyright:
7+
- license: MIT
8+
9+
environment:
10+
contents:
11+
repositories:
12+
- https://packages.wolfi.dev/os
13+
keyring:
14+
- https://packages.wolfi.dev/os/wolfi-signing.rsa.pub
15+
packages:
16+
- build-base
17+
- busybox
18+
19+
pipeline:
20+
- runs: |
21+
mkdir -p "${{targets.destdir}}"/etc/ld.so.conf.d
22+
echo "/my/lib/test" > "${{targets.destdir}}"/etc/ld.so.conf.d/ld-so-conf-d-test.conf
23+
24+
update:
25+
enabled: false

0 commit comments

Comments
 (0)