Skip to content

Commit dabc526

Browse files
authored
Merge pull request #2 from thediveo/develop
Develop
2 parents 2bf6eae + 1c434d4 commit dabc526

21 files changed

+641
-222
lines changed

.github/workflows/buildandtest.yaml

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@ name: build and test
22
on:
33
push:
44
branches:
5-
- master
5+
- master
6+
pull_request:
7+
branches:
8+
- master
9+
- develop
610

711
jobs:
812

@@ -11,18 +15,17 @@ jobs:
1115
runs-on: ubuntu-latest
1216
strategy:
1317
matrix:
14-
go: [ '1.19', '1.20' ]
18+
go: [ 'stable', 'oldstable' ]
1519
steps:
1620

1721
- name: Set up Go ${{matrix.go}}
18-
uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # pin@v3
22+
uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # pin@v4
1923
with:
2024
go-version: ${{matrix.go}}
2125
id: go
2226

2327
- name: Check out code into the Go module directory
24-
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # pin@v3
28+
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # pin@v4
2529

2630
- name: Test
2731
run: go test -v -p=1 -race ./...
28-
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: 'CodeQL'
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
schedule:
9+
- cron: '02 42 * * 1'
10+
11+
jobs:
12+
analyze:
13+
name: Analyze
14+
runs-on: ubuntu-latest
15+
16+
permissions:
17+
actions: read # for github/codeql-action/init to get workflow details
18+
contents: read # for actions/checkout to fetch code
19+
security-events: write # for github/codeql-action/analyze to upload SARIF results
20+
21+
strategy:
22+
fail-fast: false
23+
matrix:
24+
language: [ 'go' ]
25+
26+
steps:
27+
- name: Checkout repository
28+
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # pin@v4
29+
30+
- name: Initialize CodeQL
31+
uses: github/codeql-action/init@0116bc2df50751f9724a2e35ef1f24d22f90e4e1 # pin@v2
32+
with:
33+
languages: ${{ matrix.language }}
34+
35+
- name: Autobuild
36+
uses: github/codeql-action/autobuild@0116bc2df50751f9724a2e35ef1f24d22f90e4e1 # pin@v2
37+
38+
- name: Perform CodeQL Analysis
39+
uses: github/codeql-action/analyze@0116bc2df50751f9724a2e35ef1f24d22f90e4e1 # pin@v2

.github/workflows/codeql-analysis.yml

Lines changed: 0 additions & 67 deletions
This file was deleted.

Makefile

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.PHONY: help clean pkgsite report test
1+
.PHONY: help clean coverage pkgsite report test vuln grype
22

33
help: ## list available targets
44
@# Shamelessly stolen from Gomega's Makefile
@@ -18,4 +18,10 @@ report: ## run goreportcard on this module
1818
@scripts/goreportcard.sh
1919

2020
test: ## run unit tests
21-
go test -v -p=1 -race ./...
21+
go test -v -count=1 -p=1 -race ./...
22+
23+
vuln: ## run go vulnerabilities check
24+
@scripts/vuln.sh
25+
26+
grype: ## run grype vul scan on sources
27+
@scripts/grype.sh

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
[![GitHub](https://img.shields.io/github/license/thediveo/procfsroot)](https://img.shields.io/github/license/thediveo/procfsroot)
55
![build and test](https://github.com/thediveo/procfsroot/workflows/build%20and%20test/badge.svg?branch=master)
66
[![Go Report Card](https://goreportcard.com/badge/github.com/thediveo/procfsroot)](https://goreportcard.com/report/github.com/thediveo/procfsroot)
7-
![Coverage](https://img.shields.io/badge/Coverage-96.8%25-brightgreen)
7+
![Coverage](https://img.shields.io/badge/Coverage-96.9%25-brightgreen)
88

99
`procfsroot` is a small Go module that helps with accessing file system paths
1010
containing absolute symbolic links that are to be taken relative (sic!) to a

doc.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
/*
2-
32
Package procfsroot helps with accessing file system paths containing absolute
43
symbolic links that are to be taken relative (sic!) to a particular root path.
54
65
A typical use case is accessing paths inside /proc/[PID]/root "wormholes" in the
76
proc file system. Symbolic links are properly resolved and kept inside a given
87
root path, prohibiting rogue relative symbolic links from breaking out of, for
98
example, a procfs /proc/[PID]/root "wormhole".
10-
119
*/
1210
package procfsroot

evalsymlink.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ package procfsroot
1616

1717
import (
1818
"errors"
19-
"os"
19+
"io/fs"
2020
"path"
2121
"syscall"
2222
)
@@ -117,12 +117,11 @@ func EvalSymlinks(abspath, root string, pathhandling EvalSymlinkPathHandling) (s
117117
break
118118
}
119119
wormpath := root + dest
120-
stat, err := os.Lstat(wormpath)
120+
stat, err := slinker.Lstat(wormpath)
121121
if err != nil {
122122
return "", err
123123
}
124-
// For compatibility with pre-1.16 use "os" instead of "fs"
125-
if stat.Mode()&os.ModeSymlink == 0 {
124+
if stat.Mode()&fs.ModeSymlink == 0 {
126125
// Phew, ain't no symlink, so to ensure that -- with the exception
127126
// of the final component -- all other components are directories,
128127
// we check this path component if necessary.
@@ -138,7 +137,7 @@ func EvalSymlinks(abspath, root string, pathhandling EvalSymlinkPathHandling) (s
138137
if jumps > 255 {
139138
return "", errors.New("procfsroot.EvalSymlinks: too many symlinks")
140139
}
141-
link, err := os.Readlink(wormpath)
140+
link, err := slinker.Readlink(wormpath)
142141
if err != nil {
143142
return "", err
144143
}

evalsymlink_test.go

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,62 @@
1515
package procfsroot
1616

1717
import (
18+
"os"
1819
"strings"
1920

21+
"github.com/spf13/afero"
22+
2023
. "github.com/onsi/ginkgo/v2"
2124
. "github.com/onsi/gomega"
25+
. "github.com/thediveo/success"
2226
)
2327

24-
const fsroot = "./test/root"
28+
const fsroot = "/root" // ...somewhere inside our temporary testing directory
29+
30+
func createFile(fs afero.Fs, name string, contents string) {
31+
GinkgoHelper()
32+
f := Successful(fs.Create(name))
33+
defer f.Close()
34+
Expect(f.WriteString(contents)).Error().NotTo(HaveOccurred())
35+
}
36+
37+
var _ = Describe("evil symlink chasing", Ordered, func() {
38+
39+
BeforeAll(func() {
40+
oldslinker := slinker
41+
DeferCleanup(func() { slinker = oldslinker })
42+
43+
tmpDir := Successful(os.MkdirTemp("", "test-evilsymlink-"))
44+
DeferCleanup(func() {
45+
Expect(os.RemoveAll(tmpDir)).To(Succeed())
46+
})
47+
48+
testfs := afero.NewBasePathFs(afero.NewOsFs(), tmpDir)
49+
slinker = &aferoSymlinker{testfs}
50+
51+
createFile(testfs, "/outofreach.txt", "This file must off-limits for symlinks inside /root")
52+
53+
Expect(testfs.MkdirAll(fsroot+"/a", 0770)).To(Succeed())
54+
createFile(testfs, fsroot+"/a/b.txt", "just some text")
55+
Expect(testfs.MkdirAll(fsroot+"/a/d", 0770)).To(Succeed())
56+
createFile(testfs, fsroot+"/a/d/dummy.txt", "better than .gitkeep")
2557

26-
var _ = Describe("evil symlink chasing", func() {
58+
// Hack around afero.BasePathFs trying to make relative symlinks
59+
// absolute ... something we absolutely don't need here.
60+
Expect(os.Symlink("a/b.txt",
61+
Successful(testfs.(*afero.BasePathFs).RealPath(fsroot+"/relsymlink")))).
62+
To(Succeed())
63+
64+
Expect(testfs.MkdirAll(fsroot+"/unrooter", 0770)).To(Succeed())
65+
Expect(os.Symlink("../../outofreach.txt",
66+
Successful(testfs.(*afero.BasePathFs).RealPath(fsroot+"/unrooter/tryingtoleavethebox")))).
67+
To(Succeed())
68+
69+
Expect(testfs.MkdirAll("/proc/self", 0770)).To(Succeed())
70+
Expect(os.Symlink("../..",
71+
Successful(testfs.(*afero.BasePathFs).RealPath("/proc/self/root")))).
72+
To(Succeed())
73+
})
2774

2875
It("handles simple paths", func() {
2976
p, err := EvalSymlinks("/a/b.txt", fsroot, EvalFullPath)
@@ -85,13 +132,6 @@ var _ = Describe("evil symlink chasing", func() {
85132
p, err := EvalSymlinks("/relsymlink", fsroot, EvalFullPath)
86133
Expect(err).NotTo(HaveOccurred())
87134
Expect(p).To(Equal("/a/b.txt"))
88-
89-
p, err = EvalSymlinks("/var/run", "/", EvalFullPath)
90-
Expect(err).NotTo(HaveOccurred())
91-
Expect(p).To(Equal("/run"))
92-
93-
Expect(EvalSymlinks("/proc/foobar1/root", "/", EvalFullPath)).
94-
Error().To(HaveOccurred())
95135
})
96136

97137
It("stays inside the wormhole", func() {

go.mod

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,23 @@
11
module github.com/thediveo/procfsroot
22

3-
go 1.16
3+
go 1.19
4+
5+
require golang.org/x/net v0.17.0 // indirect
6+
7+
require (
8+
github.com/onsi/ginkgo/v2 v2.13.0
9+
github.com/onsi/gomega v1.28.0
10+
github.com/thediveo/success v1.0.1
11+
)
412

513
require (
6-
github.com/onsi/ginkgo v1.16.5 // indirect
7-
github.com/onsi/ginkgo/v2 v2.9.0
8-
github.com/onsi/gomega v1.27.3
14+
github.com/go-logr/logr v1.2.4 // indirect
15+
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
16+
github.com/google/go-cmp v0.5.9 // indirect
17+
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
18+
github.com/spf13/afero v1.10.0
19+
golang.org/x/sys v0.13.0 // indirect
20+
golang.org/x/text v0.13.0 // indirect
21+
golang.org/x/tools v0.12.0 // indirect
22+
gopkg.in/yaml.v3 v3.0.1 // indirect
923
)

0 commit comments

Comments
 (0)