Possible memory leak in mount on OpenBSD: C strings passed to mount(2) are never freed
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 62/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Domain
- operating-systems
Research direction
Start in mount/mounter_openbsd.go: read createUfsArgs (around line 42) and the mount function that calls C.mount (around line 66), then compare with the defer C.free pattern in mounter_freebsd.go (lines 46-49). Done when each C.CString allocation is freed and the cgo preamble includes stdlib.h. The OpenBSD build can't be run locally, so check that the file still compiles for the openbsd target with cgo.
Written by the indexing model from the issue text.
Description
On OpenBSD with cgo, every mount.Mount(..., "ffs", ...) call allocates three C strings that are never freed: fspec: C.CString(device) in createUfsArgs (mount/mounter_openbsd.go:42), and C.CString(mType) / C.CString(target) passed inline to C.mount (:66). mount(2) copies its arguments, so they can be freed right after the call; mounter_freebsd.go:46-49 already does this with defer C.free.
Details
Commit: 0922b4fee15d (//go:build openbsd && cgo). The file has no C.free and does not include <stdlib.h>. The leak is on both the success and the error path, len(device)+len(target)+6 bytes per call.
I don't have an OpenBSD machine. I copied createExportInfo, createUfsArgs and mount verbatim into a small program with a stub mount() that copies its string arguments and keeps nothing, and measured on macOS:
100,000 calls, current code: +4,800,448 bytes (48 bytes per call)
100,000 calls, with the change below: +0 bytes
With device="/dev/sd0a" and target="/mnt/data" the three strings are 24 bytes; the allocator reports 48 bytes per call because each small allocation is rounded up to 16 bytes.
Possible change in mount(), replacing the createUfsArgs call (and adding #include <stdlib.h> to the existing cgo preamble):
cdev := C.CString(device)
defer C.free(unsafe.Pointer(cdev))
args := C.struct_ufs_args{fspec: cdev, export_info: createExportInfo(readOnly)}
ctype := C.CString(mType)
defer C.free(unsafe.Pointer(ctype))
ctarget := C.CString(target)
defer C.free(unsafe.Pointer(ctarget))
if errno := C.mount(ctype, ctarget, C.int(flag), unsafe.Pointer(&args)); errno != 0 {
Separately (not part of this issue): :66 treats the return value of mount as an errno. mount(2) returns -1 and sets errno, so the error currently reads "errno -1" instead of the real error. mounter_freebsd.go does the same with nmount. Happy to open a separate issue for that if useful.
AI disclosure: I found and analysed this with AI assistance (Claude); the reproduction above was run, and I reviewed and edited this report before posting.
If you could credit me as a reporter for my contributions to security advisory I will be thankful.
- Dominant language
- Go
- Stars
- 102
- Forks
- 62
- Avg merge
- 6m
- Merged PRs (30d)
- 2
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from moby/sys
-
devices: ignore .incus-mounts in GetDevicesPossibly taken @SashaMIT claimed this 7 days ago. Open
Difficulty 1/5 Under an hour Newbie friendliness 88/100
-
[userns-remap] Bug: ToHost incorrectly maps non-root container UID to root when it collides with RootPairPossibly taken @okhowang claimed this 73 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
-
Difficulty 3/5 1-2 days Newbie friendliness 50/100
-
Difficulty 3/5 1-2 days Newbie friendliness 74/100
-
Difficulty 3/5 1-2 days Newbie friendliness 68/100
Similar issues
-
bug frontend grammar sev-3
Difficulty 2/5 1-3 hours Newbie friendliness 63/100
-
connector docs good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
soma-intelligence/open-health-sync#134 ·
Maintainers usually reply within 1 day
-
bug frontend
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Maintainers usually reply within 3 days
-
Difficulty 1/5 Under an hour Newbie friendliness 72/100
Maintainers usually reply within 1 day
-
oss/0 pending team/container-integrations
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
DataDog/datadog-agent#58323 ·
Maintainers usually reply within 1 day