aboutsummaryrefslogtreecommitdiff
path: root/sys/security
Commit message (Collapse)AuthorAgeFilesLines
* sys: add AUE_PDOPENPIDKonstantin Belousov2026-07-071-0/+10
| | | | | | | | Reviewed by: markj Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D57124
* mac_portacl: do not reject unspecific family directlyK Rin2026-06-101-1/+2
| | | | | Reviewed by: imp,emaste Pull Request: https://github.com/freebsd/freebsd-src/pull/1659
* audit: Replace TAILQ with STAILQDag-Erling Smørgrav2026-06-051-11/+11
| | | | | | | | | | This reduces the size of a trigger entry from 24 bytes to 16 (or from 12 bytes to 8 on 32-bit) with no additional complexity. MFC after: 1 week Sponsored by: Klara, Inc. Reviewed by: kevans, emaste Differential Revision: https://reviews.freebsd.org/D57464
* audit: Add poll / select supportDag-Erling Smørgrav2026-06-051-2/+21
| | | | | | | | | | | It was previously not possible to poll() or select() on the trigger device, which made implementing proper signal handling in auditd difficult. MFC after: 1 week Sponsored by: Klara, Inc. Reviewed by: kevans, markj Differential Revision: https://reviews.freebsd.org/D57457
* MAC/do: Clarify comments about flags attached per-ID or per-ID-typeOlivier Certner2026-06-041-5/+7
| | | | | | | No functional change. MFC after: 3 days Sponsored by: The FreeBSD Foundation
* MAC/do: Fix double-free on parse error after "executable paths" featureOlivier Certner2026-06-011-8/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | parse_rules() has been calling toast_rules() in case of a parse error in order to deallocate the 'struct rule' objects it has constructed up to that point. toast_rules() would take a pointer to a full 'struct rules' object, and besides freeing all 'struct rule' referenced by it, would also free the holding 'struct rules' itself. With the introduction of the "executable paths" feature, and the embedding of 'struct rules' into 'struct conf', meaning that the lifecycle for 'struct rules' was no longer independent, toast_rules() was changed not to free the passed 'struct rules' (as it was a field of a 'struct conf' object). Unfortunately, this change was not completed with a reinitialization of the rules list head, so the 'struct conf' object would continue to reference just-freed rules, which then would be freed a second time on destruction of that container. So, make toast_rules() re-initialize the rules list in 'struct rules', which it logically has been having to do since not freeing the enclosing 'struct rules'. This alone is enough to fix the bug, but let's use the occasion to change the contract of parse_rules() and bring its herald comment up-to-date: On error, parse_rules() now simply leaves already constructed 'struct rule' objects in 'conf'. The latter is eventually destroyed and the rule objects reclaimed at that point. Add a test trying to set an invalid rules configuration with the first rule being valid and the second being invalid, which triggers the bug (and an immediate panic() on an INVARIANTS kernel). Reported by: impost0r(ret2plt) <impostor@ret2p.lt> Reviewed by: markj Fixes: 9818224174c4 ("MAC/do: Executable paths feature (GSoC 2025's final state)") Sponsored by: The FreeBSD Foundation
* MAC/do: Update copyrightOlivier Certner2026-05-291-3/+3
| | | | | | | | | | | | | | | Update years for the Foundation. While here, remove the initial '/*-' which has been useless for a long time. While here, add a missing space on bapt@'s copyright line (approved by him). Reviewed by: bapt MFC after: 1 month Sponsored by: The FreeBSD Foundation Pull Request: https://ron-dev.freebsd.org/FreeBSD/src/pulls/38
* MAC/do: Do not skip blanks when parsing executable pathsOlivier Certner2026-05-291-1/+1
| | | | | | | | | | | | | | | | The kind of tolerance we apply to parsing rules, whose format we have defined, cannot be applied to paths since blank characters are allowed there. There is still the limitation that no escape character is currently supported, and so it is not possible to configure a path having a ':' character. Reviewed by: bapt Fixes: 9818224174c4 ("MAC/do: Executable paths feature (GSoC 2025's final state)") MFC after: 1 month Sponsored by: The FreeBSD Foundation Pull Request: https://ron-dev.freebsd.org/FreeBSD/src/pulls/38
* MAC/do: Serialize installing/modifying some jail's configurationOlivier Certner2026-05-291-23/+76
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | See the immediately preceding commit for explanations on what this is fixing. When setting 'mac.do' to 'inherit' on a jail with 'mac.do.rules' and 'mac.do.exec_paths' also specified in the same call, ensure that the check that these passed parameters are the same as those to be inherited is atomic with respect to enabling the inheritance (i.e., removing the jail's 'struct conf' object). (See previous commit "MAC/do: Fix the recent logic to set jail parameters, make it more tolerant" as for why this check exists.) Because we currently only modify a single configuration object per transaction, we introduce the parse_and_commit_conf() wrapper around parse_and_set_conf() to remove duplicated code that would ensue from calling the latter directly, namely, releasing the 'mac_do_rwl' lock and freeing the old configuration object (if any). Taking the 'mac_do_rwl' lock for writing as a way to freeze all accesses to mac_do(4) configurations was deemed too thin an operation to be worth wrapping. Reviewed by: bapt (older version) Fixes: 9818224174c4 ("MAC/do: Executable paths feature (GSoC 2025's final state)") MFC after: 1 month Sponsored by: The FreeBSD Foundation Pull Request: https://ron-dev.freebsd.org/FreeBSD/src/pulls/38
* MAC/do: Support for atomically modifying configurationsOlivier Certner2026-05-291-15/+49
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | As mentioned in previous commits "MAC/do: parse_and_set_conf(): Require the model configuration" and "MAC/do: Sequential consistency for configuration retrieval", the introduction of the "executable path" feature, more fundamentally, the fact that there is now more than one per-jail parameter and that parameters can be independently modified or copied, causes an atomicity problem in case of concurrent accesses to of a jail's applicable configuration. Partially modifying a configuration is indeed akin to a read-modify-write operation, where the read is either to the current or an inherited configuration. More precisely, once pointed to by a jail, a configuration object is immutable, and changing the jail's configuration means making the jail point to another configuration object. To change a jail's configuration, a new configuration object is thus built, and if only some parameters have been explicitly specified, those that have not been are set by copying the corresponding values from an existing configuration object (in case of partial modification of the existing configuration, from the original configuration object that is going to be replaced; in case of breakage of inheritance or at jail creation, from the applicable configuration object, which is on an ancestor jail). This process is not immune to concurrent modifications because nothing prevents changes of configurations between reading existing values and setting the new configuration. Thus, some other thread could change the value of a parameter after a copy of it has been made into the new object but before that copy is actually installed, which effectively will erase the other thread's modification. To avoid this, we introduce support for serializing configuration changes on a given jail. To this end, we move the jail climbing process from find_conf() into find_conf_locked(), and make the former call the latter in a read-locked section. Similarly, we isolate setting a configuration in the new set_conf_locked() function, and make set_conf() call it inside a write-locked section. The new *_unlocked() variants make it possible to prevent any configuration access between determining and reading an applicable configuration, computing from it a new configuration object and finally setting it, by holding a write lock over the whole process (there is a trade-off here, as read-mostly locks cannot be upgraded), effectively making it atomic and realizing full sequential consistency of configuration changes. Also, the 'mac_do_rm' global read-mostly lock is made sleepable so that it can be write-locked over sysctl_handle*() functions or memory allocations (eases implementation, at the expense of a potential loss of concurrency which is most probably irrelevant). No functional change (intended) at this point. Reviewed by: bapt Fixes: 9818224174c4 ("MAC/do: Executable paths feature (GSoC 2025's final state)") MFC after: 1 month Sponsored by: The FreeBSD Foundation Pull Request: https://ron-dev.freebsd.org/FreeBSD/src/pulls/38
* MAC/do: Sequential consistency for configuration retrievalOlivier Certner2026-05-291-48/+64
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Since the inception of mac_do(4), find_conf(), used to retrieve the applicable configuration, has been weakly consistent with respect to concurrent modifications to configuration inheritance that influence its result (and it has been sequentially consistent with respect to other configuration modifications, which the initial executable paths feature and introduction of implicit parameters broke and which will be fixed in a subsequent commit). Indeed, find_conf() climbs the jail tree to find an applicable configuration, which is not an atomic operation. It examines the current jail's configuration pointer for each browsed jail, which does not prevent concurrent modifications of the configuration pointer for jails below or above it. Modifications above the current jail are not a problem, since if climbing needs to continue (i.e., the current jail inherits), these modifications will be seen if performed before that check (and may or may not be seen if performed after that check). However, modifications below the current jail impair sequential consistency, because they could be done before other modifications at the current jail or higher up, and the latter could still be picked up by the rest of the climb, effectively ignoring that the former should have blocked the climb earlier, making them look as if they had happened after for the climbing thread. As a concrete example of this situation, let's examine a scenario where some jail A is the parent of some jail B, and B inherits its configuration from A. An administrator may want to relax the rules only for jail A but not B. To this end, he first copies the current rules on B over to A and then relaxes the rules on A. He can intuitively and reasonably expect that changing B's rules first will prevent A's relaxed rules to leak to threads in B. Unfortunately, that is not the case: As explained in the previous paragraph, there can be a time window where threads from B can still pick up A's new configuration just after it has been installed. This arguably makes changing inheritance in mac_do(4) in a fully secure fashion almost impossible. If preserving fine-grained locking of prisons, we could prevent this problem by having find_conf(), once it has climbed to a non-NULL pointer (actual, non-inherited configuration), do another climb to check that it can reach the same configuration on the same jail again. If the new climb gives another pointer or jail, it could make it the new candidate and do a climb check again until the situation stabilizes. A climb check detects whether changes in jails below that of the candidate configuration object happened, catching in particular such changes that happened before changes to the candidate object. However, that process alone would still be subject to ABA problems, and we would additionally need to tag each prison with some modification timestamp (global, or local but necessitating allocating memory during the check) to fix them. In the end, we considered this direction to be unnecessarily complex, given that configuration changes are to be rare events and most uses will just be configuration determination. Consequently, switch protecting jail configurations with a single read-mostly lock. While here, adapt set_conf() to accept NULL as the new configuration object, and have remove_conf() call it, which removes duplicated code. While here, add a comment explaining why we do not need to take any more locks when climbing the jail tree. Reviewed by: bapt MFC after: 1 month Sponsored by: The FreeBSD Foundation Pull Request: https://ron-dev.freebsd.org/FreeBSD/src/pulls/38
* MAC/do: Comment to explain the main invariant for configurationsOlivier Certner2026-05-291-0/+5
| | | | | | | | | | | | Once visible, configuration structures must *never* change. Spell that out in a comment to help future readers/contributors understand the design. Reviewed by: bapt MFC after: 1 month Sponsored by: The FreeBSD Foundation Pull Request: https://ron-dev.freebsd.org/FreeBSD/src/pulls/38
* MAC/do: Allocate only one default configurationOlivier Certner2026-05-291-12/+12
| | | | | | | | | | | | When mac_do(4) is loaded, all jails get the same default configuration (disabled, with only one allowed executable path: '/usr/bin/mdo'). Share it between all jails instead of creating a separate copy for each. Reviewed by: bapt Fixes: 9818224174c4 ("MAC/do: Executable paths feature (GSoC 2025's final state)") MFC after: 1 month Sponsored by: The FreeBSD Foundation Pull Request: https://ron-dev.freebsd.org/FreeBSD/src/pulls/38
* MAC/do: Visually separate some file sectionsOlivier Certner2026-05-291-0/+2
| | | | | | | | | | | With additional empty lines. No functional change (intended). Reviewed by: bapt MFC after: 1 month Sponsored by: The FreeBSD Foundation Pull Request: https://ron-dev.freebsd.org/FreeBSD/src/pulls/38
* MAC/do: Fix reporting of "mac.do" post-"executable paths"Olivier Certner2026-05-291-3/+2
| | | | | | | | | | | In mac_do_jail_get(), computation of 'jsys' had not been updated to take into account executable paths. Reviewed by: bapt Fixes: 9818224174c4 ("MAC/do: Executable paths feature (GSoC 2025's final state)") MFC after: 1 month Sponsored by: The FreeBSD Foundation Pull Request: https://ron-dev.freebsd.org/FreeBSD/src/pulls/38
* MAC/do: Configuration: Fix default values: Remove jail creation methodOlivier Certner2026-05-291-14/+6
| | | | | | | | | | | | | | | | | | | | | | | | | mac_do_jail_create() would create a default configuration on the just-created jail, erroneously causing mac_do_jail_set() to then retrieve it and use it as a model when determining the default values for not-specified parameters, instead of using the configuration applicable to the parent jail. Setting a default configuration in mac_do_jail_create() had been done as a kind of defensive measure to prevent a created jail not to have a configuration (effectively making it inherit from an ancestor jail, which is a security hazard except if explicitly requested). However, this measure was never really effective (osd_jail_call(PR_METHOD_CREATE) in kern_jail_set() calls the PR_PETHOD_CREATE methods in an unspecified order, and stops at the first error), so we are forced to rely in any case on the fact that an error in a PR_METHOD_CREATE or PR_METHOD_SET method leads to stopping the jail creation process (which is the case today; see kern_jail_set()). Reviewed by: bapt Fixes: 9818224174c4 ("MAC/do: Executable paths feature (GSoC 2025's final state)") MFC after: 1 month Sponsored by: The FreeBSD Foundation Pull Request: https://ron-dev.freebsd.org/FreeBSD/src/pulls/38
* MAC/do: Fix the recent logic to set jail parameters, make it more tolerantOlivier Certner2026-05-291-61/+140
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The logic introduced in the initial commit for the "executable paths" feature did not match the specification we discussed in that specifying an empty value (for rules or executable paths) on "mac.do" being "new" would be treated as an absence of value and trigger a copy from the currently applicable configuration, instead of being an override that deactivates mac_do(4) in the jail. Fix that by distinguishing both cases. More generally, a non-explicitly specified parameter is set to the same value it has in the currently applicable configuration (that of the closest ancestor jail that has one; 'prison0' (the host) always has one), with an exception in the disable case. On disable (explicit: "mac.do" to "disable", implicit: no parameters passed, or at least one is empty), now accept parameters with a non-empty value as long as at least one of them is empty (which alone is enough to disable mac_do(4)). If no parameters are passed, both are copied from the currently applicable configuration; if none of them is empty, then the rules are emptied to effectively disable mac_do(4) (see the inline comment as to why this was chosen). On explicit enable ("mac.do" to "enable"), allow not specifying any of the rules and executable paths, in which case both are copied from the currently applicable configuration (consistently with what is done when only one is missing). Note that, as mentioned above, not specifying any of them by default still resolves to disabling mac_do(4) (i.e., on no explicit "mac.do" parameter). On (explicit) inheritance, allow specifying non-empty parameters, provided they match the values we are going to inherit. This enables re-applying jail parameters' reported values verbatim to the current jail (idempotence) or, e.g., to some sibling jail. (While here, make some existing code easier to read by leveraging is_null_or_empty().) Reviewed by: bapt Fixes: 9818224174c4 ("MAC/do: Executable paths feature (GSoC 2025's final state)") MFC after: 1 month Sponsored by: The FreeBSD Foundation Pull Request: https://ron-dev.freebsd.org/FreeBSD/src/pulls/38
* MAC/do: Constify is_null_or_empty()Olivier Certner2026-05-291-1/+1
| | | | | | | Reviewed by: bapt MFC after: 1 month Sponsored by: The FreeBSD Foundation Pull Request: https://ron-dev.freebsd.org/FreeBSD/src/pulls/38
* MAC/do: Fix obsolete wording in a comment ("ascendant" => "ancestor")Olivier Certner2026-05-291-1/+1
| | | | | | | Reviewed by: bapt MFC after: 1 month Sponsored by: The FreeBSD Foundation Pull Request: https://ron-dev.freebsd.org/FreeBSD/src/pulls/38
* MAC/do: parse_and_set_conf(): Require the model configurationOlivier Certner2026-05-291-28/+38
| | | | | | | | | | | | | | | | | | | | | | | | | This change is a prerequisite for the next change in caller mac_do_jail_set(), which for semantic correctness needs to rely on a stable model configuration. The two other callers already call find_conf() to retrieve the applicable configuration, so for these a second call to find_conf() can be saved. However, this does not fix (actually, makes slightly worse) an atomicity problem when multiple threads concurrently change some jail's configuration (or the configuration inherited by a jail), which has existed since the introduction of executable paths due to being able to change only rules or executable paths independently (and the possibility of not specifying them and having them copied from the currently applicable configuration). Before tackling it in later commits, we first focus on fixing the semantics of configuration changes in the very next patches. Reviewed by: bapt MFC after: 1 month Sponsored by: The FreeBSD Foundation Pull Request: https://ron-dev.freebsd.org/FreeBSD/src/pulls/38
* MAC/do: parse_and_set_conf(): Obey empty parameters; Add docOlivier Certner2026-05-291-14/+14
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | parse_and_set_conf() is meant to be used in all situations when there is a need to set or modify some jail's MAC/do configuration. This entails passing the information of whether some parameter was explicitly specified. For example, an administrator setting/modifying jail parameters may not specify executable paths but only rules, in which case the executable paths value is copied from the currently-applicable configuration. The sysctl(8) knobs case always leverages this feature, since setting a knob changes one parameter at a time. Currently, a NULL or empty string argument is treated as a non-specified parameter. This causes a bug where disabling MAC/do in a jail does not actually work because, to this end, parse_and_set_conf() is passed an empty string which it then interprets as a request to copy the currently applicable configuration's value, which may well not be empty. Fix this problem by only treating NULL as a marker for a non-specified parameter, in accordance with the original design for this function. While here, write some documentation to explain the interface. While here, remove the original herald comment for parse_and_set_rules(), which was inadvertently pushed apart from the replacing parse_and_set_conf(). Reviewed by: bapt Fixes: 9818224174c4 ("MAC/do: Executable paths feature (GSoC 2025's final state)") MFC after: 1 month Sponsored by: The FreeBSD Foundation Pull Request: https://ron-dev.freebsd.org/FreeBSD/src/pulls/38
* MAC/do: clone_rules(): Readability improvements, constificationOlivier Certner2026-05-291-11/+13
| | | | | | | | | | | | Constify in order to let the compiler check that source and destination arguments are passed in the proper order in the different calls. No functional change (intended). Reviewed by: bapt MFC after: 1 month Sponsored by: The FreeBSD Foundation Pull Request: https://ron-dev.freebsd.org/FreeBSD/src/pulls/38
* MAC/do: Remove superfluous configuration initializationOlivier Certner2026-05-291-10/+24
| | | | | | | | | | | | Configuration objects would be initialized (zeroed, and some STAILQ_INIT() called) multiple times. Make sure they are so only once, and add assertions to check that this is actually the case for functions that expect it. Reviewed by: bapt MFC after: 1 month Sponsored by: The FreeBSD Foundation Pull Request: https://ron-dev.freebsd.org/FreeBSD/src/pulls/38
* MAC/do: Move static assertions on constants close to their definitionsOlivier Certner2026-05-291-4/+6
| | | | | | | | | And document more clearly their purpose. Reviewed by: bapt MFC after: 1 month Sponsored by: The FreeBSD Foundation Pull Request: https://ron-dev.freebsd.org/FreeBSD/src/pulls/38
* MAC/do: Constify clone_rules() and clone_exec_paths()'s source argumentOlivier Certner2026-05-291-2/+3
| | | | | | | | | Defensive programming. Reviewed by: bapt MFC after: 1 month Sponsored by: The FreeBSD Foundation Pull Request: https://ron-dev.freebsd.org/FreeBSD/src/pulls/38
* MAC/do: Fix releasing a nonexistent reference on configuration parsing errorOlivier Certner2026-05-291-6/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | On parsing error, parse_and_set_conf(), introduced with the recent "executable paths" feature, has been calling drop_conf() on the being-built configuration. However, that configuration structure is allocated through alloc_conf(), which does not grab a reference. Calling drop_conf() on it, which releases a reference, is thus erroneous, and causes the underlying counter to saturate, translating into a memory leak. To fix this bug, make alloc_conf() grab a reference on the newly-created 'struct conf', and rename it to new_conf() to be more in line with what it does. Keep set_conf() as is, i.e., grabbing an additional reference on behalf of the jail that is going to hold the configuration. Consequently, make sure that callers of alloc_conf() unconditionally drop the reference acquired by the latter before returning (i.e., even if set_conf() has been called). While here, since hold_conf() is always used to obtain additional references on a configuration (new_conf() does not use it, instead directly setting the use count), add an assertion that it is never used on a configuration that has no references at all (which indicates that the configuration has been destroyed). These changes generally simplify the lifecycle of configurations, reducing the probability of re-introducing reference mismatches (at the expense of slightly more reference counting operations, but performance does not matter here). Reviewed by: bapt Fixes: 9818224174c4 ("MAC/do: Executable paths feature (GSoC 2025's final state)") MFC after: 1 month Sponsored by: The FreeBSD Foundation Pull Request: https://ron-dev.freebsd.org/FreeBSD/src/pulls/38
* MAC/do: find_conf(): Return configuration with a true referenceOlivier Certner2026-05-291-43/+40
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In addition to the applicable configuration, find_conf() was returning a pointer to the actual jail holding the configuration object, with that jail's mutex locked in order to ensure liveness of the returned configuration (if we wouldn't, a concurrent thread modifying the jail's configuration could destroy this configuration object underneath us). But: 1. Ensuring configuration stability by owning the holding jail's mutex requires callers to either keep that mutex locked for a longer period of time than just accessing the corresponding 'struct prison' (in general, bad for concurrency with other operations involving jails) or to perform an additional dance to acquire a real reference in case the jail's mutex, for some reason (in general, LORs or acquiring a sleepable lock) must be dropped before use. 2. Most code does not actually need to know which jail holds the applicable configuration but for unlocking the jail's mutex. Having to deal with the jail holding the configuration can cause confusion about which jail (the current one, or the one holding the configuration) must be used (and actually did in the very initial version of MAC/do, which had a serious flaw as a consequence). So, do not keep a lock on the holding jail. Instead, ensure configuration stability by always acquiring a true reference from the start and passing it to the caller. Those callers not doing the dance mentioned above now need to free it when finished (but this need replaces the one to unlock the prison). Additionally, only return the holding jail if explicitly requested by the caller. mac_do_jail_get() is currently the only caller that needs it, in order to be able to reliably report if the configuration is inherited. Reviewed by: bapt MFC after: 1 month Sponsored by: The FreeBSD Foundation Pull Request: https://ron-dev.freebsd.org/FreeBSD/src/pulls/38
* MAC/do: Move hold_conf() and drop_conf() earlierOlivier Certner2026-05-291-15/+15
| | | | | | | | | This is in preparation for using hold_conf() in find_conf(). Reviewed by: bapt MFC after: 1 month Sponsored by: The FreeBSD Foundation Pull Request: https://ron-dev.freebsd.org/FreeBSD/src/pulls/38
* MAC/do: find_conf(): Turn an MPASS() into a KASSERT()Olivier Certner2026-05-291-1/+9
| | | | | | | | | | | | | | | | Turn the pre-existing comment into an assertion message, with an update following the introduction of the "executable paths" feature. Explain in a comment why this situation cannot happen. Without INVARIANTS, such a situation would cause an immediate panic() (NULL is dereferenced in the next iteration of the loop), so leave the check under INVARIANTS only. Reviewed by: bapt MFC after: 1 month Sponsored by: The FreeBSD Foundation Pull Request: https://ron-dev.freebsd.org/FreeBSD/src/pulls/38
* MAC/do: Rename size constants/variables to clear confusion with string lengthsOlivier Certner2026-05-291-34/+34
| | | | | | | | | | | | | | | | | These constants represent buffer sizes in bytes, not string lengths. While here, move MAX in EXEC_PATHS_MAXLEN at start, like the other constants. While here, fix the prefix of the old MAC_RULE_STRING_LEN accordingly. No functional change. Reviewed by: bapt Fixes: 8aac90f18aef ("mac_do: add a new MAC/do policy and mdo(1) utility") Fixes: 9818224174c4 ("MAC/do: Executable paths feature (GSoC 2025's final state)") MFC after: 1 month Sponsored by: The FreeBSD Foundation Pull Request: https://ron-dev.freebsd.org/FreeBSD/src/pulls/38
* MAC/do: Executable paths: Accept an empty stringOlivier Certner2026-05-291-6/+0
| | | | | | | | | | | | This effectively allows to disable mac_do(4) by setting the executable paths to an empty string, realizing a symmetry with rules to be leveraged in subsequent commits. Reviewed by: bapt Fixes: 9818224174c4 ("MAC/do: Executable paths feature (GSoC 2025's final state)") MFC after: 1 month Sponsored by: The FreeBSD Foundation Pull Request: https://ron-dev.freebsd.org/FreeBSD/src/pulls/38
* MAC/do: Document and assert when parse error objects must be builtOlivier Certner2026-05-291-32/+50
| | | | | | | | | | | | | | | | | | | | | | | | The invariant is that parse_*() functions must create a parse error object and return it through their 'parse_error' argument if and only if they return an error code (non-zero). Add assertions checking this invariant in various places, and in particular in the new parse_exec_paths(), to be future proof. Change the contract of parse_and_set_conf() so that the caller is required to pass a NULL '*parse_error'. Remove useless resetting of '*parse_error' to NULL. While here, remove a test that is always true thanks to this invariant and that was recently introduced with the "executable paths" feature. No functional change intended. Reviewed by: bapt MFC after: 1 month Sponsored by: The FreeBSD Foundation Pull Request: https://ron-dev.freebsd.org/FreeBSD/src/pulls/38
* MAC/do: check_proc(): Remove a superfluous 'if'Olivier Certner2026-05-291-6/+5
| | | | | | | | | No functional change (intended). Reviewed by: bapt MFC after: 1 month Sponsored by: The FreeBSD Foundation Pull Request: https://ron-dev.freebsd.org/FreeBSD/src/pulls/38
* MAC/do: Expand "conf" to "configuration" in a panic message on INVARIANTSOlivier Certner2026-05-291-2/+2
| | | | | | | | | | No functional change. Reviewed by: bapt Fixes: 9818224174c4 ("MAC/do: Executable paths feature (GSoC 2025's final state)") MFC after: 1 month Sponsored by: The FreeBSD Foundation Pull Request: https://ron-dev.freebsd.org/FreeBSD/src/pulls/38
* MAC/do: Fix recently-introduced commentsOlivier Certner2026-05-291-14/+25
| | | | | | | | Reviewed by: bapt Fixes: 9818224174c4 ("MAC/do: Executable paths feature (GSoC 2025's final state)") MFC after: 1 month Sponsored by: The FreeBSD Foundation Pull Request: https://ron-dev.freebsd.org/FreeBSD/src/pulls/38
* MAC/do: Make it style(9) compliant againOlivier Certner2026-05-291-70/+96
| | | | | | | | | | | | | | | Fix too long lines, declarations not at head of block, improper indentation and superfluous whitespace coming from the previous commit introducing the configurable executable paths feature. While here, fix some older improper comment formatting. Reviewed by: bapt Fixes: 6c3def74e2de ("MAC/do: Support multiple users and groups as single rule's targets") Fixes: 9818224174c4 ("MAC/do: Executable paths feature (GSoC 2025's final state)") MFC after: 1 month Sponsored by: The FreeBSD Foundation Pull Request: https://ron-dev.freebsd.org/FreeBSD/src/pulls/38
* MAC/do: Update copyrightOlivier Certner2026-05-291-0/+1
| | | | | | | | | | Add Kushagra to account for the commit adding the "executable paths" feature. Reviewed by: bapt MFC after: 1 month Sponsored by: The FreeBSD Foundation Pull Request: https://ron-dev.freebsd.org/FreeBSD/src/pulls/38
* MAC/do: Executable paths feature (GSoC 2025's final state)Kushagra Srivastava2026-05-291-159/+422
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | By design, mac_do(4) only authorizes credentials change requests if they are issued by a process spawned from '/usr/bin/mdo'. The executable paths feature introduces some flexibility by allowing to change that path, thus allowing another executable to make requests, and to use multiple such paths (up to 8 in the current implementation). Its purpose is to enable thin jails scenarios where mdo(1) may not be at its canonical path ('/usr/bin/mdo') and to allow experimenting with other userland programs leveraging setcred(2). Configuration of executable paths is per-jail and intentionally works completely similarly with rules. It is accessible from within a jail through the 'security.mac.do.exec_paths' sysctl knob and from outside a jail through the 'mac.do.exec_paths' jail parameter. This commit groups the verbatim changes of the following commits that Kushagra Srivastava, our GSoC 2025 student, created in his GitHub repository (https://github.com/thesynthax/freebsd-src), branch 'task/exec-paths-refactor': mac_do(4): Complete refactor of allowed executable paths feature mac_do(4): Fixed changing security.mac.do.* knobs in inheritance mode mac_do(4): Debugging rules and exec_paths leak on destroy mac_do(4): Deep copy rules mac_do(4): Fixed leak mac_do(4): fixed various bugs, structs inlined, leaks remain mac_do(4): MAC/do working in jail, leaks decreased mac_do(4): MAC/do fixed, works in host and jails, leaks removed mac_do(4): style Frozen log for these commits: https://github.com/OlCe2/freebsd-src/compare/main...14fdc49fb29265fac5d0daf95a13d0dce325c951. The corresponding pull request is at: https://github.com/OlCe2/freebsd-src/pull/2. The GSoC's final state of this code still has a number of problems that are fixed in subsequent commits. It is however committed separately to clearly delineate Kushagra's work. Reviewed by: olce (amendments to come, see above) MFC after: 1 month Relnotes: yes Sponsored by: Google LLC (GSoC 2025) Sponsored by: The FreeBSD Foundation (review, commit) Pull Request: https://ron-dev.freebsd.org/FreeBSD/src/pulls/38
* mac_seeotheruids: allow specificgid to be a list of groupsKyle Evans2026-04-231-10/+164
| | | | | | | | | | | | | | | | | | | The specificgid functionality has historically allowed only a single group to be exempt, but in practice one might want a few services to be exempt for reasons. From a security perspective, we probably don't want to encourage unrelated users to be grouped together solely for this purpose, as that creates one point of shared access that could be used for nefarious purposes. Normalize the group list as we do cr_groups to allow for linear matching rather than quadratic, we just need to account for the differences in FreeBSD 15.0+ where cr_groups is entirely supplementary groups vs. earlier versions, where cr_groups[0] is the egid and the rest is sorted. Reviewed by: csjp, des (earlier version) Sponsored by: Klara, Inc. Differential Revision: https://reviews.freebsd.org/D56592
* kern: mac: bump the MAC_VERSION for 16.xKyle Evans2026-04-231-1/+2
| | | | | Reviewed by: bapt Differential Revision: https://reviews.freebsd.org/D55703
* kern: mac: sprinkle a bit of const correctnessKyle Evans2026-04-232-8/+8
| | | | | | | | | | | | | | | mpc_name and mpc_fullname are string literals in correct usage, so they should really be const instead. mpc_ops aren't typically const, but the framework shouldn't be doing anything to clobber it; thus, good to constify it as a reminder. Switch to using a slightly more semantically correct `void **` in the fastpath bits while we're here, since we only do arithmetic on the outer layer of pointer and compare the inner to a pointer-typed (NULL). Reviewed by: bapt Differential Revision: https://reviews.freebsd.org/D55702
* kern: vfs: add MAC checks for mount/unmount/updateKyle Evans2026-04-235-0/+134
| | | | | | | | | | | | | | | | | | | The unmount check is straightforward and only really needs the struct mount and flags used, in case a MAC policy wants to reject force-unmounts or do special handling for FSID-based unmounts. The mount check offers as much information as I think might be of interest to a MAC policy: the vnode to be mounted on, vfsconf, and applicable mount options. XNU also has a later version that just takes a struct mount for everything that VFS_MOUNT() has to offer, but my draft policy doesn't need any of that. It also doesn't really need the unmount check, but it seems reasonable to add it while I'm here. The update check similarly passes the flags/options for the operation, along with the struct mount and label. Reviewed by: kib, olce Differential Revision: https://reviews.freebsd.org/D55601
* audit: Fix logging of IPv6 addressesAndrew Gallatin2026-04-212-3/+16
| | | | | | | | | | - kaudit_to_bsm: Log IPv6 as well as IPv4 and unix addrs - au_to_sock_inet128: Treat ports the same way as au_to_sock_inet32() as just pushing a uint16 causes byte ordering problems on little endian. Differential Revision: https://reviews.freebsd.org/D39633 Sponsored by: Netflix Reviewed by: csjp
* MAC/do: Comments: Rephrase one, fix a typo in anotherOlivier Certner2026-03-211-4/+5
| | | | | | | | No functional change. MFC after: 3 days Event: AsiaBSDCon 2026 Sponsored by: The FreeBSD Foundation
* kern: mac: add a prison_cleanup entry pointKyle Evans2026-02-144-0/+22
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The MAC framework provides a lot of useful functionality that can be configured per-jail without requiring the use of labels. Having another entry point that we invoke just for general prison cleanup rather than freeing the label is useful to allow a module that can otherwise work off of a series of MAC entry points + sysctls for configuration to free its per-jail configuration without having to bring in osd(9). One such example in the wild is HardenedBSD's secadm, but some of my own personal use had wanted it as well- it was simply overlooked in the final version because my first policy made more sense with labels. On that note, it's expected that prison_cleanup and prison_destroy_label will effectively be mutually exclusive -- the former only used when a label isn't needed, the latter when it is. Note that prison_cleanup isn't perfectly symmetrical w.r.t. prison_created: the latter takes a label as well, because it's called later in jail setup and a better point for propagation than when the label is created. As discussed with olce@, we may want to later revisit the notion that struct labels get passed around explicitly along with the referenced object and consider stripping them from all entry points in favor of an object -> label accessor or something. __FreeBSD_version bumped to force a rebuild of MAC policies. Reviewed by: olce Differential Revision: https://reviews.freebsd.org/D54833
* audit: handle AUE_PDWAITKonstantin Belousov2026-01-251-0/+10
| | | | | | | | Reviewed by: asomers, markj Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D54592
* sys: add AUE_PDRFORKKonstantin Belousov2026-01-251-0/+18
| | | | | | | | Reviewed by: asomers, markj Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D54592
* jail(3): fix common usage after mac.label supportKyle Evans2026-01-201-6/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Nobody else's mac.conf(5) has any entries for jails, so they get a trivial ENOENT and we fail before we can fetch any jail parameters. Most notably, this breaks `jls -s` / `jls -n` if you do not have any loaded policy that applies jail labels. Add an entry that works for everyone, and hardcode that as an ENOENT fallback in libjail to provide a smoother transition. This is probably not harmful to leave in long-term, since mac.conf(5) will override it. This unearthed one additional issue, in that mac_get_prison() in the MAC framework handled the no-label-policies bit wrong. We don't want to break jail utilities enumerating jail parameters automatically, so we must ingest the label in all cases -- we can still use it as a small optimization to avoid trying to copy out any label. We will break things if a non-optional element is specified in the copied in label, but that's expected. The APIs dedicated to jaildescs remain unphased, since they won't be used in the same way. Fixes: db3b39f063d9f05 ("libjail: extend struct handlers [...]") Fixes: bd55cbb50c58876 ("kern: add a mac.label jail parameter") Reported by: jlduran (on behalf of Jenkins) Reviewed by: jlduran Differential Revision: https://reviews.freebsd.org/D54786
* kern: add a mac.label jail parameterKyle Evans2026-01-162-0/+164
| | | | | | | | | Have it take a `struct mac` and we'll paper over the difference for jail(8)/jls(8) in libjail(3). The mac_syscalls.h model is taken from mac_set_proc_*() that were previously done. Reviewed by: olce Differential Revision: https://reviews.freebsd.org/D53958
* kern: mac: pull mac_label_copyin_string outKyle Evans2026-01-161-18/+30
| | | | | | | | | | | | A future commit to the area will further our jail integration and add a use for this: the struct mac itself was already copied in as part of vfs_buildopts(), so we only need to copyin the strings. We add an explicit flag argument because the jail operation will need to do it while holding the prison lock. Reviewed by: olce Differential Revision: https://reviews.freebsd.org/D53957