6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 * Copyright 2019 Joyent, Inc.
26 */
27
28 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
29 /* All rights reserved. */
30
31 #include <sys/types.h>
32 #include <sys/param.h>
33 #include <sys/vmparam.h>
34 #include <sys/var.h>
35 #include <sys/cmn_err.h>
36 #include <sys/cred.h>
37 #include <sys/debug.h>
38 #include <sys/errno.h>
39 #include <sys/file.h>
40 #include <sys/inline.h>
41 #include <sys/kmem.h>
42 #include <sys/proc.h>
43 #include <sys/brand.h>
44 #include <sys/sysmacros.h>
45 #include <sys/systm.h>
192 * Support for old /proc interface.
193 */
194 if (pnp->pr_pidfile != NULL) {
195 ASSERT(pnp->pr_type == PR_PIDDIR);
196 vp = pnp->pr_pidfile;
197 pnp = VTOP(vp);
198 ASSERT(pnp->pr_type == PR_PIDFILE);
199 }
200
201 if (pnp->pr_type != PR_PIDFILE && pnp->pr_type != PR_LWPIDFILE)
202 return (ENOTTY);
203
204 /*
205 * Fail ioctls which are logically "write" requests unless
206 * the user has write permission.
207 */
208 if ((flag & FWRITE) == 0 && isprwrioctl(cmd))
209 return (EBADF);
210
211 /*
212 * Perform any necessary copyin() operations before
213 * locking the process. Helps avoid deadlocks and
214 * improves performance.
215 *
216 * Also, detect invalid ioctl codes here to avoid
217 * locking a process unnnecessarily.
218 *
219 * Also, prepare to allocate space that will be needed below,
220 * case by case.
221 */
222 error = 0;
223 switch (cmd) {
224 case PIOCGETPR:
225 thingsize = sizeof (proc_t);
226 break;
227 case PIOCGETU:
228 thingsize = sizeof (user_t);
229 break;
230 case PIOCSTOP:
231 case PIOCWSTOP:
232 case PIOCLWPIDS:
233 case PIOCGTRACE:
234 case PIOCGENTRY:
235 case PIOCGEXIT:
236 case PIOCSRLC:
237 case PIOCRRLC:
238 case PIOCSFORK:
239 case PIOCRFORK:
240 case PIOCGREG:
241 case PIOCGFPREG:
242 case PIOCSTATUS:
243 case PIOCLSTATUS:
244 case PIOCPSINFO:
245 case PIOCMAXSIG:
246 case PIOCGXREGSIZE:
247 break;
248 case PIOCSXREG: /* set extra registers */
249 case PIOCGXREG: /* get extra registers */
250 #if defined(__sparc)
251 thingsize = sizeof (prxregset_t);
252 #else
253 thingsize = 0;
254 #endif
255 break;
256 case PIOCACTION:
257 thingsize = (nsig-1) * sizeof (struct sigaction);
258 break;
259 case PIOCGHOLD:
260 case PIOCNMAP:
261 case PIOCMAP:
262 case PIOCGFAULT:
263 case PIOCCFAULT:
264 case PIOCCRED:
265 case PIOCGROUPS:
266 case PIOCUSAGE:
267 case PIOCLUSAGE:
268 break;
269 case PIOCOPENPD:
270 /*
271 * We will need this below.
272 * Allocate it now, before locking the process.
273 */
274 xpnp = prgetnode(vp, PR_OPAGEDATA);
375 /*
376 * If we need kmem_alloc()d space then we allocate it now, before
377 * grabbing the process lock. Using kmem_alloc(KM_SLEEP) while
378 * holding the process lock leads to deadlock with the clock thread.
379 * (The clock thread wakes up the pageout daemon to free up space.
380 * If the clock thread blocks behind us and we are sleeping waiting
381 * for space, then space may never become available.)
382 */
383 if (thingsize) {
384 ASSERT(thing == NULL);
385 thing = kmem_alloc(thingsize, KM_SLEEP);
386 }
387
388 switch (cmd) {
389 case PIOCPSINFO:
390 case PIOCGETPR:
391 case PIOCUSAGE:
392 case PIOCLUSAGE:
393 zdisp = ZYES;
394 break;
395 case PIOCSXREG: /* set extra registers */
396 /*
397 * perform copyin before grabbing the process lock
398 */
399 if (thing) {
400 if (copyin(cmaddr, thing, thingsize)) {
401 kmem_free(thing, thingsize);
402 return (EFAULT);
403 }
404 }
405 /* fall through... */
406 default:
407 zdisp = ZNO;
408 break;
409 }
410
411 if ((error = prlock(pnp, zdisp)) != 0) {
412 if (thing != NULL)
413 kmem_free(thing, thingsize);
414 if (xpnp)
415 prfreenode(xpnp);
416 return (error);
417 }
418
419 pcp = pnp->pr_common;
420 p = pcp->prc_proc;
421 ASSERT(p != NULL);
422
423 /*
424 * Choose a thread/lwp for the operation.
425 */
772 if (copyout(&un.fpregs, cmaddr, sizeof (un.fpregs)))
773 error = EFAULT;
774 break;
775
776 case PIOCSFPREG: /* set floating-point registers */
777 if (!prhasfp())
778 error = EINVAL; /* No FP support */
779 else if (!ISTOPPED(t) && !VSTOPPED(t) && !DSTOPPED(t))
780 error = EBUSY;
781 else {
782 /* drop p_lock while touching the lwp's stack */
783 mutex_exit(&p->p_lock);
784 prsetprfpregs(lwp, &un.fpregs);
785 mutex_enter(&p->p_lock);
786 }
787 prunlock(pnp);
788 break;
789
790 case PIOCGXREGSIZE: /* get the size of the extra registers */
791 {
792 int xregsize;
793
794 if (prhasx(p)) {
795 xregsize = prgetprxregsize(p);
796 prunlock(pnp);
797 if (copyout(&xregsize, cmaddr, sizeof (xregsize)))
798 error = EFAULT;
799 } else {
800 prunlock(pnp);
801 error = EINVAL; /* No extra register support */
802 }
803 break;
804 }
805
806 case PIOCGXREG: /* get extra registers */
807 if (prhasx(p)) {
808 bzero(thing, thingsize);
809 if (t->t_state == TS_STOPPED || VSTOPPED(t)) {
810 /* drop p_lock to touch the stack */
811 mutex_exit(&p->p_lock);
812 prgetprxregs(lwp, thing);
813 mutex_enter(&p->p_lock);
814 }
815 prunlock(pnp);
816 if (copyout(thing, cmaddr, thingsize))
817 error = EFAULT;
818 } else {
819 prunlock(pnp);
820 error = EINVAL; /* No extra register support */
821 }
822 if (thing) {
823 kmem_free(thing, thingsize);
824 thing = NULL;
825 }
826 break;
827
828 case PIOCSXREG: /* set extra registers */
829 if (!ISTOPPED(t) && !VSTOPPED(t) && !DSTOPPED(t))
830 error = EBUSY;
831 else if (!prhasx(p))
832 error = EINVAL; /* No extra register support */
833 else if (thing) {
834 /* drop p_lock while touching the lwp's stack */
835 mutex_exit(&p->p_lock);
836 prsetprxregs(lwp, thing);
837 mutex_enter(&p->p_lock);
838 }
839 prunlock(pnp);
840 if (thing) {
841 kmem_free(thing, thingsize);
842 thing = NULL;
843 }
844 break;
845
846 case PIOCSTATUS: /* get process/lwp status */
847 oprgetstatus(t, &un.prstat, VTOZONE(vp));
848 prunlock(pnp);
849 if (copyout(&un.prstat, cmaddr, sizeof (un.prstat)))
850 error = EFAULT;
851 break;
852
853 case PIOCLSTATUS: /* get status for process & all lwps */
854 {
855 int Nlwp;
856 int nlwp;
857 prstatus_t *Bprsp;
858 prstatus_t *prsp;
859
860 nlwp = Nlwp = p->p_lwpcnt;
861
862 if (thing && thingsize != (Nlwp+1) * sizeof (prstatus_t)) {
863 kmem_free(thing, thingsize);
864 thing = NULL;
865 }
1747 * Support for old /proc interface.
1748 */
1749 if (pnp->pr_pidfile != NULL) {
1750 ASSERT(pnp->pr_type == PR_PIDDIR);
1751 vp = pnp->pr_pidfile;
1752 pnp = VTOP(vp);
1753 ASSERT(pnp->pr_type == PR_PIDFILE);
1754 }
1755
1756 if (pnp->pr_type != PR_PIDFILE && pnp->pr_type != PR_LWPIDFILE)
1757 return (ENOTTY);
1758
1759 /*
1760 * Fail ioctls which are logically "write" requests unless
1761 * the user has write permission.
1762 */
1763 if ((flag & FWRITE) == 0 && isprwrioctl(cmd))
1764 return (EBADF);
1765
1766 /*
1767 * Perform any necessary copyin() operations before
1768 * locking the process. Helps avoid deadlocks and
1769 * improves performance.
1770 *
1771 * Also, detect invalid ioctl codes here to avoid
1772 * locking a process unnnecessarily.
1773 *
1774 * Also, prepare to allocate space that will be needed below,
1775 * case by case.
1776 */
1777 error = 0;
1778 switch (cmd) {
1779 case PIOCGETPR:
1780 thingsize = sizeof (proc_t);
1781 break;
1782 case PIOCGETU:
1783 thingsize = sizeof (user_t);
1784 break;
1785 case PIOCSTOP:
1786 case PIOCWSTOP:
1787 case PIOCLWPIDS:
1788 case PIOCGTRACE:
1789 case PIOCGENTRY:
1790 case PIOCGEXIT:
1791 case PIOCSRLC:
1792 case PIOCRRLC:
1793 case PIOCSFORK:
1794 case PIOCRFORK:
1795 case PIOCGREG:
1796 case PIOCGFPREG:
1797 case PIOCSTATUS:
1798 case PIOCLSTATUS:
1799 case PIOCPSINFO:
1800 case PIOCMAXSIG:
1801 case PIOCGXREGSIZE:
1802 break;
1803 case PIOCSXREG: /* set extra registers */
1804 case PIOCGXREG: /* get extra registers */
1805 #if defined(__sparc)
1806 thingsize = sizeof (prxregset_t);
1807 #else
1808 thingsize = 0;
1809 #endif
1810 break;
1811 case PIOCACTION:
1812 thingsize = (nsig-1) * sizeof (struct sigaction32);
1813 break;
1814 case PIOCGHOLD:
1815 case PIOCNMAP:
1816 case PIOCMAP:
1817 case PIOCGFAULT:
1818 case PIOCCFAULT:
1819 case PIOCCRED:
1820 case PIOCGROUPS:
1821 case PIOCUSAGE:
1822 case PIOCLUSAGE:
1823 break;
1824 case PIOCOPENPD:
1825 /*
1826 * We will need this below.
1827 * Allocate it now, before locking the process.
1828 */
1829 xpnp = prgetnode(vp, PR_OPAGEDATA);
1930 /*
1931 * If we need kmem_alloc()d space then we allocate it now, before
1932 * grabbing the process lock. Using kmem_alloc(KM_SLEEP) while
1933 * holding the process lock leads to deadlock with the clock thread.
1934 * (The clock thread wakes up the pageout daemon to free up space.
1935 * If the clock thread blocks behind us and we are sleeping waiting
1936 * for space, then space may never become available.)
1937 */
1938 if (thingsize) {
1939 ASSERT(thing == NULL);
1940 thing = kmem_alloc(thingsize, KM_SLEEP);
1941 }
1942
1943 switch (cmd) {
1944 case PIOCPSINFO:
1945 case PIOCGETPR:
1946 case PIOCUSAGE:
1947 case PIOCLUSAGE:
1948 zdisp = ZYES;
1949 break;
1950 case PIOCSXREG: /* set extra registers */
1951 /*
1952 * perform copyin before grabbing the process lock
1953 */
1954 if (thing) {
1955 if (copyin(cmaddr, thing, thingsize)) {
1956 kmem_free(thing, thingsize);
1957 return (EFAULT);
1958 }
1959 }
1960 /* fall through... */
1961 default:
1962 zdisp = ZNO;
1963 break;
1964 }
1965
1966 if ((error = prlock(pnp, zdisp)) != 0) {
1967 if (thing != NULL)
1968 kmem_free(thing, thingsize);
1969 if (xpnp)
1970 prfreenode(xpnp);
1971 return (error);
1972 }
1973
1974 pcp = pnp->pr_common;
1975 p = pcp->prc_proc;
1976 ASSERT(p != NULL);
1977
1978 /*
1979 * Choose a thread/lwp for the operation.
1980 */
2367 break;
2368
2369 case PIOCSFPREG: /* set floating-point registers */
2370 if (!prhasfp())
2371 error = EINVAL; /* No FP support */
2372 else if (PROCESS_NOT_32BIT(p))
2373 error = EOVERFLOW;
2374 else if (!ISTOPPED(t) && !VSTOPPED(t) && !DSTOPPED(t))
2375 error = EBUSY;
2376 else {
2377 /* drop p_lock while touching the lwp's stack */
2378 mutex_exit(&p->p_lock);
2379 prsetprfpregs32(lwp, &un32.fpregs);
2380 mutex_enter(&p->p_lock);
2381 }
2382 prunlock(pnp);
2383 break;
2384
2385 case PIOCGXREGSIZE: /* get the size of the extra registers */
2386 {
2387 int xregsize;
2388
2389 if (prhasx(p)) {
2390 xregsize = prgetprxregsize(p);
2391 prunlock(pnp);
2392 if (copyout(&xregsize, cmaddr, sizeof (xregsize)))
2393 error = EFAULT;
2394 } else {
2395 prunlock(pnp);
2396 error = EINVAL; /* No extra register support */
2397 }
2398 break;
2399 }
2400
2401 case PIOCGXREG: /* get extra registers */
2402 if (PROCESS_NOT_32BIT(p))
2403 error = EOVERFLOW;
2404 else if (!prhasx(p))
2405 error = EINVAL; /* No extra register support */
2406 else {
2407 bzero(thing, thingsize);
2408 if (t->t_state == TS_STOPPED || VSTOPPED(t)) {
2409 /* drop p_lock to touch the stack */
2410 mutex_exit(&p->p_lock);
2411 prgetprxregs(lwp, thing);
2412 mutex_enter(&p->p_lock);
2413 }
2414 }
2415 prunlock(pnp);
2416 if (error == 0 &&
2417 copyout(thing, cmaddr, thingsize))
2418 error = EFAULT;
2419 if (thing) {
2420 kmem_free(thing, thingsize);
2421 thing = NULL;
2422 }
2423 break;
2424
2425 case PIOCSXREG: /* set extra registers */
2426 if (PROCESS_NOT_32BIT(p))
2427 error = EOVERFLOW;
2428 else if (!ISTOPPED(t) && !VSTOPPED(t) && !DSTOPPED(t))
2429 error = EBUSY;
2430 else if (!prhasx(p))
2431 error = EINVAL; /* No extra register support */
2432 else if (thing) {
2433 /* drop p_lock while touching the lwp's stack */
2434 mutex_exit(&p->p_lock);
2435 prsetprxregs(lwp, thing);
2436 mutex_enter(&p->p_lock);
2437 }
2438 prunlock(pnp);
2439 if (thing) {
2440 kmem_free(thing, thingsize);
2441 thing = NULL;
2442 }
2443 break;
2444
2445 case PIOCSTATUS: /* get process/lwp status */
2446 if (PROCESS_NOT_32BIT(p)) {
2447 prunlock(pnp);
2448 error = EOVERFLOW;
2449 break;
2450 }
2451 oprgetstatus32(t, &un32.prstat, VTOZONE(vp));
2452 prunlock(pnp);
2453 if (copyout(&un32.prstat, cmaddr, sizeof (un32.prstat)))
2454 error = EFAULT;
2455 break;
2456
2457 case PIOCLSTATUS: /* get status for process & all lwps */
2458 {
2459 int Nlwp;
2460 int nlwp;
|
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 * Copyright 2019 Joyent, Inc.
26 * Copyright 2023 Oxide Computer Company
27 */
28
29 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
30 /* All rights reserved. */
31
32 #include <sys/types.h>
33 #include <sys/param.h>
34 #include <sys/vmparam.h>
35 #include <sys/var.h>
36 #include <sys/cmn_err.h>
37 #include <sys/cred.h>
38 #include <sys/debug.h>
39 #include <sys/errno.h>
40 #include <sys/file.h>
41 #include <sys/inline.h>
42 #include <sys/kmem.h>
43 #include <sys/proc.h>
44 #include <sys/brand.h>
45 #include <sys/sysmacros.h>
46 #include <sys/systm.h>
193 * Support for old /proc interface.
194 */
195 if (pnp->pr_pidfile != NULL) {
196 ASSERT(pnp->pr_type == PR_PIDDIR);
197 vp = pnp->pr_pidfile;
198 pnp = VTOP(vp);
199 ASSERT(pnp->pr_type == PR_PIDFILE);
200 }
201
202 if (pnp->pr_type != PR_PIDFILE && pnp->pr_type != PR_LWPIDFILE)
203 return (ENOTTY);
204
205 /*
206 * Fail ioctls which are logically "write" requests unless
207 * the user has write permission.
208 */
209 if ((flag & FWRITE) == 0 && isprwrioctl(cmd))
210 return (EBADF);
211
212 /*
213 * The following commands are no longer supported. They were present on
214 * SPARC and were always errors on other platforms. We now explicitly
215 * return ENOTSUP to indicate that this is no longer done.
216 */
217 switch (cmd) {
218 case PIOCSXREG:
219 return (ENOTSUP);
220 default:
221 break;
222 }
223
224 /*
225 * Perform any necessary copyin() operations before
226 * locking the process. Helps avoid deadlocks and
227 * improves performance.
228 *
229 * Also, detect invalid ioctl codes here to avoid
230 * locking a process unnecessarily.
231 *
232 * Also, prepare to allocate space that will be needed below,
233 * case by case.
234 */
235 error = 0;
236 switch (cmd) {
237 case PIOCGETPR:
238 thingsize = sizeof (proc_t);
239 break;
240 case PIOCGETU:
241 thingsize = sizeof (user_t);
242 break;
243 case PIOCSTOP:
244 case PIOCWSTOP:
245 case PIOCLWPIDS:
246 case PIOCGTRACE:
247 case PIOCGENTRY:
248 case PIOCGEXIT:
249 case PIOCSRLC:
250 case PIOCRRLC:
251 case PIOCSFORK:
252 case PIOCRFORK:
253 case PIOCGREG:
254 case PIOCGFPREG:
255 case PIOCSTATUS:
256 case PIOCLSTATUS:
257 case PIOCPSINFO:
258 case PIOCMAXSIG:
259 case PIOCGXREGSIZE:
260 break;
261 case PIOCGXREG: /* get extra registers */
262 thingsize = prgetprxregsize(p);
263 break;
264 case PIOCACTION:
265 thingsize = (nsig-1) * sizeof (struct sigaction);
266 break;
267 case PIOCGHOLD:
268 case PIOCNMAP:
269 case PIOCMAP:
270 case PIOCGFAULT:
271 case PIOCCFAULT:
272 case PIOCCRED:
273 case PIOCGROUPS:
274 case PIOCUSAGE:
275 case PIOCLUSAGE:
276 break;
277 case PIOCOPENPD:
278 /*
279 * We will need this below.
280 * Allocate it now, before locking the process.
281 */
282 xpnp = prgetnode(vp, PR_OPAGEDATA);
383 /*
384 * If we need kmem_alloc()d space then we allocate it now, before
385 * grabbing the process lock. Using kmem_alloc(KM_SLEEP) while
386 * holding the process lock leads to deadlock with the clock thread.
387 * (The clock thread wakes up the pageout daemon to free up space.
388 * If the clock thread blocks behind us and we are sleeping waiting
389 * for space, then space may never become available.)
390 */
391 if (thingsize) {
392 ASSERT(thing == NULL);
393 thing = kmem_alloc(thingsize, KM_SLEEP);
394 }
395
396 switch (cmd) {
397 case PIOCPSINFO:
398 case PIOCGETPR:
399 case PIOCUSAGE:
400 case PIOCLUSAGE:
401 zdisp = ZYES;
402 break;
403 default:
404 zdisp = ZNO;
405 break;
406 }
407
408 if ((error = prlock(pnp, zdisp)) != 0) {
409 if (thing != NULL)
410 kmem_free(thing, thingsize);
411 if (xpnp)
412 prfreenode(xpnp);
413 return (error);
414 }
415
416 pcp = pnp->pr_common;
417 p = pcp->prc_proc;
418 ASSERT(p != NULL);
419
420 /*
421 * Choose a thread/lwp for the operation.
422 */
769 if (copyout(&un.fpregs, cmaddr, sizeof (un.fpregs)))
770 error = EFAULT;
771 break;
772
773 case PIOCSFPREG: /* set floating-point registers */
774 if (!prhasfp())
775 error = EINVAL; /* No FP support */
776 else if (!ISTOPPED(t) && !VSTOPPED(t) && !DSTOPPED(t))
777 error = EBUSY;
778 else {
779 /* drop p_lock while touching the lwp's stack */
780 mutex_exit(&p->p_lock);
781 prsetprfpregs(lwp, &un.fpregs);
782 mutex_enter(&p->p_lock);
783 }
784 prunlock(pnp);
785 break;
786
787 case PIOCGXREGSIZE: /* get the size of the extra registers */
788 {
789 if (prhasx(p)) {
790 size_t xregsize;
791 int abisize;
792
793 xregsize = prgetprxregsize(p);
794 prunlock(pnp);
795 if (xregsize > INT_MAX) {
796 error = EOVERFLOW;
797 break;
798 }
799
800 abisize = (int)xregsize;
801 if (copyout(&abisize, cmaddr, sizeof (abisize)))
802 error = EFAULT;
803 } else {
804 prunlock(pnp);
805 error = EINVAL; /* No extra register support */
806 }
807 break;
808 }
809
810 case PIOCGXREG: /* get extra registers */
811 if (prhasx(p)) {
812 bzero(thing, thingsize);
813 if (t->t_state == TS_STOPPED || VSTOPPED(t)) {
814 /* drop p_lock to touch the stack */
815 mutex_exit(&p->p_lock);
816 prgetprxregs(lwp, thing);
817 mutex_enter(&p->p_lock);
818 }
819 prunlock(pnp);
820 if (copyout(thing, cmaddr, thingsize))
821 error = EFAULT;
822 } else {
823 prunlock(pnp);
824 error = EINVAL; /* No extra register support */
825 }
826 if (thing) {
827 kmem_free(thing, thingsize);
828 thing = NULL;
829 }
830 break;
831
832 case PIOCSTATUS: /* get process/lwp status */
833 oprgetstatus(t, &un.prstat, VTOZONE(vp));
834 prunlock(pnp);
835 if (copyout(&un.prstat, cmaddr, sizeof (un.prstat)))
836 error = EFAULT;
837 break;
838
839 case PIOCLSTATUS: /* get status for process & all lwps */
840 {
841 int Nlwp;
842 int nlwp;
843 prstatus_t *Bprsp;
844 prstatus_t *prsp;
845
846 nlwp = Nlwp = p->p_lwpcnt;
847
848 if (thing && thingsize != (Nlwp+1) * sizeof (prstatus_t)) {
849 kmem_free(thing, thingsize);
850 thing = NULL;
851 }
1733 * Support for old /proc interface.
1734 */
1735 if (pnp->pr_pidfile != NULL) {
1736 ASSERT(pnp->pr_type == PR_PIDDIR);
1737 vp = pnp->pr_pidfile;
1738 pnp = VTOP(vp);
1739 ASSERT(pnp->pr_type == PR_PIDFILE);
1740 }
1741
1742 if (pnp->pr_type != PR_PIDFILE && pnp->pr_type != PR_LWPIDFILE)
1743 return (ENOTTY);
1744
1745 /*
1746 * Fail ioctls which are logically "write" requests unless
1747 * the user has write permission.
1748 */
1749 if ((flag & FWRITE) == 0 && isprwrioctl(cmd))
1750 return (EBADF);
1751
1752 /*
1753 * The following commands are no longer supported. They were present on
1754 * SPARC and were always errors on other platforms. We now explicitly
1755 * return ENOTSUP to indicate that this is no longer done.
1756 */
1757 switch (cmd) {
1758 case PIOCSXREG:
1759 return (ENOTSUP);
1760 default:
1761 break;
1762 }
1763
1764 /*
1765 * Perform any necessary copyin() operations before
1766 * locking the process. Helps avoid deadlocks and
1767 * improves performance.
1768 *
1769 * Also, detect invalid ioctl codes here to avoid
1770 * locking a process unnecessarily.
1771 *
1772 * Also, prepare to allocate space that will be needed below,
1773 * case by case.
1774 */
1775 error = 0;
1776 switch (cmd) {
1777 case PIOCGETPR:
1778 thingsize = sizeof (proc_t);
1779 break;
1780 case PIOCGETU:
1781 thingsize = sizeof (user_t);
1782 break;
1783 case PIOCSTOP:
1784 case PIOCWSTOP:
1785 case PIOCLWPIDS:
1786 case PIOCGTRACE:
1787 case PIOCGENTRY:
1788 case PIOCGEXIT:
1789 case PIOCSRLC:
1790 case PIOCRRLC:
1791 case PIOCSFORK:
1792 case PIOCRFORK:
1793 case PIOCGREG:
1794 case PIOCGFPREG:
1795 case PIOCSTATUS:
1796 case PIOCLSTATUS:
1797 case PIOCPSINFO:
1798 case PIOCMAXSIG:
1799 case PIOCGXREGSIZE:
1800 break;
1801 case PIOCGXREG: /* get extra registers */
1802 thingsize = prgetprxregsize(p);
1803 break;
1804 case PIOCACTION:
1805 thingsize = (nsig-1) * sizeof (struct sigaction32);
1806 break;
1807 case PIOCGHOLD:
1808 case PIOCNMAP:
1809 case PIOCMAP:
1810 case PIOCGFAULT:
1811 case PIOCCFAULT:
1812 case PIOCCRED:
1813 case PIOCGROUPS:
1814 case PIOCUSAGE:
1815 case PIOCLUSAGE:
1816 break;
1817 case PIOCOPENPD:
1818 /*
1819 * We will need this below.
1820 * Allocate it now, before locking the process.
1821 */
1822 xpnp = prgetnode(vp, PR_OPAGEDATA);
1923 /*
1924 * If we need kmem_alloc()d space then we allocate it now, before
1925 * grabbing the process lock. Using kmem_alloc(KM_SLEEP) while
1926 * holding the process lock leads to deadlock with the clock thread.
1927 * (The clock thread wakes up the pageout daemon to free up space.
1928 * If the clock thread blocks behind us and we are sleeping waiting
1929 * for space, then space may never become available.)
1930 */
1931 if (thingsize) {
1932 ASSERT(thing == NULL);
1933 thing = kmem_alloc(thingsize, KM_SLEEP);
1934 }
1935
1936 switch (cmd) {
1937 case PIOCPSINFO:
1938 case PIOCGETPR:
1939 case PIOCUSAGE:
1940 case PIOCLUSAGE:
1941 zdisp = ZYES;
1942 break;
1943 default:
1944 zdisp = ZNO;
1945 break;
1946 }
1947
1948 if ((error = prlock(pnp, zdisp)) != 0) {
1949 if (thing != NULL)
1950 kmem_free(thing, thingsize);
1951 if (xpnp)
1952 prfreenode(xpnp);
1953 return (error);
1954 }
1955
1956 pcp = pnp->pr_common;
1957 p = pcp->prc_proc;
1958 ASSERT(p != NULL);
1959
1960 /*
1961 * Choose a thread/lwp for the operation.
1962 */
2349 break;
2350
2351 case PIOCSFPREG: /* set floating-point registers */
2352 if (!prhasfp())
2353 error = EINVAL; /* No FP support */
2354 else if (PROCESS_NOT_32BIT(p))
2355 error = EOVERFLOW;
2356 else if (!ISTOPPED(t) && !VSTOPPED(t) && !DSTOPPED(t))
2357 error = EBUSY;
2358 else {
2359 /* drop p_lock while touching the lwp's stack */
2360 mutex_exit(&p->p_lock);
2361 prsetprfpregs32(lwp, &un32.fpregs);
2362 mutex_enter(&p->p_lock);
2363 }
2364 prunlock(pnp);
2365 break;
2366
2367 case PIOCGXREGSIZE: /* get the size of the extra registers */
2368 {
2369 if (prhasx(p)) {
2370 size_t xregsize;
2371 int abisize;
2372
2373 xregsize = prgetprxregsize(p);
2374 prunlock(pnp);
2375 if (xregsize > INT_MAX) {
2376 error = EOVERFLOW;
2377 break;
2378 }
2379
2380 abisize = (int)xregsize;
2381 if (copyout(&abisize, cmaddr, sizeof (abisize)))
2382 error = EFAULT;
2383 } else {
2384 prunlock(pnp);
2385 error = EINVAL; /* No extra register support */
2386 }
2387 break;
2388 }
2389
2390 case PIOCGXREG: /* get extra registers */
2391 if (PROCESS_NOT_32BIT(p))
2392 error = EOVERFLOW;
2393 else if (!prhasx(p))
2394 error = EINVAL; /* No extra register support */
2395 else {
2396 bzero(thing, thingsize);
2397 if (t->t_state == TS_STOPPED || VSTOPPED(t)) {
2398 /* drop p_lock to touch the stack */
2399 mutex_exit(&p->p_lock);
2400 prgetprxregs(lwp, thing);
2401 mutex_enter(&p->p_lock);
2402 }
2403 }
2404 prunlock(pnp);
2405 if (error == 0 &&
2406 copyout(thing, cmaddr, thingsize))
2407 error = EFAULT;
2408 if (thing) {
2409 kmem_free(thing, thingsize);
2410 thing = NULL;
2411 }
2412 break;
2413
2414 case PIOCSTATUS: /* get process/lwp status */
2415 if (PROCESS_NOT_32BIT(p)) {
2416 prunlock(pnp);
2417 error = EOVERFLOW;
2418 break;
2419 }
2420 oprgetstatus32(t, &un32.prstat, VTOZONE(vp));
2421 prunlock(pnp);
2422 if (copyout(&un32.prstat, cmaddr, sizeof (un32.prstat)))
2423 error = EFAULT;
2424 break;
2425
2426 case PIOCLSTATUS: /* get status for process & all lwps */
2427 {
2428 int Nlwp;
2429 int nlwp;
|