Print this page
12306 XPG4v2 slave pty behaviour should generally be disabled
Reviewed by: Robert Mustacchi <rm@fingolfin.org>
Change-ID: I7ccd399c22866f34dd20c6bb9d28e77ba4e24c67


   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 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  22 /*        All Rights Reserved   */
  23 
  24 
  25 /*
  26  * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
  27  * Copyright 2017 Joyent, Inc.
  28  * Copyright 2019 OmniOS Community Edition (OmniOSce) Association.
  29  */
  30 
  31 #include <sys/types.h>
  32 #include <sys/sysmacros.h>
  33 #include <sys/param.h>
  34 #include <sys/errno.h>
  35 #include <sys/signal.h>
  36 #include <sys/stat.h>
  37 #include <sys/proc.h>
  38 #include <sys/cred.h>
  39 #include <sys/user.h>
  40 #include <sys/vnode.h>
  41 #include <sys/file.h>
  42 #include <sys/stream.h>
  43 #include <sys/strsubr.h>
  44 #include <sys/stropts.h>
  45 #include <sys/tihdr.h>
  46 #include <sys/var.h>
  47 #include <sys/poll.h>
  48 #include <sys/termio.h>


  61 #include <sys/vtrace.h>
  62 #include <sys/debug.h>
  63 #include <sys/strredir.h>
  64 #include <sys/fs/fifonode.h>
  65 #include <sys/fs/snode.h>
  66 #include <sys/strlog.h>
  67 #include <sys/strsun.h>
  68 #include <sys/project.h>
  69 #include <sys/kbio.h>
  70 #include <sys/msio.h>
  71 #include <sys/tty.h>
  72 #include <sys/ptyvar.h>
  73 #include <sys/vuid_event.h>
  74 #include <sys/modctl.h>
  75 #include <sys/sunddi.h>
  76 #include <sys/sunldi_impl.h>
  77 #include <sys/autoconf.h>
  78 #include <sys/policy.h>
  79 #include <sys/dld.h>
  80 #include <sys/zone.h>

  81 #include <c2/audit.h>
  82 
  83 /*
  84  * This define helps improve the readability of streams code while
  85  * still maintaining a very old streams performance enhancement.  The
  86  * performance enhancement basically involved having all callers
  87  * of straccess() perform the first check that straccess() will do
  88  * locally before actually calling straccess().  (There by reducing
  89  * the number of unnecessary calls to straccess().)
  90  */
  91 #define i_straccess(x, y)       ((stp->sd_sidp == NULL) ? 0 : \
  92                                     (stp->sd_vnode->v_type == VFIFO) ? 0 : \
  93                                     straccess((x), (y)))
  94 
  95 /*
  96  * what is mblk_pull_len?
  97  *
  98  * If a streams message consists of many short messages,
  99  * a performance degradation occurs from copyout overhead.
 100  * To decrease the per mblk overhead, messages that are


 214         /*
 215          * push new module and call its open routine via qattach
 216          */
 217         if ((error = qattach(qp, devp, 0, crp, fp, B_FALSE)) != 0)
 218                 return (error);
 219 
 220         /*
 221          * Check to see if caller wants a STREAMS anchor
 222          * put at this place in the stream, and add if so.
 223          */
 224         mutex_enter(&stp->sd_lock);
 225         if (anchor == stp->sd_pushcnt) {
 226                 stp->sd_anchor = stp->sd_pushcnt;
 227                 stp->sd_anchorzone = anchor_zoneid;
 228         }
 229         mutex_exit(&stp->sd_lock);
 230 
 231         return (0);
 232 }
 233 












































 234 /*
 235  * Open a stream device.
 236  */
 237 int
 238 stropen(vnode_t *vp, dev_t *devp, int flag, cred_t *crp)
 239 {
 240         struct stdata *stp;
 241         queue_t *qp;
 242         int s;
 243         dev_t dummydev, savedev;
 244         struct autopush *ap;
 245         struct dlautopush dlap;
 246         int error = 0;
 247         ssize_t rmin, rmax;
 248         int cloneopen;
 249         queue_t *brq;
 250         major_t major;
 251         str_stack_t *ss;
 252         zoneid_t zoneid;
 253         uint_t anchor;


 532                          */
 533                         zoneid = crgetzoneid(crp);
 534                         if (zoneid != GLOBAL_ZONEID)
 535                                 goto retryap;
 536                 }
 537                 goto opendone;
 538         }
 539         anchor = ap->ap_anchor;
 540         zoneid = crgetzoneid(crp);
 541         for (s = 0; s < ap->ap_npush; s++) {
 542                 error = push_mod(qp, &dummydev, stp, ap->ap_list[s],
 543                     anchor, crp, zoneid);
 544                 if (error != 0)
 545                         break;
 546         }
 547         sad_ap_rele(ap, ss);
 548         netstack_rele(ss->ss_netstack);
 549 
 550 opendone:
 551 





 552         /*
 553          * let specfs know that open failed part way through
 554          */
 555         if (error) {
 556                 mutex_enter(&stp->sd_lock);
 557                 stp->sd_flag |= STREOPENFAIL;
 558                 mutex_exit(&stp->sd_lock);
 559         }
 560 
 561         /*
 562          * Wake up others that are waiting for stream to be created.
 563          */
 564         mutex_enter(&stp->sd_lock);
 565         stp->sd_flag &= ~STWOPEN;
 566 
 567         /*
 568          * As a performance concern we are caching the values of
 569          * q_minpsz and q_maxpsz of the module below the stream
 570          * head in the stream head.
 571          */
 572         mutex_enter(QLOCK(stp->sd_wrq->q_next));
 573         rmin = stp->sd_wrq->q_next->q_minpsz;
 574         rmax = stp->sd_wrq->q_next->q_maxpsz;
 575         mutex_exit(QLOCK(stp->sd_wrq->q_next));




   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 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  22 /*        All Rights Reserved   */
  23 
  24 
  25 /*
  26  * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
  27  * Copyright 2017 Joyent, Inc.
  28  * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
  29  */
  30 
  31 #include <sys/types.h>
  32 #include <sys/sysmacros.h>
  33 #include <sys/param.h>
  34 #include <sys/errno.h>
  35 #include <sys/signal.h>
  36 #include <sys/stat.h>
  37 #include <sys/proc.h>
  38 #include <sys/cred.h>
  39 #include <sys/user.h>
  40 #include <sys/vnode.h>
  41 #include <sys/file.h>
  42 #include <sys/stream.h>
  43 #include <sys/strsubr.h>
  44 #include <sys/stropts.h>
  45 #include <sys/tihdr.h>
  46 #include <sys/var.h>
  47 #include <sys/poll.h>
  48 #include <sys/termio.h>


  61 #include <sys/vtrace.h>
  62 #include <sys/debug.h>
  63 #include <sys/strredir.h>
  64 #include <sys/fs/fifonode.h>
  65 #include <sys/fs/snode.h>
  66 #include <sys/strlog.h>
  67 #include <sys/strsun.h>
  68 #include <sys/project.h>
  69 #include <sys/kbio.h>
  70 #include <sys/msio.h>
  71 #include <sys/tty.h>
  72 #include <sys/ptyvar.h>
  73 #include <sys/vuid_event.h>
  74 #include <sys/modctl.h>
  75 #include <sys/sunddi.h>
  76 #include <sys/sunldi_impl.h>
  77 #include <sys/autoconf.h>
  78 #include <sys/policy.h>
  79 #include <sys/dld.h>
  80 #include <sys/zone.h>
  81 #include <sys/ptms.h>
  82 #include <c2/audit.h>
  83 
  84 /*
  85  * This define helps improve the readability of streams code while
  86  * still maintaining a very old streams performance enhancement.  The
  87  * performance enhancement basically involved having all callers
  88  * of straccess() perform the first check that straccess() will do
  89  * locally before actually calling straccess().  (There by reducing
  90  * the number of unnecessary calls to straccess().)
  91  */
  92 #define i_straccess(x, y)       ((stp->sd_sidp == NULL) ? 0 : \
  93                                     (stp->sd_vnode->v_type == VFIFO) ? 0 : \
  94                                     straccess((x), (y)))
  95 
  96 /*
  97  * what is mblk_pull_len?
  98  *
  99  * If a streams message consists of many short messages,
 100  * a performance degradation occurs from copyout overhead.
 101  * To decrease the per mblk overhead, messages that are


 215         /*
 216          * push new module and call its open routine via qattach
 217          */
 218         if ((error = qattach(qp, devp, 0, crp, fp, B_FALSE)) != 0)
 219                 return (error);
 220 
 221         /*
 222          * Check to see if caller wants a STREAMS anchor
 223          * put at this place in the stream, and add if so.
 224          */
 225         mutex_enter(&stp->sd_lock);
 226         if (anchor == stp->sd_pushcnt) {
 227                 stp->sd_anchor = stp->sd_pushcnt;
 228                 stp->sd_anchorzone = anchor_zoneid;
 229         }
 230         mutex_exit(&stp->sd_lock);
 231 
 232         return (0);
 233 }
 234 
 235 static int
 236 xpg4_fixup(queue_t *qp, dev_t *devp, struct stdata *stp, cred_t *crp)
 237 {
 238         static const char *ptsmods[] = {
 239             "ptem", "ldterm", "ttcompat"
 240         };
 241         dev_t dummydev = *devp;
 242         struct strioctl strioc;
 243         zoneid_t zoneid;
 244         int32_t rval;
 245         uint_t i;
 246 
 247         /*
 248          * Push modules required for the slave PTY to have terminal
 249          * semantics out of the box; this is required by XPG4v2.
 250          * These three modules are flagged as single-instance so that
 251          * the system will never end up with duplicate copies pushed
 252          * onto a stream.
 253          */
 254 
 255         zoneid = crgetzoneid(crp);
 256         for (i = 0; i < ARRAY_SIZE(ptsmods); i++) {
 257                 int error;
 258 
 259                 error = push_mod(qp, &dummydev, stp, ptsmods[i], 0,
 260                     crp, zoneid);
 261                 if (error != 0)
 262                         return (error);
 263         }
 264 
 265         /*
 266          * Send PTSSTTY down the stream
 267          */
 268 
 269         strioc.ic_cmd = PTSSTTY;
 270         strioc.ic_timout = 0;
 271         strioc.ic_len = 0;
 272         strioc.ic_dp = NULL;
 273 
 274         (void) strdoioctl(stp, &strioc, FNATIVE, K_TO_K, crp, &rval);
 275 
 276         return (0);
 277 }
 278 
 279 /*
 280  * Open a stream device.
 281  */
 282 int
 283 stropen(vnode_t *vp, dev_t *devp, int flag, cred_t *crp)
 284 {
 285         struct stdata *stp;
 286         queue_t *qp;
 287         int s;
 288         dev_t dummydev, savedev;
 289         struct autopush *ap;
 290         struct dlautopush dlap;
 291         int error = 0;
 292         ssize_t rmin, rmax;
 293         int cloneopen;
 294         queue_t *brq;
 295         major_t major;
 296         str_stack_t *ss;
 297         zoneid_t zoneid;
 298         uint_t anchor;


 577                          */
 578                         zoneid = crgetzoneid(crp);
 579                         if (zoneid != GLOBAL_ZONEID)
 580                                 goto retryap;
 581                 }
 582                 goto opendone;
 583         }
 584         anchor = ap->ap_anchor;
 585         zoneid = crgetzoneid(crp);
 586         for (s = 0; s < ap->ap_npush; s++) {
 587                 error = push_mod(qp, &dummydev, stp, ap->ap_list[s],
 588                     anchor, crp, zoneid);
 589                 if (error != 0)
 590                         break;
 591         }
 592         sad_ap_rele(ap, ss);
 593         netstack_rele(ss->ss_netstack);
 594 
 595 opendone:
 596 
 597         if (error == 0 &&
 598             (stp->sd_flag & (STRISTTY|STRXPG4TTY)) == (STRISTTY|STRXPG4TTY)) {
 599                 error = xpg4_fixup(qp, devp, stp, crp);
 600         }
 601 
 602         /*
 603          * let specfs know that open failed part way through
 604          */
 605         if (error != 0) {
 606                 mutex_enter(&stp->sd_lock);
 607                 stp->sd_flag |= STREOPENFAIL;
 608                 mutex_exit(&stp->sd_lock);
 609         }
 610 
 611         /*
 612          * Wake up others that are waiting for stream to be created.
 613          */
 614         mutex_enter(&stp->sd_lock);
 615         stp->sd_flag &= ~STWOPEN;
 616 
 617         /*
 618          * As a performance concern we are caching the values of
 619          * q_minpsz and q_maxpsz of the module below the stream
 620          * head in the stream head.
 621          */
 622         mutex_enter(QLOCK(stp->sd_wrq->q_next));
 623         rmin = stp->sd_wrq->q_next->q_minpsz;
 624         rmax = stp->sd_wrq->q_next->q_maxpsz;
 625         mutex_exit(QLOCK(stp->sd_wrq->q_next));