jails mac.do usage in a jail

I am unable to get a jail to inherit mac.do settings for a user in group wheel.

Host is set up to use mdo:

Bash:
/usr/local/bastille/jails $ mdo sysctl security.mac.do
security.mac.do.rules: gid=0>uid=0,gid=*,+gid=*
security.mac.do.print_parse_error: 1
security.mac.do.enabled: 1

mdo works fine with uid 1001 in the host.

I have set up a VNET jail using bastille and used the following to set inherit on the jail:

Bash:
mdo jail -m -n daredevil mac.do='inherit'

Console into jail and checking sysctl shows the jail has inherited the mac.do rules

Bash:
/usr/local/bastille/jails $ mdo bastille console daredevil

[daredevil]:
root@daredevil:~ # sysctl security.mac.do
security.mac.do.rules: gid=0>uid=0,gid=*,+gid=*
security.mac.do.print_parse_error: 1
security.mac.do.enabled: 1

But actual execution of mdo by uid 1001 in the jail fails:

Bash:
root@daredevil:~ # su - build
Nice bash prompt: PS1='(\[$(tput md)\]\t <\w>\[$(tput me)\]) $(echo $?) \$ '
                -- Mathieu <mathieu@hal.interactionvirtuelle.com>
build@daredevil:~ $ mdo ls
mdo: setcred(): Operation not permitted

Here is the info about the user and the groups:

Bash:
root@daredevil:~ # pw user show build -P
Login Name: build             #1001         Group: build             #1001
 Full Name: User Build
      Home: /home/build                     Class:
     Shell: /bin/sh                        Office: [None]
Work Phone: [None]                     Home Phone: [None]
Acc Expire: [None]                     Pwd Expire: [None]
    Groups: wheel

root@daredevil:~ # pw group show wheel -P
Group Name: wheel             #0
   Members: root,build

I've tried putting the rules into the mac.do rules for the jail and this has not worked either. Any thoughts on what I can do next to get this wot work?
 
WARNING 1: Seeing that you have received no additional responses in a while, with nothing but good intentions in my heart, especially helping you, I outsourced your case to a non-subject expert-in-training and below the horizontal line is what it had to say.

WARNING 2: Use it all only as an inspiration or starting investigative point and check everything using official sources. That it sounds certain doesn't mean it is; these non-subjects are trained to first and foremost sound certain.

WARNING 3: Read in full before doing anything. Then, decide what you want to do.

Note: If you end up solving your problem, please write a post explaining what fixed it, so it gets documented for the community.



Fix mdo: setcred(): Operation not permitted inside a jail when mac_do(4)() is inherited

The inheritance is working (the jail sees security.mac.do.*). The failure happens because either:
  • the jail is not executing /usr/bin/mdo, so mac_do(4)() never applies, or
  • the jail is executing /usr/bin/mdo, but the requested transition is not matching any rule.

mac_do(4)() currently only affects processes spawned from /usr/bin/mdo, and each jail must have mdo(1)() available at that path. HAZARD: Misconfigurations here can lead to unexpected privilege escalation inside the jail.

1) Confirm which mdo is being executed in the jail

Inside the jail:

Code:
# as root
freebsd-version
ls -l /usr/bin/mdo 2>/dev/null || echo "/usr/bin/mdo is missing"

# as the unprivileged user
id
type -a mdo
command -v mdo
ls -l "$(command -v mdo)"

Success condition: type -a mdo lists /usr/bin/mdo and that is the one being run. mac_do(4)() only produces effects for processes spawned from /usr/bin/mdo.

2) Prove rule matching using an explicit “become root” invocation

Given the rule shown ( gid=0&gt;uid=0,...), the intended authorization is “members of group 0 (wheel), including via supplementary groups, can switch to UID 0.” mac_do(4)() states gid=... matching includes supplementary groups.

Run as build in the jail:

Code:
id
/usr/bin/mdo -u root id

Success condition: id output from the mdo command shows UID 0.

  • If /usr/bin/mdo -u root id works, but mdo ls fails, mdo in PATH is not /usr/bin/mdo (go to step 3).
  • If /usr/bin/mdo -u root id fails, the jail either lacks a usable /usr/bin/mdo, or something else is preventing the transition; continue with step 4.

3) If mdo resolves to /usr/local/bin/mdo, force /usr/bin/mdo

Use the absolute path (or remove/rename the other mdo in the jail if it is not needed):

Code:
/usr/bin/mdo -u root ls

Reason: mac_do(4)() only affects processes spawned from /usr/bin/mdo, not an mdo installed elsewhere. HAZARD: Leaving a non-base mdo earlier in PATH can silently defeat mac_do(4)() authorization.

4) If /usr/bin/mdo is missing, fix the jail userland

mdo(1)() first appeared in FreeBSD 14.2. So a jail based on 14.1/13.x will not have /usr/bin/mdo in base, and any mdo installed under /usr/local will not trigger mac_do(4)().

Safer fix: rebuild or re-bootstrap the jail on FreeBSD 14.2+ (or 15.x), so /usr/bin/mdo exists inside the jail.

HAZARD: Copying /usr/bin/mdo from the host into an older jail can break due to userland/library mismatches. Prefer a jail userland that natively contains /usr/bin/mdo.

5) Verify the jail parameters from the host (correct jls usage)

On the host, jls(8)() supports printing parameters in name=value form with -n, and all prints all parameters.

Code:
jls -j daredevil -n mac.do mac.do.rules
jls -j daredevil -n all | egrep '^(mac\.do|mac\.do\.rules)='

6) Security note on the rule

HAZARD: gid=0&gt;uid=0,gid=*,+gid=* grants broad privilege to any process with group 0 (wheel) membership, allowing transition to UID 0 and unconstrained groups. Keep the wheel membership inside the jail tightly controlled.
 
Thanks this did not fix my problem but it did lead me to this:

Bash:
build@daredevil:/usr $ ls -la
lrwxr-xr-x   1 root wheel 18 Feb 23 15:14 bin -> /.bastille/usr/bin

I'm guessing that /usr/bin/ being a symlink my be the issue as mdo is actually at /.bastille/usr/bin? This is how bastille sets up its nullfs mounts.

I'll have to test with a thick jail and see if this occurs with bastille.
 
I fed this new info to the non-subject and below the horizontal line is what it had to add. The same warnings as before apply.



Bastille thin-jail /usr/bin symlink and mac_do(4)() / mdo(1)() behavior

mac_do(4)() currently only authorizes credential transitions for processes spawned from the /usr/bin/mdo executable, and that path is not configurable (including in jails). The FreeBSD status report notes this hardcoded path can be problematic for “custom thin jail layouts,” which matches Bastille thin jails’ indirection.

1) Confirm the thin-jail path indirection is present

Inside the jail:

Code:
ls -ld /usr/bin
ls -l /usr/bin/mdo 2>/dev/null || echo "/usr/bin/mdo missing"
realpath /usr/bin/mdo 2>/dev/null
type -a mdo

If realpath /usr/bin/mdo resolves to /.bastille/usr/bin/mdo, the jail is not presenting a “normal” /usr/bin tree.

2) Do a clean A/B test by converting the existing thin jail to thick

HAZARD (jail filesystem): converting changes the jail’s on-disk layout; take a snapshot/backup first if the jail contains important state.

Bastille supports converting a thin jail to a thick jail directly:

Code:
bastille stop daredevil
bastille convert -a -y daredevil
bastille start daredevil

Re-apply the per-jail parameter (safe even if already set):

Code:
mdo jail -m -n daredevil mac.do='inherit'

3) Verify behavior in the thick jail

Inside the jail:

Code:
sysctl security.mac.do
su - build
id
/usr/bin/mdo -u root id
/usr/bin/mdo ls

If this starts working after conversion, the thin-jail filesystem presentation (including the /usr/bin symlink) is the differentiator, consistent with the hardcoded executable-path limitation in mac_do(4)().

4) If creating a fresh thick VNET jail is preferred

Use Bastille’s documented create options:
  • -T|--thick creates a thick jail
  • -V|--vnet enables VNET and requires a physical interface
  • -B|--bridge enables VNET with a bridge interface

Example pattern:

Code:
bastille create -T -V NAME RELEASE IP INTERFACE

(Use -B instead of -V when INTERFACE is a bridge.)
 
WARNING 1: Seeing that you have received no additional responses in a while, with nothing but good intentions in my heart, especially helping you, I outsourced your case to a non-subject expert-in-training and below the horizontal line is what it had to say.
you did no such thing. the random text generator is not an expert in training.
 
you did no such thing. the random text generator is not an expert in training.
Déjà vu:
 
have you considered that if people wanted to read bot output, they would go ask chatgpt themselves? instead, you are misrepresenting chatbot output as advice from a real person.
 
Back
Top