Print this page
15254 %ymm registers not restored after signal handler
15367 x86 getfpregs() summons corrupting %xmm ghosts
15333 want x86 /proc xregs support (libc_db, libproc, mdb, etc.)
15336 want libc functions for extended ucontext_t
15334 want ps_lwphandle-specific reg routines
15328 FPU_CW_INIT mistreats reserved bit
15335 i86pc fpu_subr.c isn't really platform-specific
15332 setcontext(2) isn't actually noreturn
15331 need <sys/stdalign.h>
Change-Id: I7060aa86042dfb989f77fc3323c065ea2eafa9ad
Conflicts:
    usr/src/uts/common/fs/proc/prcontrol.c
    usr/src/uts/intel/os/archdep.c
    usr/src/uts/intel/sys/ucontext.h
    usr/src/uts/intel/syscall/getcontext.c

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/proc/prioctl.c
          +++ new/usr/src/uts/common/fs/proc/prioctl.c
↓ open down ↓ 15 lines elided ↑ open up ↑
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  24   24   * Use is subject to license terms.
  25   25   * Copyright 2019 Joyent, Inc.
       26 + * Copyright 2023 Oxide Computer Company
  26   27   */
  27   28  
  28   29  /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
  29   30  /*        All rights reserved.  */
  30   31  
  31   32  #include <sys/types.h>
  32   33  #include <sys/param.h>
  33   34  #include <sys/vmparam.h>
  34   35  #include <sys/var.h>
  35   36  #include <sys/cmn_err.h>
↓ open down ↓ 166 lines elided ↑ open up ↑
 202  203                  return (ENOTTY);
 203  204  
 204  205          /*
 205  206           * Fail ioctls which are logically "write" requests unless
 206  207           * the user has write permission.
 207  208           */
 208  209          if ((flag & FWRITE) == 0 && isprwrioctl(cmd))
 209  210                  return (EBADF);
 210  211  
 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 +        /*
 212  225           * Perform any necessary copyin() operations before
 213  226           * locking the process.  Helps avoid deadlocks and
 214  227           * improves performance.
 215  228           *
 216  229           * Also, detect invalid ioctl codes here to avoid
 217      -         * locking a process unnnecessarily.
      230 +         * locking a process unnecessarily.
 218  231           *
 219  232           * Also, prepare to allocate space that will be needed below,
 220  233           * case by case.
 221  234           */
 222  235          error = 0;
 223  236          switch (cmd) {
 224  237          case PIOCGETPR:
 225  238                  thingsize = sizeof (proc_t);
 226  239                  break;
 227  240          case PIOCGETU:
↓ open down ↓ 10 lines elided ↑ open up ↑
 238  251          case PIOCSFORK:
 239  252          case PIOCRFORK:
 240  253          case PIOCGREG:
 241  254          case PIOCGFPREG:
 242  255          case PIOCSTATUS:
 243  256          case PIOCLSTATUS:
 244  257          case PIOCPSINFO:
 245  258          case PIOCMAXSIG:
 246  259          case PIOCGXREGSIZE:
 247  260                  break;
 248      -        case PIOCSXREG:         /* set extra registers */
 249  261          case PIOCGXREG:         /* get extra registers */
 250      -#if defined(__sparc)
 251      -                thingsize = sizeof (prxregset_t);
 252      -#else
 253      -                thingsize = 0;
 254      -#endif
      262 +                thingsize = prgetprxregsize(p);
 255  263                  break;
 256  264          case PIOCACTION:
 257  265                  thingsize = (nsig-1) * sizeof (struct sigaction);
 258  266                  break;
 259  267          case PIOCGHOLD:
 260  268          case PIOCNMAP:
 261  269          case PIOCMAP:
 262  270          case PIOCGFAULT:
 263  271          case PIOCCFAULT:
 264  272          case PIOCCRED:
↓ open down ↓ 120 lines elided ↑ open up ↑
 385  393                  thing = kmem_alloc(thingsize, KM_SLEEP);
 386  394          }
 387  395  
 388  396          switch (cmd) {
 389  397          case PIOCPSINFO:
 390  398          case PIOCGETPR:
 391  399          case PIOCUSAGE:
 392  400          case PIOCLUSAGE:
 393  401                  zdisp = ZYES;
 394  402                  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  403          default:
 407  404                  zdisp = ZNO;
 408  405                  break;
 409  406          }
 410  407  
 411  408          if ((error = prlock(pnp, zdisp)) != 0) {
 412  409                  if (thing != NULL)
 413  410                          kmem_free(thing, thingsize);
 414  411                  if (xpnp)
 415  412                          prfreenode(xpnp);
↓ open down ↓ 366 lines elided ↑ open up ↑
 782  779                          /* drop p_lock while touching the lwp's stack */
 783  780                          mutex_exit(&p->p_lock);
 784  781                          prsetprfpregs(lwp, &un.fpregs);
 785  782                          mutex_enter(&p->p_lock);
 786  783                  }
 787  784                  prunlock(pnp);
 788  785                  break;
 789  786  
 790  787          case PIOCGXREGSIZE:     /* get the size of the extra registers */
 791  788          {
 792      -                int xregsize;
 793      -
 794  789                  if (prhasx(p)) {
      790 +                        size_t xregsize;
      791 +                        int abisize;
      792 +
 795  793                          xregsize = prgetprxregsize(p);
 796  794                          prunlock(pnp);
 797      -                        if (copyout(&xregsize, cmaddr, sizeof (xregsize)))
      795 +                        if (xregsize > INT_MAX) {
      796 +                                error = EOVERFLOW;
      797 +                                break;
      798 +                        }
      799 +
      800 +                        abisize = (int)xregsize;
      801 +                        if (copyout(&abisize, cmaddr, sizeof (abisize)))
 798  802                                  error = EFAULT;
 799  803                  } else {
 800  804                          prunlock(pnp);
 801  805                          error = EINVAL; /* No extra register support */
 802  806                  }
 803  807                  break;
 804  808          }
 805  809  
 806  810          case PIOCGXREG:         /* get extra registers */
 807  811                  if (prhasx(p)) {
↓ open down ↓ 10 lines elided ↑ open up ↑
 818  822                  } else {
 819  823                          prunlock(pnp);
 820  824                          error = EINVAL; /* No extra register support */
 821  825                  }
 822  826                  if (thing) {
 823  827                          kmem_free(thing, thingsize);
 824  828                          thing = NULL;
 825  829                  }
 826  830                  break;
 827  831  
 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  832          case PIOCSTATUS:        /* get process/lwp status */
 847  833                  oprgetstatus(t, &un.prstat, VTOZONE(vp));
 848  834                  prunlock(pnp);
 849  835                  if (copyout(&un.prstat, cmaddr, sizeof (un.prstat)))
 850  836                          error = EFAULT;
 851  837                  break;
 852  838  
 853  839          case PIOCLSTATUS:       /* get status for process & all lwps */
 854  840          {
 855  841                  int Nlwp;
↓ open down ↓ 901 lines elided ↑ open up ↑
1757 1743                  return (ENOTTY);
1758 1744  
1759 1745          /*
1760 1746           * Fail ioctls which are logically "write" requests unless
1761 1747           * the user has write permission.
1762 1748           */
1763 1749          if ((flag & FWRITE) == 0 && isprwrioctl(cmd))
1764 1750                  return (EBADF);
1765 1751  
1766 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 +        /*
1767 1765           * Perform any necessary copyin() operations before
1768 1766           * locking the process.  Helps avoid deadlocks and
1769 1767           * improves performance.
1770 1768           *
1771 1769           * Also, detect invalid ioctl codes here to avoid
1772      -         * locking a process unnnecessarily.
     1770 +         * locking a process unnecessarily.
1773 1771           *
1774 1772           * Also, prepare to allocate space that will be needed below,
1775 1773           * case by case.
1776 1774           */
1777 1775          error = 0;
1778 1776          switch (cmd) {
1779 1777          case PIOCGETPR:
1780 1778                  thingsize = sizeof (proc_t);
1781 1779                  break;
1782 1780          case PIOCGETU:
↓ open down ↓ 10 lines elided ↑ open up ↑
1793 1791          case PIOCSFORK:
1794 1792          case PIOCRFORK:
1795 1793          case PIOCGREG:
1796 1794          case PIOCGFPREG:
1797 1795          case PIOCSTATUS:
1798 1796          case PIOCLSTATUS:
1799 1797          case PIOCPSINFO:
1800 1798          case PIOCMAXSIG:
1801 1799          case PIOCGXREGSIZE:
1802 1800                  break;
1803      -        case PIOCSXREG:         /* set extra registers */
1804 1801          case PIOCGXREG:         /* get extra registers */
1805      -#if defined(__sparc)
1806      -                thingsize = sizeof (prxregset_t);
1807      -#else
1808      -                thingsize = 0;
1809      -#endif
     1802 +                thingsize = prgetprxregsize(p);
1810 1803                  break;
1811 1804          case PIOCACTION:
1812 1805                  thingsize = (nsig-1) * sizeof (struct sigaction32);
1813 1806                  break;
1814 1807          case PIOCGHOLD:
1815 1808          case PIOCNMAP:
1816 1809          case PIOCMAP:
1817 1810          case PIOCGFAULT:
1818 1811          case PIOCCFAULT:
1819 1812          case PIOCCRED:
↓ open down ↓ 120 lines elided ↑ open up ↑
1940 1933                  thing = kmem_alloc(thingsize, KM_SLEEP);
1941 1934          }
1942 1935  
1943 1936          switch (cmd) {
1944 1937          case PIOCPSINFO:
1945 1938          case PIOCGETPR:
1946 1939          case PIOCUSAGE:
1947 1940          case PIOCLUSAGE:
1948 1941                  zdisp = ZYES;
1949 1942                  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 1943          default:
1962 1944                  zdisp = ZNO;
1963 1945                  break;
1964 1946          }
1965 1947  
1966 1948          if ((error = prlock(pnp, zdisp)) != 0) {
1967 1949                  if (thing != NULL)
1968 1950                          kmem_free(thing, thingsize);
1969 1951                  if (xpnp)
1970 1952                          prfreenode(xpnp);
↓ open down ↓ 406 lines elided ↑ open up ↑
2377 2359                          /* drop p_lock while touching the lwp's stack */
2378 2360                          mutex_exit(&p->p_lock);
2379 2361                          prsetprfpregs32(lwp, &un32.fpregs);
2380 2362                          mutex_enter(&p->p_lock);
2381 2363                  }
2382 2364                  prunlock(pnp);
2383 2365                  break;
2384 2366  
2385 2367          case PIOCGXREGSIZE:     /* get the size of the extra registers */
2386 2368          {
2387      -                int xregsize;
2388      -
2389 2369                  if (prhasx(p)) {
     2370 +                        size_t xregsize;
     2371 +                        int abisize;
     2372 +
2390 2373                          xregsize = prgetprxregsize(p);
2391 2374                          prunlock(pnp);
2392      -                        if (copyout(&xregsize, cmaddr, sizeof (xregsize)))
     2375 +                        if (xregsize > INT_MAX) {
     2376 +                                error = EOVERFLOW;
     2377 +                                break;
     2378 +                        }
     2379 +
     2380 +                        abisize = (int)xregsize;
     2381 +                        if (copyout(&abisize, cmaddr, sizeof (abisize)))
2393 2382                                  error = EFAULT;
2394 2383                  } else {
2395 2384                          prunlock(pnp);
2396 2385                          error = EINVAL; /* No extra register support */
2397 2386                  }
2398 2387                  break;
2399 2388          }
2400 2389  
2401 2390          case PIOCGXREG:         /* get extra registers */
2402 2391                  if (PROCESS_NOT_32BIT(p))
↓ open down ↓ 8 lines elided ↑ open up ↑
2411 2400                                  prgetprxregs(lwp, thing);
2412 2401                                  mutex_enter(&p->p_lock);
2413 2402                          }
2414 2403                  }
2415 2404                  prunlock(pnp);
2416 2405                  if (error == 0 &&
2417 2406                      copyout(thing, cmaddr, thingsize))
2418 2407                          error = EFAULT;
2419 2408                  if (thing) {
2420 2409                          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 2410                          thing = NULL;
2442 2411                  }
2443 2412                  break;
2444 2413  
2445 2414          case PIOCSTATUS:        /* get process/lwp status */
2446 2415                  if (PROCESS_NOT_32BIT(p)) {
2447 2416                          prunlock(pnp);
2448 2417                          error = EOVERFLOW;
2449 2418                          break;
2450 2419                  }
↓ open down ↓ 1493 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX