Date: Mon, 12 Nov 2001 14:50:41 -0800 From: Terry Lambert <tlambert2@mindspring.com> To: Robert Watson <rwatson@FreeBSD.org> Cc: freebsd-arch@FreeBSD.org Subject: Re: cur{thread/proc}, or not. Message-ID: <3BF05241.74F895EF@mindspring.com> References: <Pine.NEB.3.96L.1011111101234.11566A-100000@fledge.watson.org>
next in thread | previous in thread | raw e-mail | index | archive | help
Robert Watson wrote: > There are a number of uses of curproc in the netinet code, used to > retrieve credentials for authorization somewhere down the stack, when no > proc or thread pointer has been passed down. I think that the majority of the netinet code can be handled by using the socket credential, instead of the process credential. > With the eventual addition > of td->td_ucred, it will be desirable to use the credential for the > current thread, rather than the proc, which will require locking to use. I think locking credential instances is bad. The real question you want to answer is whether or not the credential instance that was used to acquire a socket should be used continuously from there on out (i.e. it is a grant), or whether it should change when the process credential changes (i.e. it is a lease). You seem to be arguing for a lease. I would argue for a grant. One issue is that there are cases where write permission is tested before each write. There are also cases, where you obtain a privileged socket, and then relinquish privileges after obtaining it; such cases are explicitly modelled on a grant model rather than a lease model. The point is that if the credentials are granted, then a change in credential is not a change of the credential itself, but is instead a copy-on-write proposition. In other words, credentials, once granted, are priviledge stable. If this is the case, then they are written when they are instanced, cloned before they are modified (indeed, it seems that the clone/modify operation must be made atomic), and thus are never written once instanced -- only destroyed on the 1->0 reference transition. If so, then no locking is required, since the LCK CMPXCHG can be utilized to do atomic increment and decrement on the reference counting, without needing locks. > As I > understand it, use of curproc was branded 'undesirable' at some point in > the semi-distant past, and since that time, a reference to 'proc' has been > passed down the stack. With a change to KSE, this has been translated to > references the thread, but the issue remains the same. This comes up in > particular because I have a tree where I have propagated the thread > pointer down if_ioctl in the network stack: the normal ioctl call carries > a thread pointer now, but when it is translated into if_ioctl by the > network stack, that pointer is lost. This raises the question: should we > (in practice) be adding process or thread pointers to many more of the > function arguments, or should we switch to using curproc/curthread > instead. The "curproc" undesirability stems primarily from credentials enforcement during interrupt processing. I think that this is not an insurmountable issue, but I would argue that these are more appropriate for object credentials, where the objects in question are not threads or processes. For example, if we were to process incoming TCP connections up through the "accept" code at interrupt time, one might naievely assume that, since the current socket code down through the accept processing code off the queue filled in at NETISR seems to require a proc credential, that it is therefore necessary to have a proc credential at interrupt time in order to do this processing. The answer is that this is a false assumption, and is predicated on historical code, and nothing more. Specifically, if I need a credential for a newly accepted socket that I am now creating, I can add a reference to the listen socket credential -- I //do not need// a process credential in order to do an accept. There is a lot of this type of fuzzy thinking, asking "how can I propagate the process credential that I used to use for this operation down to the underlying code?", when the real question should be "what is the appropriate credential to use for this operation, and is the process credential really what I want to use in this case?". I think it's possible to get rid of most of the process credential references -- and therefore, most of the proc references -- at all points below the /sys/kern/uipc_socket*.c level. > I don't pretend to have a grasp of all the issues here, so the purpose of > this message is to raise the issues so that I can understand them. I have > a tree where I've eliminated many references to curproc; however, I'm now > wondering if it wouldn't simply be more useful to eliminate many of the > references to struct proc in the function arguments, and use curproc > instead, and add references to ucred (and related ref-counted structures) > as needed for delegation types of situations. In particular, that would > suggest the following changes: I think this is the wrong direction, but if you wanted to do this, I think that you would need to put the cur* symbols into the per CPU private pages. This is problematic in the extreme, because it means that you must set these values each time going down, in order to be able to substitute a per CPU global for the stack reference. I think this is a bad thing, in general, and will lead only to trouble later. I would much rather that the credentials be object referenced off of non-process, non-thread objects, based on whatever the correct scoping really is, for the security model you want to enforce. My "accept" example is only one of a class of changes that could facilitate this. -- Terry To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-arch" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3BF05241.74F895EF>