kern_proc.c (a5d8944a83ff8a3aad14197b7aa0800ff9bda95e) kern_proc.c (711fbd17ecb5c73100aeb4991e158efcd50b8e7b)
1/*-
2 * Copyright (c) 1982, 1986, 1989, 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 1512 unchanged lines hidden (view full) ---

1521
1522 if (pa == NULL)
1523 return;
1524 if (refcount_release(&pa->ar_ref))
1525 pargs_free(pa);
1526}
1527
1528static int
1/*-
2 * Copyright (c) 1982, 1986, 1989, 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 1512 unchanged lines hidden (view full) ---

1521
1522 if (pa == NULL)
1523 return;
1524 if (refcount_release(&pa->ar_ref))
1525 pargs_free(pa);
1526}
1527
1528static int
1529proc_read_mem(struct thread *td, struct proc *p, vm_offset_t offset, void* buf,
1530 size_t len)
1531{
1532 struct iovec iov;
1533 struct uio uio;
1534
1535 iov.iov_base = (caddr_t)buf;
1536 iov.iov_len = len;
1537 uio.uio_iov = &iov;
1538 uio.uio_iovcnt = 1;
1539 uio.uio_offset = offset;
1540 uio.uio_resid = (ssize_t)len;
1541 uio.uio_segflg = UIO_SYSSPACE;
1542 uio.uio_rw = UIO_READ;
1543 uio.uio_td = td;
1544
1545 return (proc_rwmem(p, &uio));
1546}
1547
1548static int
1549proc_read_string(struct thread *td, struct proc *p, const char *sptr, char *buf,
1550 size_t len)
1551{
1529proc_read_string(struct thread *td, struct proc *p, const char *sptr, char *buf,
1530 size_t len)
1531{
1552 size_t i;
1553 int error;
1532 ssize_t n;
1554
1533
1555 error = proc_read_mem(td, p, (vm_offset_t)sptr, buf, len);
1556 /*
1534 /*
1557 * Reading the chunk may validly return EFAULT if the string is shorter
1558 * than the chunk and is aligned at the end of the page, assuming the
1559 * next page is not mapped. So if EFAULT is returned do a fallback to
1560 * one byte read loop.
1535 * This may return a short read if the string is shorter than the chunk
1536 * and is aligned at the end of the page, and the following page is not
1537 * mapped.
1561 */
1538 */
1562 if (error == EFAULT) {
1563 for (i = 0; i < len; i++, buf++, sptr++) {
1564 error = proc_read_mem(td, p, (vm_offset_t)sptr, buf, 1);
1565 if (error != 0)
1566 return (error);
1567 if (*buf == '\0')
1568 break;
1569 }
1570 error = 0;
1571 }
1572 return (error);
1539 n = proc_readmem(td, p, (vm_offset_t)sptr, buf, len);
1540 if (n <= 0)
1541 return (ENOMEM);
1542 return (0);
1573}
1574
1575#define PROC_AUXV_MAX 256 /* Safety limit on auxv size. */
1576
1577enum proc_vector_type {
1578 PROC_ARG,
1579 PROC_ENV,
1580 PROC_AUX,

--- 7 unchanged lines hidden (view full) ---

1588 struct freebsd32_ps_strings pss;
1589 Elf32_Auxinfo aux;
1590 vm_offset_t vptr, ptr;
1591 uint32_t *proc_vector32;
1592 char **proc_vector;
1593 size_t vsize, size;
1594 int i, error;
1595
1543}
1544
1545#define PROC_AUXV_MAX 256 /* Safety limit on auxv size. */
1546
1547enum proc_vector_type {
1548 PROC_ARG,
1549 PROC_ENV,
1550 PROC_AUX,

--- 7 unchanged lines hidden (view full) ---

1558 struct freebsd32_ps_strings pss;
1559 Elf32_Auxinfo aux;
1560 vm_offset_t vptr, ptr;
1561 uint32_t *proc_vector32;
1562 char **proc_vector;
1563 size_t vsize, size;
1564 int i, error;
1565
1596 error = proc_read_mem(td, p, (vm_offset_t)(p->p_sysent->sv_psstrings),
1597 &pss, sizeof(pss));
1598 if (error != 0)
1599 return (error);
1566 error = 0;
1567 if (proc_readmem(td, p, (vm_offset_t)p->p_sysent->sv_psstrings, &pss,
1568 sizeof(pss)) != sizeof(pss))
1569 return (ENOMEM);
1600 switch (type) {
1601 case PROC_ARG:
1602 vptr = (vm_offset_t)PTRIN(pss.ps_argvstr);
1603 vsize = pss.ps_nargvstr;
1604 if (vsize > ARG_MAX)
1605 return (ENOEXEC);
1606 size = vsize * sizeof(int32_t);
1607 break;

--- 5 unchanged lines hidden (view full) ---

1613 size = vsize * sizeof(int32_t);
1614 break;
1615 case PROC_AUX:
1616 vptr = (vm_offset_t)PTRIN(pss.ps_envstr) +
1617 (pss.ps_nenvstr + 1) * sizeof(int32_t);
1618 if (vptr % 4 != 0)
1619 return (ENOEXEC);
1620 for (ptr = vptr, i = 0; i < PROC_AUXV_MAX; i++) {
1570 switch (type) {
1571 case PROC_ARG:
1572 vptr = (vm_offset_t)PTRIN(pss.ps_argvstr);
1573 vsize = pss.ps_nargvstr;
1574 if (vsize > ARG_MAX)
1575 return (ENOEXEC);
1576 size = vsize * sizeof(int32_t);
1577 break;

--- 5 unchanged lines hidden (view full) ---

1583 size = vsize * sizeof(int32_t);
1584 break;
1585 case PROC_AUX:
1586 vptr = (vm_offset_t)PTRIN(pss.ps_envstr) +
1587 (pss.ps_nenvstr + 1) * sizeof(int32_t);
1588 if (vptr % 4 != 0)
1589 return (ENOEXEC);
1590 for (ptr = vptr, i = 0; i < PROC_AUXV_MAX; i++) {
1621 error = proc_read_mem(td, p, ptr, &aux, sizeof(aux));
1622 if (error != 0)
1623 return (error);
1591 if (proc_readmem(td, p, ptr, &aux, sizeof(aux)) !=
1592 sizeof(aux))
1593 return (ENOMEM);
1624 if (aux.a_type == AT_NULL)
1625 break;
1626 ptr += sizeof(aux);
1627 }
1628 if (aux.a_type != AT_NULL)
1629 return (ENOEXEC);
1630 vsize = i + 1;
1631 size = vsize * sizeof(aux);
1632 break;
1633 default:
1634 KASSERT(0, ("Wrong proc vector type: %d", type));
1635 return (EINVAL);
1636 }
1637 proc_vector32 = malloc(size, M_TEMP, M_WAITOK);
1594 if (aux.a_type == AT_NULL)
1595 break;
1596 ptr += sizeof(aux);
1597 }
1598 if (aux.a_type != AT_NULL)
1599 return (ENOEXEC);
1600 vsize = i + 1;
1601 size = vsize * sizeof(aux);
1602 break;
1603 default:
1604 KASSERT(0, ("Wrong proc vector type: %d", type));
1605 return (EINVAL);
1606 }
1607 proc_vector32 = malloc(size, M_TEMP, M_WAITOK);
1638 error = proc_read_mem(td, p, vptr, proc_vector32, size);
1639 if (error != 0)
1608 if (proc_readmem(td, p, vptr, proc_vector32, size) != size) {
1609 error = ENOMEM;
1640 goto done;
1610 goto done;
1611 }
1641 if (type == PROC_AUX) {
1642 *proc_vectorp = (char **)proc_vector32;
1643 *vsizep = vsize;
1644 return (0);
1645 }
1646 proc_vector = malloc(vsize * sizeof(char *), M_TEMP, M_WAITOK);
1647 for (i = 0; i < (int)vsize; i++)
1648 proc_vector[i] = PTRIN(proc_vector32[i]);

--- 9 unchanged lines hidden (view full) ---

1658get_proc_vector(struct thread *td, struct proc *p, char ***proc_vectorp,
1659 size_t *vsizep, enum proc_vector_type type)
1660{
1661 struct ps_strings pss;
1662 Elf_Auxinfo aux;
1663 vm_offset_t vptr, ptr;
1664 char **proc_vector;
1665 size_t vsize, size;
1612 if (type == PROC_AUX) {
1613 *proc_vectorp = (char **)proc_vector32;
1614 *vsizep = vsize;
1615 return (0);
1616 }
1617 proc_vector = malloc(vsize * sizeof(char *), M_TEMP, M_WAITOK);
1618 for (i = 0; i < (int)vsize; i++)
1619 proc_vector[i] = PTRIN(proc_vector32[i]);

--- 9 unchanged lines hidden (view full) ---

1629get_proc_vector(struct thread *td, struct proc *p, char ***proc_vectorp,
1630 size_t *vsizep, enum proc_vector_type type)
1631{
1632 struct ps_strings pss;
1633 Elf_Auxinfo aux;
1634 vm_offset_t vptr, ptr;
1635 char **proc_vector;
1636 size_t vsize, size;
1666 int error, i;
1637 int i;
1667
1668#ifdef COMPAT_FREEBSD32
1669 if (SV_PROC_FLAG(p, SV_ILP32) != 0)
1670 return (get_proc_vector32(td, p, proc_vectorp, vsizep, type));
1671#endif
1638
1639#ifdef COMPAT_FREEBSD32
1640 if (SV_PROC_FLAG(p, SV_ILP32) != 0)
1641 return (get_proc_vector32(td, p, proc_vectorp, vsizep, type));
1642#endif
1672 error = proc_read_mem(td, p, (vm_offset_t)(p->p_sysent->sv_psstrings),
1673 &pss, sizeof(pss));
1674 if (error != 0)
1675 return (error);
1643 if (proc_readmem(td, p, (vm_offset_t)p->p_sysent->sv_psstrings, &pss,
1644 sizeof(pss)) != sizeof(pss))
1645 return (ENOMEM);
1676 switch (type) {
1677 case PROC_ARG:
1678 vptr = (vm_offset_t)pss.ps_argvstr;
1679 vsize = pss.ps_nargvstr;
1680 if (vsize > ARG_MAX)
1681 return (ENOEXEC);
1682 size = vsize * sizeof(char *);
1683 break;

--- 20 unchanged lines hidden (view full) ---

1704 /*
1705 * We count the array size reading the aux vectors from the
1706 * stack until AT_NULL vector is returned. So (to keep the code
1707 * simple) we read the process stack twice: the first time here
1708 * to find the size and the second time when copying the vectors
1709 * to the allocated proc_vector.
1710 */
1711 for (ptr = vptr, i = 0; i < PROC_AUXV_MAX; i++) {
1646 switch (type) {
1647 case PROC_ARG:
1648 vptr = (vm_offset_t)pss.ps_argvstr;
1649 vsize = pss.ps_nargvstr;
1650 if (vsize > ARG_MAX)
1651 return (ENOEXEC);
1652 size = vsize * sizeof(char *);
1653 break;

--- 20 unchanged lines hidden (view full) ---

1674 /*
1675 * We count the array size reading the aux vectors from the
1676 * stack until AT_NULL vector is returned. So (to keep the code
1677 * simple) we read the process stack twice: the first time here
1678 * to find the size and the second time when copying the vectors
1679 * to the allocated proc_vector.
1680 */
1681 for (ptr = vptr, i = 0; i < PROC_AUXV_MAX; i++) {
1712 error = proc_read_mem(td, p, ptr, &aux, sizeof(aux));
1713 if (error != 0)
1714 return (error);
1682 if (proc_readmem(td, p, ptr, &aux, sizeof(aux)) !=
1683 sizeof(aux))
1684 return (ENOMEM);
1715 if (aux.a_type == AT_NULL)
1716 break;
1717 ptr += sizeof(aux);
1718 }
1719 /*
1720 * If the PROC_AUXV_MAX entries are iterated over, and we have
1721 * not reached AT_NULL, it is most likely we are reading wrong
1722 * data: either the process doesn't have auxv array or data has

--- 4 unchanged lines hidden (view full) ---

1727 vsize = i + 1;
1728 size = vsize * sizeof(aux);
1729 break;
1730 default:
1731 KASSERT(0, ("Wrong proc vector type: %d", type));
1732 return (EINVAL); /* In case we are built without INVARIANTS. */
1733 }
1734 proc_vector = malloc(size, M_TEMP, M_WAITOK);
1685 if (aux.a_type == AT_NULL)
1686 break;
1687 ptr += sizeof(aux);
1688 }
1689 /*
1690 * If the PROC_AUXV_MAX entries are iterated over, and we have
1691 * not reached AT_NULL, it is most likely we are reading wrong
1692 * data: either the process doesn't have auxv array or data has

--- 4 unchanged lines hidden (view full) ---

1697 vsize = i + 1;
1698 size = vsize * sizeof(aux);
1699 break;
1700 default:
1701 KASSERT(0, ("Wrong proc vector type: %d", type));
1702 return (EINVAL); /* In case we are built without INVARIANTS. */
1703 }
1704 proc_vector = malloc(size, M_TEMP, M_WAITOK);
1735 if (proc_vector == NULL)
1736 return (ENOMEM);
1737 error = proc_read_mem(td, p, vptr, proc_vector, size);
1738 if (error != 0) {
1705 if (proc_readmem(td, p, vptr, proc_vector, size) != size) {
1739 free(proc_vector, M_TEMP);
1706 free(proc_vector, M_TEMP);
1740 return (error);
1707 return (ENOMEM);
1741 }
1742 *proc_vectorp = proc_vector;
1743 *vsizep = vsize;
1744
1745 return (0);
1746}
1747
1748#define GET_PS_STRINGS_CHUNK_SZ 256 /* Chunk size (bytes) for ps_strings operations. */

--- 1341 unchanged lines hidden ---
1708 }
1709 *proc_vectorp = proc_vector;
1710 *vsizep = vsize;
1711
1712 return (0);
1713}
1714
1715#define GET_PS_STRINGS_CHUNK_SZ 256 /* Chunk size (bytes) for ps_strings operations. */

--- 1341 unchanged lines hidden ---