Page MenuHomeFreeBSD

lindebugfs: Don't pass a kernel pointer to copy_from_user
AbandonedPublic

Authored by jhb on Mar 11 2026, 7:15 PM.
Tags
None
Referenced Files
Unknown Object (File)
Sat, Apr 18, 7:20 AM
Unknown Object (File)
Sat, Apr 18, 5:05 AM
Unknown Object (File)
Sat, Apr 18, 3:44 AM
Unknown Object (File)
Fri, Apr 17, 7:29 PM
Unknown Object (File)
Wed, Apr 15, 10:56 PM
Unknown Object (File)
Tue, Apr 14, 11:53 AM
Unknown Object (File)
Sat, Apr 11, 8:03 PM
Unknown Object (File)
Mon, Mar 30, 1:28 PM
Subscribers

Details

Reviewers
bz
emaste
dumbbell
Group Reviewers
cheri
linuxkpi
Summary

lindebugfs doesn't actually pass user pointers to the LinuxKPI
file_operations read/write methods as pseudofs uses in-kernel buffers
for VOP_READ and VOP_WRITE. simple_read_from_buffer() (used in
fops_str_read) already accounts for this by using memcpy() instead of
copy_to_user(). Make the same change in fops_str_write by using
memcpy() instead of copy_from_user().

Obtained from: CheriBSD
Fixes: 78e25e65bf38 ("lindebugfs: Add debugfs_create_str()")
Sponsored by: AFRL, DARPA

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped
Build Status
Buildable 71347
Build 68230: arc lint + arc unit

Event Timeline

jhb requested review of this revision.Mar 11 2026, 7:15 PM
jrtc27 added inline comments.
sys/compat/lindebugfs/lindebugfs.c
706

?

706

But also, is this not a bug in pseudofs? file_operations's function pointers still have __user annotations on them, and the whole point of linuxkpi is to be Linux's KPI, which this is not.

bz added inline comments.
sys/compat/lindebugfs/lindebugfs.c
706

I would assume the problem stems from debugfs_fill() then but I just woke up and didn't dive into this. So if you argue that the source of the problem should be fixed instead of working around it, this may be quite a bit more work.

sys/compat/lindebugfs/lindebugfs.c
706

This is quite hard to fix. FreeBSD doesn't pass user pointers down to VOPs, we pass struct uio structures that are iovecs that are accessed via uiomove. If we wanted to pass the "user" pointer all the way down to struct file_operations we would need to instead pass down the struct uio in place of the char * __user ubuf, then debugfs_fill could just pass that down directly. Looks like debugs_fill has a bug btw in that it doesn't honor uio_offset since it always sets off to 0.

You could perhaps "fix" debugfs_fill to iterate over the uio passing down each iovec entry one at a time. You have to set the PFS_RAWRD and PFS_RAWWR flags, but then we would avoid all the sbuf stuff and could just do direct user I/O.

We have some other hacks already in CheriBSD because of this kernel vs user mismatch that are all due to debugfs, so perhaps it might indeed be better to fix debugfs. I can take a stab at that I guess. Blech.

See comment about why I accepted this.

sys/compat/lindebugfs/lindebugfs.c
706

Thanks for the details.

In case you want to get this in in the mean time, maybe referring to this review about the more general problem, I'll accept it, given 5668c22a13c6b was me.

This revision is now accepted and ready to land.Mar 12 2026, 3:57 PM

Going to fix this the right way.