60 #include <sys/debug.h>
61 #include <sys/strredir.h>
62 #include <sys/fs/fifonode.h>
63 #include <sys/fs/snode.h>
64 #include <sys/strlog.h>
65 #include <sys/strsun.h>
66 #include <sys/project.h>
67 #include <sys/kbio.h>
68 #include <sys/msio.h>
69 #include <sys/tty.h>
70 #include <sys/ptyvar.h>
71 #include <sys/vuid_event.h>
72 #include <sys/modctl.h>
73 #include <sys/sunddi.h>
74 #include <sys/sunldi_impl.h>
75 #include <sys/autoconf.h>
76 #include <sys/policy.h>
77 #include <sys/dld.h>
78 #include <sys/zone.h>
79 #include <c2/audit.h>
80
81 /*
82 * This define helps improve the readability of streams code while
83 * still maintaining a very old streams performance enhancement. The
84 * performance enhancement basically involved having all callers
85 * of straccess() perform the first check that straccess() will do
86 * locally before actually calling straccess(). (There by reducing
87 * the number of unnecessary calls to straccess().)
88 */
89 #define i_straccess(x, y) ((stp->sd_sidp == NULL) ? 0 : \
90 (stp->sd_vnode->v_type == VFIFO) ? 0 : \
91 straccess((x), (y)))
92
93 /*
94 * what is mblk_pull_len?
95 *
96 * If a streams message consists of many short messages,
97 * a performance degradation occurs from copyout overhead.
98 * To decrease the per mblk overhead, messages that are
99 * likely to consist of many small mblks are pulled up into
125 * The "new semantics" are that TIOCGETP returns B38400 for
126 * sg_[io]speed if the corresponding value is over B38400, and that
127 * TIOCSET[PN] accept B38400 in these cases to mean "retain current
128 * bit rate."
129 */
130 int sgttyb_handling = 1;
131 static boolean_t sgttyb_complaint;
132
133 /* don't push drcompat module by default on Style-2 streams */
134 static int push_drcompat = 0;
135
136 /*
137 * id value used to distinguish between different ioctl messages
138 */
139 static uint32_t ioc_id;
140
141 static void putback(struct stdata *, queue_t *, mblk_t *, int);
142 static void strcleanall(struct vnode *);
143 static int strwsrv(queue_t *);
144 static int strdocmd(struct stdata *, struct strcmd *, cred_t *);
145
146 /*
147 * qinit and module_info structures for stream head read and write queues
148 */
149 struct module_info strm_info = { 0, "strrhead", 0, INFPSZ, STRHIGH, STRLOW };
150 struct module_info stwm_info = { 0, "strwhead", 0, 0, 0, 0 };
151 struct qinit strdata = { strrput, NULL, NULL, NULL, NULL, &strm_info };
152 struct qinit stwdata = { NULL, strwsrv, NULL, NULL, NULL, &stwm_info };
153 struct module_info fiform_info = { 0, "fifostrrhead", 0, PIPE_BUF, FIFOHIWAT,
154 FIFOLOWAT };
155 struct module_info fifowm_info = { 0, "fifostrwhead", 0, 0, 0, 0 };
156 struct qinit fifo_strdata = { strrput, NULL, NULL, NULL, NULL, &fiform_info };
157 struct qinit fifo_stwdata = { NULL, strwsrv, NULL, NULL, NULL, &fifowm_info };
158
159 extern kmutex_t strresources; /* protects global resources */
160 extern kmutex_t muxifier; /* single-threads multiplexor creation */
161
162 static boolean_t msghasdata(mblk_t *bp);
163 #define msgnodata(bp) (!msghasdata(bp))
164
379 stp->sd_sigflags = 0;
380 stp->sd_mark = NULL;
381 stp->sd_closetime = STRTIMOUT;
382 stp->sd_sidp = NULL;
383 stp->sd_pgidp = NULL;
384 stp->sd_vnode = vp;
385 stp->sd_rerror = 0;
386 stp->sd_werror = 0;
387 stp->sd_wroff = 0;
388 stp->sd_tail = 0;
389 stp->sd_iocblk = NULL;
390 stp->sd_cmdblk = NULL;
391 stp->sd_pushcnt = 0;
392 stp->sd_qn_minpsz = 0;
393 stp->sd_qn_maxpsz = INFPSZ - 1; /* used to check for initialization */
394 stp->sd_maxblk = INFPSZ;
395 qp->q_ptr = _WR(qp)->q_ptr = stp;
396 STREAM(qp) = STREAM(_WR(qp)) = stp;
397 vp->v_stream = stp;
398 mutex_exit(&vp->v_lock);
399 if (vp->v_type == VFIFO) {
400 stp->sd_flag |= OLDNDELAY;
401 /*
402 * This means, both for pipes and fifos
403 * strwrite will send SIGPIPE if the other
404 * end is closed. For putmsg it depends
405 * on whether it is a XPG4_2 application
406 * or not
407 */
408 stp->sd_wput_opt = SW_SIGPIPE;
409
410 /* setq might sleep in kmem_alloc - avoid holding locks. */
411 setq(qp, &fifo_strdata, &fifo_stwdata, NULL, QMTSAFE,
412 SQ_CI|SQ_CO, B_FALSE);
413
414 set_qend(qp);
415 stp->sd_strtab = fifo_getinfo();
416 _WR(qp)->q_nfsrv = _WR(qp);
417 qp->q_nfsrv = qp;
418 /*
5665 return (strcopyout(&pgrp, (void *)arg, sizeof (pid_t),
5666 copyflag));
5667 }
5668
5669 case TIOCSCTTY:
5670 {
5671 return (strctty(stp));
5672 }
5673
5674 case TIOCNOTTY:
5675 {
5676 /* freectty() always assumes curproc. */
5677 if (freectty(B_FALSE) != 0)
5678 return (0);
5679 return (ENOTTY);
5680 }
5681
5682 case FIONBIO:
5683 case FIOASYNC:
5684 return (0); /* handled by the upper layer */
5685 }
5686 }
5687
5688 /*
5689 * Custom free routine used for M_PASSFP messages.
5690 */
5691 static void
5692 free_passfp(struct k_strrecvfd *srf)
5693 {
5694 (void) closef(srf->fp);
5695 kmem_free(srf, sizeof (struct k_strrecvfd) + sizeof (frtn_t));
5696 }
5697
5698 /* ARGSUSED */
5699 int
5700 do_sendfp(struct stdata *stp, struct file *fp, struct cred *cr)
5701 {
5702 queue_t *qp, *nextqp;
5703 struct k_strrecvfd *srf;
5704 mblk_t *mp;
8595 if (update) {
8596 stp->sd_sigflags = 0;
8597 for (ssp = stp->sd_siglist; ssp; ssp = ssp->ss_next)
8598 stp->sd_sigflags |= ssp->ss_events;
8599 }
8600 mutex_exit(&stp->sd_lock);
8601 }
8602
8603 /*
8604 * Return B_TRUE if there is data in the message, B_FALSE otherwise.
8605 */
8606 static boolean_t
8607 msghasdata(mblk_t *bp)
8608 {
8609 for (; bp; bp = bp->b_cont)
8610 if (bp->b_datap->db_type == M_DATA) {
8611 ASSERT(bp->b_wptr >= bp->b_rptr);
8612 if (bp->b_wptr > bp->b_rptr)
8613 return (B_TRUE);
8614 }
8615 return (B_FALSE);
8616 }
|
60 #include <sys/debug.h>
61 #include <sys/strredir.h>
62 #include <sys/fs/fifonode.h>
63 #include <sys/fs/snode.h>
64 #include <sys/strlog.h>
65 #include <sys/strsun.h>
66 #include <sys/project.h>
67 #include <sys/kbio.h>
68 #include <sys/msio.h>
69 #include <sys/tty.h>
70 #include <sys/ptyvar.h>
71 #include <sys/vuid_event.h>
72 #include <sys/modctl.h>
73 #include <sys/sunddi.h>
74 #include <sys/sunldi_impl.h>
75 #include <sys/autoconf.h>
76 #include <sys/policy.h>
77 #include <sys/dld.h>
78 #include <sys/zone.h>
79 #include <c2/audit.h>
80 #include <sys/fcntl.h>
81
82 /*
83 * This define helps improve the readability of streams code while
84 * still maintaining a very old streams performance enhancement. The
85 * performance enhancement basically involved having all callers
86 * of straccess() perform the first check that straccess() will do
87 * locally before actually calling straccess(). (There by reducing
88 * the number of unnecessary calls to straccess().)
89 */
90 #define i_straccess(x, y) ((stp->sd_sidp == NULL) ? 0 : \
91 (stp->sd_vnode->v_type == VFIFO) ? 0 : \
92 straccess((x), (y)))
93
94 /*
95 * what is mblk_pull_len?
96 *
97 * If a streams message consists of many short messages,
98 * a performance degradation occurs from copyout overhead.
99 * To decrease the per mblk overhead, messages that are
100 * likely to consist of many small mblks are pulled up into
126 * The "new semantics" are that TIOCGETP returns B38400 for
127 * sg_[io]speed if the corresponding value is over B38400, and that
128 * TIOCSET[PN] accept B38400 in these cases to mean "retain current
129 * bit rate."
130 */
131 int sgttyb_handling = 1;
132 static boolean_t sgttyb_complaint;
133
134 /* don't push drcompat module by default on Style-2 streams */
135 static int push_drcompat = 0;
136
137 /*
138 * id value used to distinguish between different ioctl messages
139 */
140 static uint32_t ioc_id;
141
142 static void putback(struct stdata *, queue_t *, mblk_t *, int);
143 static void strcleanall(struct vnode *);
144 static int strwsrv(queue_t *);
145 static int strdocmd(struct stdata *, struct strcmd *, cred_t *);
146 static boolean_t is_xti_str(const struct stdata *);
147
148 /*
149 * qinit and module_info structures for stream head read and write queues
150 */
151 struct module_info strm_info = { 0, "strrhead", 0, INFPSZ, STRHIGH, STRLOW };
152 struct module_info stwm_info = { 0, "strwhead", 0, 0, 0, 0 };
153 struct qinit strdata = { strrput, NULL, NULL, NULL, NULL, &strm_info };
154 struct qinit stwdata = { NULL, strwsrv, NULL, NULL, NULL, &stwm_info };
155 struct module_info fiform_info = { 0, "fifostrrhead", 0, PIPE_BUF, FIFOHIWAT,
156 FIFOLOWAT };
157 struct module_info fifowm_info = { 0, "fifostrwhead", 0, 0, 0, 0 };
158 struct qinit fifo_strdata = { strrput, NULL, NULL, NULL, NULL, &fiform_info };
159 struct qinit fifo_stwdata = { NULL, strwsrv, NULL, NULL, NULL, &fifowm_info };
160
161 extern kmutex_t strresources; /* protects global resources */
162 extern kmutex_t muxifier; /* single-threads multiplexor creation */
163
164 static boolean_t msghasdata(mblk_t *bp);
165 #define msgnodata(bp) (!msghasdata(bp))
166
381 stp->sd_sigflags = 0;
382 stp->sd_mark = NULL;
383 stp->sd_closetime = STRTIMOUT;
384 stp->sd_sidp = NULL;
385 stp->sd_pgidp = NULL;
386 stp->sd_vnode = vp;
387 stp->sd_rerror = 0;
388 stp->sd_werror = 0;
389 stp->sd_wroff = 0;
390 stp->sd_tail = 0;
391 stp->sd_iocblk = NULL;
392 stp->sd_cmdblk = NULL;
393 stp->sd_pushcnt = 0;
394 stp->sd_qn_minpsz = 0;
395 stp->sd_qn_maxpsz = INFPSZ - 1; /* used to check for initialization */
396 stp->sd_maxblk = INFPSZ;
397 qp->q_ptr = _WR(qp)->q_ptr = stp;
398 STREAM(qp) = STREAM(_WR(qp)) = stp;
399 vp->v_stream = stp;
400 mutex_exit(&vp->v_lock);
401
402 /*
403 * If this is not a system process, then add it to
404 * the list associated with the stream head.
405 */
406 if (!(curproc->p_flag & SSYS) && is_xti_str(stp))
407 sh_insert_pid(stp, curproc->p_pidp->pid_id);
408
409 if (vp->v_type == VFIFO) {
410 stp->sd_flag |= OLDNDELAY;
411 /*
412 * This means, both for pipes and fifos
413 * strwrite will send SIGPIPE if the other
414 * end is closed. For putmsg it depends
415 * on whether it is a XPG4_2 application
416 * or not
417 */
418 stp->sd_wput_opt = SW_SIGPIPE;
419
420 /* setq might sleep in kmem_alloc - avoid holding locks. */
421 setq(qp, &fifo_strdata, &fifo_stwdata, NULL, QMTSAFE,
422 SQ_CI|SQ_CO, B_FALSE);
423
424 set_qend(qp);
425 stp->sd_strtab = fifo_getinfo();
426 _WR(qp)->q_nfsrv = _WR(qp);
427 qp->q_nfsrv = qp;
428 /*
5675 return (strcopyout(&pgrp, (void *)arg, sizeof (pid_t),
5676 copyflag));
5677 }
5678
5679 case TIOCSCTTY:
5680 {
5681 return (strctty(stp));
5682 }
5683
5684 case TIOCNOTTY:
5685 {
5686 /* freectty() always assumes curproc. */
5687 if (freectty(B_FALSE) != 0)
5688 return (0);
5689 return (ENOTTY);
5690 }
5691
5692 case FIONBIO:
5693 case FIOASYNC:
5694 return (0); /* handled by the upper layer */
5695 case F_ASSOCI_PID:
5696 {
5697 if (crp != kcred)
5698 return (EPERM);
5699 if (is_xti_str(stp))
5700 sh_insert_pid(stp, (pid_t)arg);
5701 return (0);
5702 }
5703 case F_DASSOC_PID:
5704 {
5705 if (crp != kcred)
5706 return (EPERM);
5707 if (is_xti_str(stp))
5708 sh_remove_pid(stp, (pid_t)arg);
5709 return (0);
5710 }
5711 }
5712 }
5713
5714 /*
5715 * Custom free routine used for M_PASSFP messages.
5716 */
5717 static void
5718 free_passfp(struct k_strrecvfd *srf)
5719 {
5720 (void) closef(srf->fp);
5721 kmem_free(srf, sizeof (struct k_strrecvfd) + sizeof (frtn_t));
5722 }
5723
5724 /* ARGSUSED */
5725 int
5726 do_sendfp(struct stdata *stp, struct file *fp, struct cred *cr)
5727 {
5728 queue_t *qp, *nextqp;
5729 struct k_strrecvfd *srf;
5730 mblk_t *mp;
8621 if (update) {
8622 stp->sd_sigflags = 0;
8623 for (ssp = stp->sd_siglist; ssp; ssp = ssp->ss_next)
8624 stp->sd_sigflags |= ssp->ss_events;
8625 }
8626 mutex_exit(&stp->sd_lock);
8627 }
8628
8629 /*
8630 * Return B_TRUE if there is data in the message, B_FALSE otherwise.
8631 */
8632 static boolean_t
8633 msghasdata(mblk_t *bp)
8634 {
8635 for (; bp; bp = bp->b_cont)
8636 if (bp->b_datap->db_type == M_DATA) {
8637 ASSERT(bp->b_wptr >= bp->b_rptr);
8638 if (bp->b_wptr > bp->b_rptr)
8639 return (B_TRUE);
8640 }
8641 return (B_FALSE);
8642 }
8643
8644 /*
8645 * Check whether a stream is an XTI stream or not.
8646 */
8647 static boolean_t
8648 is_xti_str(const struct stdata *stp)
8649 {
8650 struct devnames *dnp;
8651 vnode_t *vn;
8652 major_t major;
8653 if ((vn = stp->sd_vnode) != NULL && vn->v_type == VCHR &&
8654 vn->v_rdev != 0) {
8655 major = getmajor(vn->v_rdev);
8656 dnp = (major != DDI_MAJOR_T_NONE && major >= 0 &&
8657 major < devcnt) ? &devnamesp[major] : NULL;
8658 if (dnp != NULL && dnp->dn_name != NULL &&
8659 (strcmp(dnp->dn_name, "ip") == 0 ||
8660 strcmp(dnp->dn_name, "tcp") == 0 ||
8661 strcmp(dnp->dn_name, "udp") == 0 ||
8662 strcmp(dnp->dn_name, "icmp") == 0 ||
8663 strcmp(dnp->dn_name, "tl") == 0 ||
8664 strcmp(dnp->dn_name, "ip6") == 0 ||
8665 strcmp(dnp->dn_name, "tcp6") == 0 ||
8666 strcmp(dnp->dn_name, "udp6") == 0 ||
8667 strcmp(dnp->dn_name, "icmp6") == 0)) {
8668 return (B_TRUE);
8669 }
8670 }
8671 return (B_FALSE);
8672 }
|