Page MenuHomeFreeBSD

geom: Check file flags before handling control request
Needs ReviewPublic

Authored by des on Fri, Sep 11, 2:51 PM.
Tags
None
Referenced Files
Unknown Object (File)
Wed, Sep 30, 6:25 AM
Unknown Object (File)
Mon, Sep 28, 1:56 PM
Unknown Object (File)
Mon, Sep 28, 1:54 PM
Unknown Object (File)
Mon, Sep 28, 10:57 AM
Unknown Object (File)
Mon, Sep 28, 10:14 AM
Unknown Object (File)
Sun, Sep 27, 7:02 PM
Unknown Object (File)
Sun, Sep 27, 6:01 PM
Unknown Object (File)
Sun, Sep 27, 12:14 PM
Subscribers

Details

Reviewers
kevans
markj
phk
mav
glebius
imp
Group Reviewers
geom
Summary

Pass fflag down to g_ctl_req() and:

  • Refuse all requests unless fflag has the FREAD bit set
  • Refuse all but getxml unless fflag also has the FWRITE bit set

This should allow us to restore read access to /dev/geom.ctl for group
operator; they will then be able to run gpart list or gpart backup
but not commands that actually modify the table.

For backward compatibility, we set the FWRITE bit if it is not already
set and the calling thread has the PRIV_GEOM privilege, which is
automatically granted to a jailed or unjailed superuser. This should
cover the case of older binaries (which open /dev/geom.ctl read-only)
running as root on a newer kernel. Since we intend to merge this to
stable/15, the compatibility code is conditional on COMPAT_FREEBSD14.

MFC after: 1 week
Event: EuroBSDCon 2026 DevSummit

Diff Detail

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

Event Timeline

des requested review of this revision.Fri, Sep 11, 2:51 PM
This revision is now accepted and ready to land.Fri, Sep 11, 4:35 PM
This revision now requires review to proceed.Sat, Sep 12, 12:39 PM
sys/geom/geom_ctl.c
658

Is PRIV_IO the right privilege to check here or should we create a new PRIV_GEOM?

The change seems right to me, but I am not an expert in the area.

sys/geom/geom_ctl.c
663

Is the void * cast needed at all?

sys/geom/geom_ctl.c
663

data is a caddr_t which is currently a char * but might be uintptr_t in the future (and in fact _is_ uintptr_t in some downstream projects).

des marked an inline comment as done.Sat, Sep 12, 1:51 PM

I did a cursory pass over verbs in base to see if we /might/ want to expand this to others / pass it through to mp->ctlreq, but it doesn't seem very likely except maybe in getactive?

sys/geom/geom_ctl.c
658

Looking at current uses of PRIV_IO, yeah- we should break this out into its own PRIV_GEOM (or PRIV_GEOM_CTL, but I guess I can't imagine what another GEOM' privilege might look like) -- I can easily see one wanting to regain geom ctl with something like MAC, and PRIV_IO includes scary looking things like io(4).

658

We also discussed in person ensuring that we don't grant the new priv(9) to jails by default, but with special consideration for COMPAT_FREEBSD14 vs. not

Add PRIV_GEOM; note that the commit message now needs work.

sys/geom/geom_ctl.c
663

But the g_ctl_ioctl_ctl() is void *. Isn't it possible to pass anything there?

des marked an inline comment as done.Sun, Sep 13, 12:10 PM
des added inline comments.
sys/geom/geom_ctl.c
663

A char * yes, but not uintptr_t.

Note that the cast was already here, I just moved it one level out.

des marked an inline comment as done.
sys/geom/geom_ctl.c
575

gctl_error() sets req->nerror = EINVAL if it's not already set. Don't we want to return EACCES?

sys/geom/geom_ctl.c
575

It should probably be EPERM rather than EACCES, no?

des edited the summary of this revision. (Show Details)

EPERM

des marked an inline comment as done.Fri, Sep 25, 10:55 AM
sys/geom/geom_ctl.c
575

I guess so, but the error string you're using with gctl_error() corresponds to EACCES, not EPERM ("Operation not permitted").

658

So one thing I could do before is create an md device in a jail, and then create a GEOM on top of that. Now that's no longer possible.

It's not obvious to me that that's the right behaviour: if the jail admin decided to expose /dev/geom.ctl to a jail, shouldn't it be usable?

sys/geom/geom_ctl.c
667

Thinking about this more (albeit without any coffee yet), I don't understand the purpose of the priv_check() here. Shouldn't write access to /dev/geom.ctl be sufficient to grant this privilege?

des marked 5 inline comments as done.Fri, Sep 25, 2:01 PM
des added inline comments.
sys/geom/geom_ctl.c
658

oh yeah I guess we have quite a few tests that do exactly this and would stop working if we don't grant a jailed superuser write access.

667

What we are doing here is the historical behavior of allowing configuration changes regardless of write access to the control node, but only for the superuser, not for e.g. members of group operator.

des marked 2 inline comments as done.

rf

des added inline comments.
sys/geom/geom_ctl.c
667

Oh sorry I thought you were replying to the similar line a few lines up. The purpose of this line is to allow MAC modules to selectively disable PRIV_GEOM. The code to do that is in kern_priv.c but without this line, it would have no effect.

sys/geom/geom_ctl.c
658

I just finished a test suite run with your two GEOM patches and I believe there's only one new failure, which I didn't dig into, in sys/fs/unionfs/unionfs_test:unionfs_exec

667

But if I decide I want to make /dev/geom.ctl writeable by an unprivileged user or group, this priv_check() will still strip FWRITE, so my change will have no effect. To implement what you describe, I'd expect to see something like

if ((fflag & FWRITE) == 0 && priv_check(td, PRIV_GEOM) == 0)
    fflag |= FWRITE;

instead.

sys/geom/geom_ctl.c
667

But if I decide I want to make /dev/geom.ctl writeable by an unprivileged user or group

that would effectively give them complete control of the system...

sys/geom/geom_ctl.c
667

I don't immediately see how. It's certainly a powerful capability, but how does it automatically give you unfettered access to the system? Said another way, why don't we need an equivalent check for, say, /dev/xpt0?