Deleted Added
full compact
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 ---