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