Hello, Outlined in this mail is my proposal for integrating the traditional BSD securelevel with the kauth(9) interface. This mail lightly uses some kauth(9) terminology; an online version of the man-page is available from http://www.bsd.org.il/netbsd/kauth.9.html It was discussed in the past ("The reason for securelevel") that we need to separate the impact of securelevel to allow finer-grained control over what can or cannot be done in our system. For example, an administrator might like to customize the impact of the securelevel combining several implications from securelevel 2 but otherwise all the affects of securelevel 1. On the other hand, some people may not want any of this. The solution must allow people who would like to stick to the current model of securelevel the ability to do so. The proposal in this mail is divided in two. The first part will discuss the proposed kernel backend to replace securelevel. The second part will discuss possible (optional) userland enhancements that will allow the finer-grained access mentioned above to people who need it. The only issue with replacing the securelevel implementation is third-party LKMs. This is because they may rely on the availability of a "securelevel" variable. For example, a driver that according to the securelevel allows or denies a certain request. The magnitude of this issue needs to be realized: this affects only LKMs that were written specifically for BSD systems, as a vanilla Linux (and perhaps Solaris? I don't know) kernel does not provide a securelevel mechanism. The first part of this proposal will also describe possible solutions to this problem. 1. Kernel backend At the moment, the kernel implementation of securelevel is very simple: a single (raise-only, sysctl-able) variable, "securelevel", that is checked in various parts of the kernel whenever a securelevel-relevant operation is requested. This means that the interface to securelevel is also its implementation. The suggested change is inspecting references to securelevel, creating a list of common requests made that rely on securelevel. This list should be able to describe the operations used in our kernel, and offer operations that third-party LKMs may need. Then, we could replace the securelevel variable with a bitmap. With each bit representing a different operation, we could both support fine-grained control over the securelevel by setting the individual bits, or the traditional model by setting to specific pre-defined bitmasks that will represent securelevels -1 to 2. There is, however, a special case to this (pointed out by Thor Lancelot Simon in a private mail) where going from multi-user to single-user mode. At the moment, what happens is that the securelevel is lowered to 0 when that happens, and when exiting the single-user shell the securelevel is raised back to 1. Later, the startup scripts may raise it further depending on /etc/sysctl.conf. In a case of multiple knobs, a mechanism for saving state will have to be in place so that the current bits set in the securelevel bitmap will be restored once the single-user shell is exited. To give an example, if some drivers guards their ioctl() in securelevel > 1, we might introduce a "allow driver ioctl" request that third-party driver LKMs can make. These requests will be implemented as a new kauth(9) scope, called the "system" scope. Giving a code example, if we have something like: /* Don't allow ioctl() requests if securelevel is > 1 */ if (securelevel > 1) return (EPERM); It might be replaced with: /* See if we can issue ioctl() requests */ if (kauth_authorize_system(curproc->p_cred, KAUTH_SYSTEM_DRIVER_IOCTL, NULL) != 0) return (EPERM); (note that this is just for illustration; we might need to pass more arguments to kauth_authorize_system(). That is why an inspection of securelevel references is required.. :) For those who are not too familiar with kauth(9), this authorization request will then be dispatched to the default listener for the system scope. That listener will perform something like this: [...] error = 0; switch (operation) { [...] case KAUTH_SYSTEM_DRIVER_IOCTL: if (securelevel & KAUTH_SYSTEM_DRIVER_IOCTL) error = EPERM; break; [...] } return (error); (if you're asking yourself "why not just do a single if statement to check for the requested operation in securelevel?", the answer is that some securelevel implications also have other considerations taken into account.) Summarizing so far, we've managed to: - Maintain existing traditional interface and implications for people who want it; - Allow finer-grained knobs to be implemented by making sure the kernel backend does not check a single variable, but rather a single "privilege". - Allow future expansion of the securelevel on a per-user basis by passing the user credentials along with the request. ...but we broke compatibility with third-party LKMs that rely on securelevel being a simple integer. Addressing that problem, we have several options: - For people who are interested in keeping the traditional securelevel, this is simple: because our securelevel bitmap will be in a new variable, we can maintain the existing securelevel variable to represent the system's securelevel for third-party LKMs that need it. That is, whenever the securelevel is changed, and the bitmasks are set, we will also modify the securelevel variable. In the NetBSD kernel it will not be used anywhere, but it will exist for third-party LKMs. - For people who are interested in the finer-grained securelevel knobs, this is somewhat more complicated. By changing the meaning of securelevel, a third-party LKM no longer has anything to refer to as a "system security level". I offer two possible solutions: (a) The securelevel variable will be maintained as "third-party LKM securelevel", maintained only for backwards binary compatibility. It will have no meaning in the NetBSD kernel, but will retain the raise-only property of the current securelevel. (b) Third-party LKMs will be encouraged to remove references to securelevel and use the kauth(9) interface, possibly with the operation they want guarded from the list of common operations for the system scope. We can always add more operations to the system scope if they are needed, however authors of third-party LKMs that heavily depend on securelevel's multiple levels will be advised to make use of the new kauth(9) interface's ability to introduce new scopes to the system. An LKM relying on securelevel might consider code like: #ifdef __HAVE_KERNELAUTH /* Use kauth(9) */ #else /* Check securelevel */ #endif /* __HAVE_KERNELAUTH */ To summarize, we maintained binary compatibility with existing LKMs, offer an easy way for LKM authors to adapt to the new kauth(9) interface, and suggest a way for supporting both earlier pre-kauth(9) NetBSD kernels as well as newer ones that do provide the interface. 2. Userland enhancements To properly support multiple-knobs, we'll have to provide a user-interface for accessing them. This is not a problem with our sysctl(9) system, but may pose a problem to third-party scripts that may query or even modify kern.securelevel. Just as with the third-party LKMs, we will continue to maintain kern.securelevel as a "third-party securelevel" that can be used, with the same semantics it has today. Unlike LKMs, "fixing" this issue for third-party software (programs or sciprts) isn't as easy, because the user-interface (sysctl(8) and sysctl(3)) will show either the single knob or multiple knobs depending on how the kernel was compiled. I am not sure about the scale of this issue -- ie. how many references we really have in third-party software -- but my best suggestion at this point is to leave the existing kern.securelevel sysctl knob to function as a "third-party reference", not just for LKMs. :) 3. Benefit The changes outlined above are a rough proposal to, first and foremost, integrate the securelevel mechanism with the kauth(9) interface. Although initially the benefit will be minor to people using the traditional securelevel interface, in the future it will allow us to implement features like capabilities or MACs (choose your favorite buzzword ;) -- the required changes to support such mechanisms will be mostly internal to the kauth(9) framework, and not system-wide changes. Waiting for any kind of feedback, -e. -- Elad Efrat
| Bart Van Assche | Integration of SCST in the mainstream Linux kernel |
| Greg KH | [GIT PATCH] driver core patches against 2.6.24 |
| Linus Torvalds | Linux 2.6.27 |
| Linus Torvalds | Linux 2.6.27-rc5 |
git: | |
| Linus Torvalds | Convert 'git blame' to parse_options() |
| Denis Bueno | Recovering from repository corruption |
| Jan Wielemaker | git filter-branch --subdirectory-filter, still a mistery |
| Linus Torvalds | Help with a tcl/tk gui thing.. |
| Richard Stallman | Real men don't attack straw men |
| GVG GVG | ssh_exchange_identification: Connection closed by remote host |
| Marcos Laufer | dmesg IBM x3650 OpenBSD 4.3 |
| Paolo Supino | order |
| Corey Hickey | SFQ: backport some features from ESFQ (try 4) |
| David Miller | Re: [GIT]: Networking |
| KOSAKI Motohiro | [bug?] tg3: Failed to load firmware "tigon/tg3_tso.bin" |
| Natalie Protasevich | [BUG] New Kernel Bugs |
| usb mic not detected | 1 hour ago | Applications and Utilities |
| Problem in Inserting a module | 2 hours ago | Linux kernel |
| Treason Uncloaked | 7 hours ago | Linux kernel |
| Shared swap partition | 18 hours ago | Linux general |
| high memory | 2 days ago | Linux kernel |
| semaphore access speed | 2 days ago | Applications and Utilities |
| the kernel how to power off the machine | 2 days ago | Linux kernel |
| Easter Eggs in windows XP | 2 days ago | Windows |
| Root password | 2 days ago | Linux general |
| Where/when DNOTIFY is used? | 2 days ago | Linux kernel |
