kern_prot.c (95973) | kern_prot.c (96886) |
---|---|
1/* 2 * Copyright (c) 1982, 1986, 1989, 1990, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * (c) UNIX System Laboratories, Inc. 5 * All or some portions of this file are derived from material licensed 6 * to the University of California by American Telephone and Telegraph 7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 * the permission of UNIX System Laboratories, Inc. --- 23 unchanged lines hidden (view full) --- 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 * 39 * @(#)kern_prot.c 8.6 (Berkeley) 1/21/94 | 1/* 2 * Copyright (c) 1982, 1986, 1989, 1990, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * (c) UNIX System Laboratories, Inc. 5 * All or some portions of this file are derived from material licensed 6 * to the University of California by American Telephone and Telegraph 7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 * the permission of UNIX System Laboratories, Inc. --- 23 unchanged lines hidden (view full) --- 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 * 39 * @(#)kern_prot.c 8.6 (Berkeley) 1/21/94 |
40 * $FreeBSD: head/sys/kern/kern_prot.c 95973 2002-05-03 07:46:59Z tanimura $ | 40 * $FreeBSD: head/sys/kern/kern_prot.c 96886 2002-05-19 00:14:50Z jhb $ |
41 */ 42 43/* 44 * System calls related to processes and protection 45 */ 46 47#include "opt_compat.h" 48 --- 114 unchanged lines hidden (view full) --- 163 error = 0; 164 if (uap->pid == 0) { 165 PROC_LOCK(p); 166 td->td_retval[0] = p->p_pgrp->pg_id; 167 PROC_UNLOCK(p); 168 } else if ((pt = pfind(uap->pid)) == NULL) 169 error = ESRCH; 170 else { | 41 */ 42 43/* 44 * System calls related to processes and protection 45 */ 46 47#include "opt_compat.h" 48 --- 114 unchanged lines hidden (view full) --- 163 error = 0; 164 if (uap->pid == 0) { 165 PROC_LOCK(p); 166 td->td_retval[0] = p->p_pgrp->pg_id; 167 PROC_UNLOCK(p); 168 } else if ((pt = pfind(uap->pid)) == NULL) 169 error = ESRCH; 170 else { |
171 error = p_cansee(p, pt); | 171 error = p_cansee(td, pt); |
172 if (error == 0) 173 td->td_retval[0] = pt->p_pgrp->pg_id; 174 PROC_UNLOCK(pt); 175 } 176 mtx_unlock(&Giant); 177 return (error); 178} 179 --- 19 unchanged lines hidden (view full) --- 199 error = 0; 200 if (uap->pid == 0) { 201 PROC_LOCK(p); 202 td->td_retval[0] = p->p_session->s_sid; 203 PROC_UNLOCK(p); 204 } else if ((pt = pfind(uap->pid)) == NULL) 205 error = ESRCH; 206 else { | 172 if (error == 0) 173 td->td_retval[0] = pt->p_pgrp->pg_id; 174 PROC_UNLOCK(pt); 175 } 176 mtx_unlock(&Giant); 177 return (error); 178} 179 --- 19 unchanged lines hidden (view full) --- 199 error = 0; 200 if (uap->pid == 0) { 201 PROC_LOCK(p); 202 td->td_retval[0] = p->p_session->s_sid; 203 PROC_UNLOCK(p); 204 } else if ((pt = pfind(uap->pid)) == NULL) 205 error = ESRCH; 206 else { |
207 error = p_cansee(p, pt); | 207 error = p_cansee(td, pt); |
208 if (error == 0) 209 td->td_retval[0] = pt->p_session->s_sid; 210 PROC_UNLOCK(pt); 211 } 212 mtx_unlock(&Giant); 213 return (error); 214} 215 --- 201 unchanged lines hidden (view full) --- 417 error = ESRCH; 418 goto done; 419 } 420 if (!inferior(targp)) { 421 PROC_UNLOCK(targp); 422 error = ESRCH; 423 goto done; 424 } | 208 if (error == 0) 209 td->td_retval[0] = pt->p_session->s_sid; 210 PROC_UNLOCK(pt); 211 } 212 mtx_unlock(&Giant); 213 return (error); 214} 215 --- 201 unchanged lines hidden (view full) --- 417 error = ESRCH; 418 goto done; 419 } 420 if (!inferior(targp)) { 421 PROC_UNLOCK(targp); 422 error = ESRCH; 423 goto done; 424 } |
425 if ((error = p_cansee(curproc, targp))) { | 425 if ((error = p_cansee(curthread, targp))) { |
426 PROC_UNLOCK(targp); 427 goto done; 428 } 429 if (targp->p_pgrp == NULL || 430 targp->p_session != curp->p_session) { 431 PROC_UNLOCK(targp); 432 error = EPERM; 433 goto done; --- 922 unchanged lines hidden (view full) --- 1356 if ((error = prison_check(u1, u2))) 1357 return (error); 1358 if ((error = cr_seeotheruids(u1, u2))) 1359 return (error); 1360 return (0); 1361} 1362 1363/*- | 426 PROC_UNLOCK(targp); 427 goto done; 428 } 429 if (targp->p_pgrp == NULL || 430 targp->p_session != curp->p_session) { 431 PROC_UNLOCK(targp); 432 error = EPERM; 433 goto done; --- 922 unchanged lines hidden (view full) --- 1356 if ((error = prison_check(u1, u2))) 1357 return (error); 1358 if ((error = cr_seeotheruids(u1, u2))) 1359 return (error); 1360 return (0); 1361} 1362 1363/*- |
1364 * Determine if p1 "can see" the subject specified by p2. | 1364 * Determine if td "can see" the subject specified by p. |
1365 * Returns: 0 for permitted, an errno value otherwise | 1365 * Returns: 0 for permitted, an errno value otherwise |
1366 * Locks: Sufficient locks to protect p1->p_ucred and p2->p_ucred must 1367 * be held. Normally, p1 will be curproc, and a lock must be held 1368 * for p2. 1369 * References: p1 and p2 must be valid for the lifetime of the call | 1366 * Locks: Sufficient locks to protect p->p_ucred must be held. td really 1367 * should be curthread. 1368 * References: td and p must be valid for the lifetime of the call |
1370 */ 1371int | 1369 */ 1370int |
1372p_cansee(struct proc *p1, struct proc *p2) | 1371p_cansee(struct thread *td, struct proc *p) |
1373{ 1374 1375 /* Wrap cr_cansee() for all functionality. */ | 1372{ 1373 1374 /* Wrap cr_cansee() for all functionality. */ |
1376 return (cr_cansee(p1->p_ucred, p2->p_ucred)); | 1375 KASSERT(td == curthread, ("%s: td not curthread", __func__)); 1376 PROC_LOCK_ASSERT(p, MA_OWNED); 1377 return (cr_cansee(td->td_ucred, p->p_ucred)); |
1377} 1378 1379/*- 1380 * Determine whether cred may deliver the specified signal to proc. 1381 * Returns: 0 for permitted, an errno value otherwise. 1382 * Locks: A lock must be held for proc. 1383 * References: cred and proc must be valid for the lifetime of the call. 1384 */ 1385int 1386cr_cansignal(struct ucred *cred, struct proc *proc, int signum) 1387{ 1388 int error; 1389 | 1378} 1379 1380/*- 1381 * Determine whether cred may deliver the specified signal to proc. 1382 * Returns: 0 for permitted, an errno value otherwise. 1383 * Locks: A lock must be held for proc. 1384 * References: cred and proc must be valid for the lifetime of the call. 1385 */ 1386int 1387cr_cansignal(struct ucred *cred, struct proc *proc, int signum) 1388{ 1389 int error; 1390 |
1391 PROC_LOCK_ASSERT(proc, MA_OWNED); |
|
1390 /* 1391 * Jail semantics limit the scope of signalling to proc in the 1392 * same jail as cred, if cred is in jail. 1393 */ 1394 error = prison_check(cred, proc->p_ucred); 1395 if (error) 1396 return (error); 1397 error = cr_seeotheruids(cred, proc->p_ucred); --- 45 unchanged lines hidden (view full) --- 1443 return (error); 1444 } 1445 1446 return (0); 1447} 1448 1449 1450/*- | 1392 /* 1393 * Jail semantics limit the scope of signalling to proc in the 1394 * same jail as cred, if cred is in jail. 1395 */ 1396 error = prison_check(cred, proc->p_ucred); 1397 if (error) 1398 return (error); 1399 error = cr_seeotheruids(cred, proc->p_ucred); --- 45 unchanged lines hidden (view full) --- 1445 return (error); 1446 } 1447 1448 return (0); 1449} 1450 1451 1452/*- |
1451 * Determine whether p1 may deliver the specified signal to p2. | 1453 * Determine whether td may deliver the specified signal to p. |
1452 * Returns: 0 for permitted, an errno value otherwise | 1454 * Returns: 0 for permitted, an errno value otherwise |
1453 * Locks: Sufficient locks to protect various components of p1 and p2 1454 * must be held. Normally, p1 will be curproc, and a lock must 1455 * be held for p2. 1456 * References: p1 and p2 must be valid for the lifetime of the call | 1455 * Locks: Sufficient locks to protect various components of td and p 1456 * must be held. td must be curthread, and a lock must be 1457 * held for p. 1458 * References: td and p must be valid for the lifetime of the call |
1457 */ 1458int | 1459 */ 1460int |
1459p_cansignal(struct proc *p1, struct proc *p2, int signum) | 1461p_cansignal(struct thread *td, struct proc *p, int signum) |
1460{ 1461 | 1462{ 1463 |
1462 if (p1 == p2) | 1464 KASSERT(td == curthread, ("%s: td not curthread", __func__)); 1465 PROC_LOCK_ASSERT(p, MA_OWNED); 1466 if (td->td_proc == p) |
1463 return (0); 1464 1465 /* 1466 * UNIX signalling semantics require that processes in the same 1467 * session always be able to deliver SIGCONT to one another, 1468 * overriding the remaining protections. 1469 */ | 1467 return (0); 1468 1469 /* 1470 * UNIX signalling semantics require that processes in the same 1471 * session always be able to deliver SIGCONT to one another, 1472 * overriding the remaining protections. 1473 */ |
1470 if (signum == SIGCONT && p1->p_session == p2->p_session) | 1474 /* XXX: This will require an additional lock of some sort. */ 1475 if (signum == SIGCONT && td->td_proc->p_session == p->p_session) |
1471 return (0); 1472 | 1476 return (0); 1477 |
1473 return (cr_cansignal(p1->p_ucred, p2, signum)); | 1478 return (cr_cansignal(td->td_ucred, p, signum)); |
1474} 1475 1476/*- | 1479} 1480 1481/*- |
1477 * Determine whether p1 may reschedule p2. | 1482 * Determine whether td may reschedule p. |
1478 * Returns: 0 for permitted, an errno value otherwise | 1483 * Returns: 0 for permitted, an errno value otherwise |
1479 * Locks: Sufficient locks to protect various components of p1 and p2 1480 * must be held. Normally, p1 will be curproc, and a lock must 1481 * be held for p2. 1482 * References: p1 and p2 must be valid for the lifetime of the call | 1484 * Locks: Sufficient locks to protect various components of td and p 1485 * must be held. td must be curthread, and a lock must 1486 * be held for p. 1487 * References: td and p must be valid for the lifetime of the call |
1483 */ 1484int | 1488 */ 1489int |
1485p_cansched(struct proc *p1, struct proc *p2) | 1490p_cansched(struct thread *td, struct proc *p) |
1486{ 1487 int error; 1488 | 1491{ 1492 int error; 1493 |
1489 if (p1 == p2) | 1494 KASSERT(td == curthread, ("%s: td not curthread", __func__)); 1495 PROC_LOCK_ASSERT(p, MA_OWNED); 1496 if (td->td_proc == p) |
1490 return (0); | 1497 return (0); |
1491 if ((error = prison_check(p1->p_ucred, p2->p_ucred))) | 1498 if ((error = prison_check(td->td_ucred, p->p_ucred))) |
1492 return (error); | 1499 return (error); |
1493 if ((error = cr_seeotheruids(p1->p_ucred, p2->p_ucred))) | 1500 if ((error = cr_seeotheruids(td->td_ucred, p->p_ucred))) |
1494 return (error); | 1501 return (error); |
1495 if (p1->p_ucred->cr_ruid == p2->p_ucred->cr_ruid) | 1502 if (td->td_ucred->cr_ruid == p->p_ucred->cr_ruid) |
1496 return (0); | 1503 return (0); |
1497 if (p1->p_ucred->cr_uid == p2->p_ucred->cr_ruid) | 1504 if (td->td_ucred->cr_uid == p->p_ucred->cr_ruid) |
1498 return (0); | 1505 return (0); |
1499 if (suser_cred(p1->p_ucred, PRISON_ROOT) == 0) | 1506 if (suser_cred(td->td_ucred, PRISON_ROOT) == 0) |
1500 return (0); 1501 1502#ifdef CAPABILITIES | 1507 return (0); 1508 1509#ifdef CAPABILITIES |
1503 if (!cap_check(NULL, p1, CAP_SYS_NICE, PRISON_ROOT)) | 1510 if (!cap_check(NULL, td, CAP_SYS_NICE, PRISON_ROOT)) |
1504 return (0); 1505#endif 1506 1507 return (EPERM); 1508} 1509 1510/* 1511 * The 'unprivileged_proc_debug' flag may be used to disable a variety of --- 7 unchanged lines hidden (view full) --- 1519 * XXX: data declarations should be together near the beginning of the file. 1520 */ 1521static int unprivileged_proc_debug = 1; 1522SYSCTL_INT(_security_bsd, OID_AUTO, unprivileged_proc_debug, CTLFLAG_RW, 1523 &unprivileged_proc_debug, 0, 1524 "Unprivileged processes may use process debugging facilities"); 1525 1526/*- | 1511 return (0); 1512#endif 1513 1514 return (EPERM); 1515} 1516 1517/* 1518 * The 'unprivileged_proc_debug' flag may be used to disable a variety of --- 7 unchanged lines hidden (view full) --- 1526 * XXX: data declarations should be together near the beginning of the file. 1527 */ 1528static int unprivileged_proc_debug = 1; 1529SYSCTL_INT(_security_bsd, OID_AUTO, unprivileged_proc_debug, CTLFLAG_RW, 1530 &unprivileged_proc_debug, 0, 1531 "Unprivileged processes may use process debugging facilities"); 1532 1533/*- |
1527 * Determine whether p1 may debug p2. | 1534 * Determine whether td may debug p. |
1528 * Returns: 0 for permitted, an errno value otherwise | 1535 * Returns: 0 for permitted, an errno value otherwise |
1529 * Locks: Sufficient locks to protect various components of p1 and p2 1530 * must be held. Normally, p1 will be curproc, and a lock must 1531 * be held for p2. 1532 * References: p1 and p2 must be valid for the lifetime of the call | 1536 * Locks: Sufficient locks to protect various components of td and p 1537 * must be held. td must be curthread, and a lock must 1538 * be held for p. 1539 * References: td and p must be valid for the lifetime of the call |
1533 */ 1534int | 1540 */ 1541int |
1535p_candebug(struct proc *p1, struct proc *p2) | 1542p_candebug(struct thread *td, struct proc *p) |
1536{ 1537 int credentialchanged, error, grpsubset, i, uidsubset; 1538 | 1543{ 1544 int credentialchanged, error, grpsubset, i, uidsubset; 1545 |
1546 KASSERT(td == curthread, ("%s: td not curthread", __func__)); 1547 PROC_LOCK_ASSERT(p, MA_OWNED); |
|
1539 if (!unprivileged_proc_debug) { | 1548 if (!unprivileged_proc_debug) { |
1540 error = suser_cred(p1->p_ucred, PRISON_ROOT); | 1549 error = suser_cred(td->td_ucred, PRISON_ROOT); |
1541 if (error) 1542 return (error); 1543 } | 1550 if (error) 1551 return (error); 1552 } |
1544 if (p1 == p2) | 1553 if (td->td_proc == p) |
1545 return (0); | 1554 return (0); |
1546 if ((error = prison_check(p1->p_ucred, p2->p_ucred))) | 1555 if ((error = prison_check(td->td_ucred, p->p_ucred))) |
1547 return (error); | 1556 return (error); |
1548 if ((error = cr_seeotheruids(p1->p_ucred, p2->p_ucred))) | 1557 if ((error = cr_seeotheruids(td->td_ucred, p->p_ucred))) |
1549 return (error); 1550 1551 /* | 1558 return (error); 1559 1560 /* |
1552 * Is p2's group set a subset of p1's effective group set? This 1553 * includes p2's egid, group access list, rgid, and svgid. | 1561 * Is p's group set a subset of td's effective group set? This 1562 * includes p's egid, group access list, rgid, and svgid. |
1554 */ 1555 grpsubset = 1; | 1563 */ 1564 grpsubset = 1; |
1556 for (i = 0; i < p2->p_ucred->cr_ngroups; i++) { 1557 if (!groupmember(p2->p_ucred->cr_groups[i], p1->p_ucred)) { | 1565 for (i = 0; i < p->p_ucred->cr_ngroups; i++) { 1566 if (!groupmember(p->p_ucred->cr_groups[i], td->td_ucred)) { |
1558 grpsubset = 0; 1559 break; 1560 } 1561 } 1562 grpsubset = grpsubset && | 1567 grpsubset = 0; 1568 break; 1569 } 1570 } 1571 grpsubset = grpsubset && |
1563 groupmember(p2->p_ucred->cr_rgid, p1->p_ucred) && 1564 groupmember(p2->p_ucred->cr_svgid, p1->p_ucred); | 1572 groupmember(p->p_ucred->cr_rgid, td->td_ucred) && 1573 groupmember(p->p_ucred->cr_svgid, td->td_ucred); |
1565 1566 /* | 1574 1575 /* |
1567 * Are the uids present in p2's credential equal to p1's 1568 * effective uid? This includes p2's euid, svuid, and ruid. | 1576 * Are the uids present in p's credential equal to td's 1577 * effective uid? This includes p's euid, svuid, and ruid. |
1569 */ | 1578 */ |
1570 uidsubset = (p1->p_ucred->cr_uid == p2->p_ucred->cr_uid && 1571 p1->p_ucred->cr_uid == p2->p_ucred->cr_svuid && 1572 p1->p_ucred->cr_uid == p2->p_ucred->cr_ruid); | 1579 uidsubset = (td->td_ucred->cr_uid == p->p_ucred->cr_uid && 1580 td->td_ucred->cr_uid == p->p_ucred->cr_svuid && 1581 td->td_ucred->cr_uid == p->p_ucred->cr_ruid); |
1573 1574 /* 1575 * Has the credential of the process changed since the last exec()? 1576 */ | 1582 1583 /* 1584 * Has the credential of the process changed since the last exec()? 1585 */ |
1577 credentialchanged = (p2->p_flag & P_SUGID); | 1586 credentialchanged = (p->p_flag & P_SUGID); |
1578 1579 /* | 1587 1588 /* |
1580 * If p2's gids aren't a subset, or the uids aren't a subset, | 1589 * If p's gids aren't a subset, or the uids aren't a subset, |
1581 * or the credential has changed, require appropriate privilege | 1590 * or the credential has changed, require appropriate privilege |
1582 * for p1 to debug p2. For POSIX.1e capabilities, this will | 1591 * for td to debug p. For POSIX.1e capabilities, this will |
1583 * require CAP_SYS_PTRACE. 1584 */ 1585 if (!grpsubset || !uidsubset || credentialchanged) { | 1592 * require CAP_SYS_PTRACE. 1593 */ 1594 if (!grpsubset || !uidsubset || credentialchanged) { |
1586 error = suser_cred(p1->p_ucred, PRISON_ROOT); | 1595 error = suser_cred(td->td_ucred, PRISON_ROOT); |
1587 if (error) 1588 return (error); 1589 } 1590 1591 /* Can't trace init when securelevel > 0. */ | 1596 if (error) 1597 return (error); 1598 } 1599 1600 /* Can't trace init when securelevel > 0. */ |
1592 if (p2 == initproc) { 1593 error = securelevel_gt(p1->p_ucred, 0); | 1601 if (p == initproc) { 1602 error = securelevel_gt(td->td_ucred, 0); |
1594 if (error) 1595 return (error); 1596 } 1597 1598 /* 1599 * Can't trace a process that's currently exec'ing. 1600 * XXX: Note, this is not a security policy decision, it's a 1601 * basic correctness/functionality decision. Therefore, this check 1602 * should be moved to the caller's of p_candebug(). 1603 */ | 1603 if (error) 1604 return (error); 1605 } 1606 1607 /* 1608 * Can't trace a process that's currently exec'ing. 1609 * XXX: Note, this is not a security policy decision, it's a 1610 * basic correctness/functionality decision. Therefore, this check 1611 * should be moved to the caller's of p_candebug(). 1612 */ |
1604 if ((p2->p_flag & P_INEXEC) != 0) | 1613 if ((p->p_flag & P_INEXEC) != 0) |
1605 return (EAGAIN); 1606 1607 return (0); 1608} 1609 1610/*- 1611 * Determine whether the subject represented by cred can "see" a socket. 1612 * Returns: 0 for permitted, ENOENT otherwise. --- 333 unchanged lines hidden --- | 1614 return (EAGAIN); 1615 1616 return (0); 1617} 1618 1619/*- 1620 * Determine whether the subject represented by cred can "see" a socket. 1621 * Returns: 0 for permitted, ENOENT otherwise. --- 333 unchanged lines hidden --- |