MFC after: 1 week
Sponsored by: fme AG
Details
Diff Detail
- Repository
- rG FreeBSD src repository
- Lint
Lint Skipped - Unit
Tests Skipped - Build Status
Buildable 77765 Build 74648: arc lint + arc unit
Event Timeline
If I understand correctly (asking for confirmation of principles), if you do not configure mac_do, that it does not use it, correct?
mac_do is still not ready for corporate use, because it has a security flaw that I discussed with others at BSDCan.
If someone can gain access to your system by hijacking ssh keys forwarded into a third machine that an attacker controls, the fact that mdo does not prompt for password means that your machine can be compromised immediately upon the attacker gaining entry as a user that mdo grants escalation.
Maintainers of mac_do have promised to work on code to require a password on new shells and potentially after a timeout (like sudo) to prevent such distributed network attacks.
Until then, we cannot make mdo the default over sudo in corporate environments with heightened security requirements.
I'm quite surprised by this statement, on multiple respects. First, I've never been informed of that, although I'm the maintainer. Second, I don't think this is true at all. mac_do(4) is perfectly usable in a corporate use, and has been developed with the highest quality in mind. You have to understand what it can and cannot do, though.
If someone can gain access to your system by hijacking ssh keys forwarded into a third machine that an attacker controls, the fact that mdo does not prompt for password means that your machine can be compromised immediately upon the attacker gaining entry as a user that mdo grants escalation.
This is not a security flaw, it is by design that mdo(1) does not prompt for a password. mdo(1) is not meant to replace sudo(8), it is meant for the specific case of role-based authorization based on UNIX users. I can only encourage you to read my article in the FreeBSD Journal, October/November/December 2025 edition.
Maintainers of mac_do have promised to work on code to require a password on new shells and potentially after a timeout (like sudo) to prevent such distributed network attacks.
It's not exactly that. Continuing in the current vain with a non-setuid mdo(1), adding such features requires a lot of development and more thinking (again, see end of my article), and personally I don't have the bandwidth for that now. To serve people wanting sudo(8), we are probably better off at this point porting doas(1) and make it use our own APIs.
Until then, we cannot make mdo the default over sudo in corporate environments with heightened security requirements.
You can use mac_do(4)/mdo(1) in "heightened security requirements". You cannot expect them to replace sudo(1) except for role-base credentials transition for now.
I've never used dwatch(1), it looks like it leverages dtrace(1), for which you need to be root. Allowing some users to become root through mac_do(4)/mdo(1) is not a flaw per se and can be perfectly acceptable in some situations, but you have to be aware of the implications. As long as authorization has not been granted through mac_do(4), mdo(1) will fail. So I don't think there is any problem in trying to run mdo(1) here.
Usability is impacted not-only by feasibility by by ability to be compliant with policy. Some environments even reject sudo in favor of Fortra BoKS (Core Privileged Access Manager).
I should have perhaps said enterprise instead of corporate, as many corporations neither need nor embrace enterprise requirements (which are often built around accountability).
If someone can gain access to your system by hijacking ssh keys forwarded into a third machine that an attacker controls, the fact that mdo does not prompt for password means that your machine can be compromised immediately upon the attacker gaining entry as a user that mdo grants escalation.
This is not a security flaw, it is by design that mdo(1) does not prompt for a password. mdo(1) is not meant to replace sudo(8), it is meant for the specific case of role-based authorization based on UNIX users. I can only encourage you to read my article in the FreeBSD Journal, October/November/December 2025 edition.
Right, given the high level of fallout from what can happen if an attacker gains access to Dtrace/dwatch on a system without being prompted for credentials (but instead merely supposing that remote access control is sufficient alone) additional scrutiny is required. The change is fine for systems that roundly reject mac_do for their inability to properly gate access in the face of failed safety systems.
Maintainers of mac_do have promised to work on code to require a password on new shells and potentially after a timeout (like sudo) to prevent such distributed network attacks.
It's not exactly that. Continuing in the current vain with a non-setuid mdo(1), adding such features requires a lot of development and more thinking (again, see end of my article), and personally I don't have the bandwidth for that now. To serve people wanting sudo(8), we are probably better off at this point porting doas(1) and make it use our own APIs.
I don't recall who I talked with at BSDCan, but we were in the hacker lounge as he was porting the code from NetBSD to add prompting, and before the convention was over he even had demonstrated a portion of working code.
I don't think people necessarily want sudo out of mdo, but the current situation where you are unchallenged and allowed to escalate privilege merely by having presence on the machine is untenable (I gave a real-world example of how presence on a machine can be illegitimate, where a hacker has used your stored credentials from elsewhere to gain access to the machine). In all manner of secure applications, one must consider the case of adjacent compromise where privileged positions on-network are not-alone sufficient protection).
Until then, we cannot make mdo the default over sudo in corporate environments with heightened security requirements.
You can use mac_do(4)/mdo(1) in "heightened security requirements". You cannot expect them to replace sudo(1) except for role-base credentials transition for now.
Again, ability in enterprise corporations is not tied alone to feasibility but also accountability.
I've never used dwatch(1), it looks like it leverages dtrace(1), for which you need to be root. Allowing some users to become root through mac_do(4)/mdo(1) is not a flaw per se and can be perfectly acceptable in some situations, but you have to be aware of the implications. As long as authorization has not been granted through mac_do(4), mdo(1) will fail. So I don't think there is any problem in trying to run mdo(1) here.
Agree that as long as nobody points the foot-gun of mac_do on a system, then things like https://github.com/FrauBSD/dwatch-pwsnoop cannot be used to wholesale batch-collect typed passwords from a system.
I demonstrated that code at Intel HQ during a conference to a rapt audience.
You don't need to "reject" anything. By default, mac_do(4) does not allow anything (assuming it's even loaded, which it should not unless you do something explicit).
If you think some user can be compromised by remote access and at the same time allowing him to become root without any additional measure (such as what mac_do(4)/mdo(1) would do *when explicitly configured to do so*), then you're doing it wrong. It's basically similar as, e.g., leaving a setuid executable accessible by an unprivileged user and then claiming setuid is in general a security flaw.
Again, ability in enterprise corporations is not tied alone to feasibility but also accountability.
In what you call "enterprise", may be. Then mac_do(4) is not the tool you should use. But there are several cases where it is useful, including in corporations.
Agree that as long as nobody points the foot-gun of mac_do on a system,
Could you please stop with this rhetoric? mac_do(4) is not a foot-gun when you understand what it is about, and it is very useful even if don't have configured any rule allowing some users or groups to become root.
then things like https://github.com/FrauBSD/dwatch-pwsnoop cannot be used to wholesale batch-collect typed passwords from a system.
You can of course extract any information from a system using dtrace(4), no surprise here.
I haven't seen any code, so can only speculate, but I wouldn't be surprised if that hacker did not understand the current architecture and was using a setuid mdo(1) executable, which is against the purpose of mdo(1). But if that's not the case, I'd like to see this code.
Was not a community hacker, but a committer if I recall, and they were modifying the kernel code, not resorting to hacks. I just am not great with the name-to-face association until I've seen you at least a couple of conferences.
I am aware. I test-drove mac_do the day it came out, and then again right before BSDCan. I was dissatisfied with the inability to require a password. My ideal situation would be that if integrates with PAM and requires a password to use it when configured to do-so because strictly-speaking, a person can gain access to a system without knowing their password. The example I gave earlier was ssh keys. Here's the example in more depth:
User John has an ssh key. That ssh key allows access to system A and system B. John uses that key to access system A. Either by using ssh -A or by configuring automatic forwarding in ~/.ssh/config for convenience, a socket is created on system A back to John's origin to sign login requests. An attacker on system A that compromised system A can use that socket to communicate with John's origin to sign a login request to access system B.
In this situation, the attacker was able to compromise system A due to an RCE that system B was patched-for, and therefore the attacker was not able to access system B until someone like John forwarded their key (which works on system B) into the compromised system A.
Now with John's credentials the attacker has gained access to system B but if the privilege escalation policy has John configured for escalation, that escalation is granted without challenge. Compared to sudo or doas (both of which default to prompting for password, and both of which have to be opted-into NOPASSWD for sudo or nopass for doas), the attacker now on system B does not immediately have privilege escalation unless they also are able to compromise John's password (which requires an additional level of complexity, depending on your PAM configuration.
NB: On that last note, both sudo and doas password prompts are impacted by PAM meaning that if a system is configured for OTP that a mere sniff of a password, say on an already-fully compromised system A, is insufficient to defeat the challenge on a new frontier such as system B.
Nobody is saying that mac_do/mdo has to be sudo or doas, but I am saying that the inability to configure a localized challenge that is influenced by PAM is a real challenge to overcome in leveraging mac_do/mdo in a high security setting.
If you think some user can be compromised by remote access and at the same time allowing him to become root without any additional measure (such as what mac_do(4)/mdo(1) would do *when explicitly configured to do so*), then you're doing it wrong. It's basically similar as, e.g., leaving a setuid executable accessible by an unprivileged user and then claiming setuid is in general a security flaw.
Again, ability in enterprise corporations is not tied alone to feasibility but also accountability.
In what you call "enterprise", may be. Then mac_do(4) is not the tool you should use. But there are several cases where it is useful, including in corporations.
Yes, but I would argue that most serious corporations accept funding from people that want (some might say demand) a level of accountability that inherently brings with it higher levels of security that mac_do/mdo cannot yet offer or satisfy.
Agree that as long as nobody points the foot-gun of mac_do on a system,
Could you please stop with this rhetoric? mac_do(4) is not a foot-gun when you understand what it is about, and it is very useful even if don't have configured any rule allowing some users or groups to become root.
The word rhetoric applied here is diminishing the very real short-comings. I'd also raise issue with the hand-wave that I "don't understand."
then things like https://github.com/FrauBSD/dwatch-pwsnoop cannot be used to wholesale batch-collect typed passwords from a system.
You can of course extract any information from a system using dtrace(4), no surprise here.
Yes, but the lack of a challenge-response system puts mac_do/mdo lower on the totem of in-depth protection against ersatz escalation
If only modifying kernel code meant all the time not resorting to hacks...
Maybe they chose the path of storing password hashes in the kernel. I evoked that possibility in the journal article, that would be a logical continuation of the work done so far. That said, the initial mdo(1)/mac_do(4) responded to particular needs: Simple role-based scheme, no trust/no need for configuration in userland. Making them evolve in this frame is more complicated and time-consuming then just importing doas(1) if the need is "just" to have a sudo(8) substitute for simple cases. In particular, putting more checks in the kernel is not necessarily good for security. And anyway, this is simply not an option if we want to factor in PAM into the equation. But let's see what code pops up, if any.
My ideal situation would be that if integrates with PAM and requires a password to use it when configured to do-so because strictly-speaking, a person can gain access to a system without knowing their password. The example I gave earlier was ssh keys. Here's the example in more depth: (snip)
mdo(1) was never made with using PAM in mind. In fact, it's currently impossible to use PAM from a non-setuid executable. This is an example of where you're still bounded by your own frame. Yes, I've understood what kind of problem you're talking about, and I certainly understand your need too. I'm saying that mdo(1) is likely not a good fit to it, and probably will never be unless we completely switch views on its current purpose and implementation (in particular, the non-setuid executable requirement), which I'm not sure it's a good idea (that would be a separate discussion).
Nobody is saying that mac_do/mdo has to be sudo or doas, but I am saying that the inability to configure a localized challenge that is influenced by PAM is a real challenge to overcome in leveraging mac_do/mdo in a high security setting.
This has nothing to do with "high security" *in general*, only some aspect of it. Which again I perfectly understand, and is indeed highly important in some settings. mac_do(4)/mdo(1) was not designed for that and cannot easily do that.
Yes, but I would argue that most serious corporations accept funding from people that want (some might say demand) a level of accountability that inherently brings with it higher levels of security that mac_do/mdo cannot yet offer or satisfy.
Probably. I can understand your frustration, but again, and especially if you'd like mdo(1) to leverage PAM, there are technical reasons making it very unlikely to happen. You're after the wrong tool because you're not recognizing its frame and technical traits.
The word rhetoric applied here is diminishing the very real short-comings.
No, I'm talking about your insistance to dismiss mac_do(4)/mdo(1) as not being "high quality" or a "foot-gun" because it does not fit your needs. Your formulation and tone in past messages can be confused with general depreciation, and this is what I disagree with and am trying to point out.
I'd also raise issue with the hand-wave that I "don't understand."
There is no handwaving. I've just addressed what you're apparently still missing in some lines above.
Yes, but the lack of a challenge-response system puts mac_do/mdo lower on the totem of in-depth protection against ersatz escalation
Certainly.
At the risk of repeating myself, but with more details:
- This is not the frame mac_do(4)/mdo(1) was designed to serve, which is a simple role-based permissions system on top of UNIX users, where users are assigned roles and can switch to these roles at will and automatically without any user intervention. Roles are endorsed only to perform certain actions, and given up just after, voluntarily. There's no provision for preventing a user to gain a role he's *already* authorized to endorse. In the context of automation, that's a *feature*, not a deficiency.
- It is certainly possible to fit some kind of challenge-response system in there, but it's very unlikely to be PAM, or else we give up on mdo(1) being a setuid executable, but then the initial needs that prompted this are not served anymore and basically this makes mac_do(4) mostly without purpose, and we are basically re-implementing doas(1). Fitting a challenge-response system in mac_do(4) means putting more of it in the kernel, which is also a risk and should be carefully designed/reviewed. This is probably comparable to the work required to port doas(1) and making it use PAM, or more. Given your exposed needs do not feature the constraints that gave birth to mac_do(4)/mdo(1), it's likely that something like doas(1) is a better fit.
To 2., I'll add that one of the ideas in my far TODO list for mac_do(4)/mdo(1) was to create a new executable, this one setuid, that would leverage setcred(2), re-use code from mdo(1) where it makes sense (with proper factoring out into a library), and behave externally like doas(1) (as much as possible and sane; at least one behavior that I know of can be considered a security flaw and should not be imported). One of the goals here is to avoid administrators having to learn a new FreeBSD-specific tool from scratch for needs that are not specific.
Truth!
Maybe they chose the path of storing password hashes in the kernel. I evoked that possibility in the journal article, that would be a logical continuation of the work done so far. That said, the initial mdo(1)/mac_do(4) responded to particular needs: Simple role-based scheme, no trust/no need for configuration in userland. Making them evolve in this frame is more complicated and time-consuming then just importing doas(1) if the need is "just" to have a sudo(8) substitute for simple cases. In particular, putting more checks in the kernel is not necessarily good for security. And anyway, this is simply not an option if we want to factor in PAM into the equation. But let's see what code pops up, if any.
The road to acting as a drop-in replacement (or even just replacement full-stop, leaving drop-in aside) in some of these shops that have accepted sudo may not be as simple as I originally regarded anyhow. sudoers for example is often maintained by something like ansible or chef and there would have to be a long vetting period. It however, in my mind, would be good to offer a BSD-licensed solution that is encapsulated in base so we could insulate ourselves from things such as having base utilities that know about externally-maintained sudo (speaking of my own dwatch here).
My ideal situation would be that if integrates with PAM and requires a password to use it when configured to do-so because strictly-speaking, a person can gain access to a system without knowing their password. The example I gave earlier was ssh keys. Here's the example in more depth: (snip)
mdo(1) was never made with using PAM in mind. In fact, it's currently impossible to use PAM from a non-setuid executable. This is an example of where you're still bounded by your own frame. Yes, I've understood what kind of problem you're talking about, and I certainly understand your need too. I'm saying that mdo(1) is likely not a good fit to it, and probably will never be unless we completely switch views on its current purpose and implementation (in particular, the non-setuid executable requirement), which I'm not sure it's a good idea (that would be a separate discussion).
Understood and understandably-so.
Nobody is saying that mac_do/mdo has to be sudo or doas, but I am saying that the inability to configure a localized challenge that is influenced by PAM is a real challenge to overcome in leveraging mac_do/mdo in a high security setting.
This has nothing to do with "high security" *in general*, only some aspect of it. Which again I perfectly understand, and is indeed highly important in some settings. mac_do(4)/mdo(1) was not designed for that and cannot easily do that.
I think on its initial arrival on day-one whether by your own intentions or that of others, it was over-sold as a replacement for sudo (even in some channels that some may consider official). Hearing that you readily disregard such notions (that it can be a replacement for sudo and that you are abreast of the situations where it is not applicable) gives me great relief.
Yes, but I would argue that most serious corporations accept funding from people that want (some might say demand) a level of accountability that inherently brings with it higher levels of security that mac_do/mdo cannot yet offer or satisfy.
Probably. I can understand your frustration, but again, and especially if you'd like mdo(1) to leverage PAM, there are technical reasons making it very unlikely to happen. You're after the wrong tool because you're not recognizing its frame and technical traits.
I understood quite well that primary benefit of a tool such as mdo, and that's the ability to have non-root running services escalate privilege on an as-needed basis through a framework that decidedly does not require a password or pose a challenge. However, upon heralded release it was primarily cast as a replacement which I found to be insalubrious.
The word rhetoric applied here is diminishing the very real short-comings.
No, I'm talking about your insistance to dismiss mac_do(4)/mdo(1) as not being "high quality" or a "foot-gun" because it does not fit your needs. Your formulation and tone in past messages can be confused with general depreciation, and this is what I disagree with and am trying to point out.
foot-gun was perhaps bad framing. I apologize for that, and I further apologize if it seemed like I was calling for deprecation. Nothing could be further from the truth -- especially for something so-recently added. It's new, and I can only see it improving and getting better over time. I for one do not want to see mac_do(4) or mdo(1) exit the system.
`
I'd also raise issue with the hand-wave that I "don't understand."
There is no handwaving. I've just addressed what you're apparently still missing in some lines above.
It is true that I have not talked of the positive merits, of which there are and absolutely do exist because of the existence of mdo and its MAC framework. There is a very real need for it and I am chagrin that I did not lead with that. I appreciate your work.
Yes, but the lack of a challenge-response system puts mac_do/mdo lower on the totem of in-depth protection against ersatz escalation
Certainly.
At the risk of repeating myself, but with more details:
- This is not the frame mac_do(4)/mdo(1) was designed to serve, which is a simple role-based permissions system on top of UNIX users, where users are assigned roles and can switch to these roles at will and automatically without any user intervention. Roles are endorsed only to perform certain actions, and given up just after, voluntarily. There's no provision for preventing a user to gain a role he's *already* authorized to endorse. In the context of automation, that's a *feature*, not a deficiency.
- It is certainly possible to fit some kind of challenge-response system in there, but it's very unlikely to be PAM, or else we give up on mdo(1) being a setuid executable, but then the initial needs that prompted this are not served anymore and basically this makes mac_do(4) mostly without purpose, and we are basically re-implementing doas(1). Fitting a challenge-response system in mac_do(4) means putting more of it in the kernel, which is also a risk and should be carefully designed/reviewed. This is probably comparable to the work required to port doas(1) and making it use PAM, or more. Given your exposed needs do not feature the constraints that gave birth to mac_do(4)/mdo(1), it's likely that something like doas(1) is a better fit.
My desires stem mostly toward satisfying internal componentry in the FreeBSD ecosystem (which mac_do and mdo get 99% of the way there -- dwatch hit a minor nerve because without the ability to initiate a challenge/response we open a huge Pandora's box since it's really hard to lock-down allowing one dwatch, or dtrace, invocation and not another that doesn't entirely open the entire system to snooping anything/everything). Without PAM, I am not sure how we would approach the need for something like OTP, which is where PAM came into the conversation.
To 2., I'll add that one of the ideas in my far TODO list for mac_do(4)/mdo(1) was to create a new executable, this one setuid, that would leverage setcred(2), re-use code from mdo(1) where it makes sense (with proper factoring out into a library), and behave externally like doas(1) (as much as possible and sane; at least one behavior that I know of can be considered a security flaw and should not be imported). One of the goals here is to avoid administrators having to learn a new FreeBSD-specific tool from scratch for needs that are not specific.
Thank you for the additional information and details. Cheers.