|Summary:||login: Extend and add features to session (struct)|
|Component:||kern||Assignee:||freebsd-bugs (Nobody) <bugs>|
|Severity:||Affects Some People||CC:||cem|
|Priority:||---||Keywords:||feature, needs-patch, security|
Description jau 2019-06-04 08:25:57 UTC
As already mentioned in the summary this is not actually a bug report per se, but a proposal to extend the OS with completely new functionality. - 1st I would like to propose making the session login name field sort of write-once-read-many (WORM) field when kern.securelevel is above 0. That would allow setting the login name once for each new session when it has not been set before. Making it immutable when it has been set would give he field content quite a lot credibility later for security related actions or logging. - 2nd I would like to propose adding a few completely new data items in the session struct. These would be the address family and source address for any IPC connections independent of whether it is LOCAL/UNIX or over a proper network connection. Maybe even the protocol and source port should be included when applicable. Obviously making such fields WORM similarly to what I proposed for session login name above would be logical. The benefit of having such address data available in a reliable manner later in the session would make it very hard for any user or process to hide the true origin of the session. That would further allow for better security related decisions based on where the session originates. Maybe some services, their features, or actions should be limited purely to local users, to users in a certain city, to users in a certain larger geographic region, to users within a certain country, to users on a certain continent, or maybe users from within any EU country but not others, etc. In many cases the application server only inherits a local socket or a pty from the actual network daemon. Without seeing the actual network socket the child process has no access to the origin information available through calls to getpeername() and getsockopt(). This then leads to weird attempts to pass the true session origin to child processes in environment variables (e.g SSH_CLIENT) or to other unreliable ad hoc methods to passing on the information while leaving it in worst case modifiable to an intruder. In some cases there might have to be distinct versions of the same service provided to users from distinct origins. In some cases the difference might be just a display of a different legal notification. In other cases there might be additional features for users from a certain origin and reduced features for other. Number 2 above would naturally make the session struct quite large if the longest possible local path name would have to fit in for LOCAL domain origins. OTOH that increase would not cause a serious memory load because there is only one session struct shared by all processes within a session. From my point of view such relatively small sacrifice in memory would be quite reasonable.
Comment 1 Conrad Meyer 2019-06-04 15:52:49 UTC
Re: (1): s_login is only modified by setlogin(2), which requires PRIV_PROC_SETLOGIN, which ... is always permitted for the current process on its session. Each time it is set, it produces an audit record, AUDIT_ARG_LOGIN(). You could conceivably add a flag to session 'has_login_been_set', set it as appropriate, and check it in priv_check PRIV_PROC_SETLOGIN under securelevel. But why? What does it mean to restrict setlogin(2) to "new" sessions? Users can always just create a new process and make it the new session leader (setsid() or setpgid()). The old process gets a new "login" on its associated session. Re: (2): I don't think this metadata makes much sense in session. It's out of line with existing session metadata (mostly tracking process group and controlling terminal -- heavily tied to shell login and process groups). In particular, sessions are a process concept, not a thread one. There is no guarantee that all httpds follow the model required for this to make sense. And if you have to fix httpds, you might as well just pass the information to the worker in some side channel; either environment variables, or a pipe, or shared memory segment. I guess the target network daemon is sshd, which is single threaded, and for that it might work? But it doesn't really generalize, IMO.