|
Description
|
Based on Bug 5070257
There is a race condition in kadmin when uadmin is called to shutdown. The relevant portion of code is:
159 if (cmd == A_SHUTDOWN || cmd == A_REBOOT || cmd == A_REMOUNT) {
160 if (!mutex_tryenter(&ualock))
161 return (0);
162 locked = 1;
163 }
164
165 switch (cmd) {
166 case A_SHUTDOWN:
167 {
168 proc_t *p = ttoproc(curthread);
169
170 /*
171 * Release (almost) all of our own resources if we are called
172 * from a user context, however if we are calling kadmin() from
173 * a kernel context then we do not release these resources.
174 */
175 if (p != &p0) {
176 proc_is_exiting(p);
177 if ((error = exitlwps(0)) != 0) {
178 ASSERT(locked)
179 mutex_exit(&ualock);
180 return (error);
181 }
Consider the case of one thread which enters the function, takes ualock on line 160, and proceeds onwards. Add another thread which enters the function, fails the mutex_tryenter on line 160, and returns. Now let the first thread fail the error check on line 177, and return. One thread has returned as if the system were already shutting down, while the other tried to shut down and failed. The system will not shut down.
This should be fixed by having the second thread, that failed to take ualock, wait around until we are certain the system is actually shutting down.
Also, this results in some invocations of the uadmin syscall returning 0 which actually should not return as described in 'man -s 2 uadmin'. This should also be addressed.
|