Skip to content

Commit aee7d3f

Browse files
committed
ci: add lint to forbid the usage of os.Create
os.Create is shorthand for open(O_CREAT|O_TRUNC) *without* O_EXCL, which is incredibly unsafe for us to do when interacting with a container rootfs (especially before pivot_root) as an attacker could swap the target path with a symlink that points to the host filesystem, causing us to delete the contents of or create host files. We did have a similar bug in CVE-2024-45310, but in that case we (luckily) didn't have O_TRUNC set which avoided the worst possible case. However, os.Create does set O_TRUNC and we were using it in scenarios that may have been exploitable. Because of how easy it us for us to accidentally introduce this kind of bug, we should simply not allow the usage of os.Create in our entire codebase. Signed-off-by: Aleksa Sarai <[email protected]>
1 parent 01de9d6 commit aee7d3f

File tree

2 files changed

+16
-1
lines changed

2 files changed

+16
-1
lines changed

.golangci.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ formatters:
1111
linters:
1212
enable:
1313
- errorlint
14+
- forbidigo
1415
- nolintlint
1516
- unconvert
1617
- unparam
@@ -25,6 +26,20 @@ linters:
2526
- -ST1003 # https://staticcheck.dev/docs/checks/#ST1003 Poorly chosen identifier.
2627
- -ST1005 # https://staticcheck.dev/docs/checks/#ST1005 Incorrectly formatted error string.
2728
- -QF1008 # https://staticcheck.dev/docs/checks/#QF1008 Omit embedded fields from selector expression.
29+
forbidigo:
30+
forbid:
31+
# os.Create implies O_TRUNC without O_CREAT|O_EXCL, which can lead to
32+
# an even more severe attacks than CVE-2024-45310, where host files
33+
# could be wiped. Always use O_EXCL or otherwise ensure we are not
34+
# going to be tricked into overwriting host files.
35+
- pattern: ^os\.Create$
36+
pkg: ^os$
37+
analyze-types: true
2838
exclusions:
39+
rules:
40+
# forbidigo lints are only relevant for main code.
41+
- path: '(.+)_test\.go'
42+
linters:
43+
- forbidigo
2944
presets:
3045
- std-error-handling

libcontainer/criu_linux.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1090,7 +1090,7 @@ func (c *Container) criuNotifications(resp *criurpc.CriuResp, process *Process,
10901090
logrus.Debugf("notify: %s\n", script)
10911091
switch script {
10921092
case "post-dump":
1093-
f, err := os.Create(filepath.Join(c.stateDir, "checkpoint"))
1093+
f, err := os.Create(filepath.Join(c.stateDir, "checkpoint")) //nolint:forbidigo // this is a host-side operation in a runc-controlled directory
10941094
if err != nil {
10951095
return err
10961096
}

0 commit comments

Comments
 (0)