Print this page
3830 SIGQUEUE_MAX's limit of 32 is too low
Reviewed by: Cedric Blancher <cedric.blancher@gmail.com>
Reviewed by: John Kennedy <john.kennedy@delphix.com>
Reviewed by: Irek Szczesniak <iszczesniak@gmail.com>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/syscall/sigqueue.c
+++ new/usr/src/uts/common/syscall/sigqueue.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
↓ open down ↓ |
18 lines elided |
↑ open up ↑ |
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
26 26
27 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 28
29 -#pragma ident "%Z%%M% %I% %E% SMI"
30 -
31 29 #include <sys/param.h>
32 30 #include <sys/types.h>
33 31 #include <sys/sysmacros.h>
34 32 #include <sys/systm.h>
35 33 #include <sys/errno.h>
36 34 #include <sys/proc.h>
37 35 #include <sys/procset.h>
38 36 #include <sys/fault.h>
39 37 #include <sys/signal.h>
40 38 #include <sys/siginfo.h>
41 39 #include <sys/debug.h>
42 40
41 +extern rctl_hndl_t rc_process_sigqueue;
42 +
43 43 static int
44 44 sigqkill(pid_t pid, sigsend_t *sigsend)
45 45 {
46 46 proc_t *p;
47 47 int error;
48 48
49 49 if ((uint_t)sigsend->sig >= NSIG)
50 50 return (EINVAL);
51 51
52 52 if (pid == -1) {
53 53 procset_t set;
54 54
55 55 setprocset(&set, POP_AND, P_ALL, P_MYID, P_ALL, P_MYID);
56 56 error = sigsendset(&set, sigsend);
57 57 } else if (pid > 0) {
58 58 mutex_enter(&pidlock);
59 59 if ((p = prfind(pid)) == NULL || p->p_stat == SIDL)
60 60 error = ESRCH;
61 61 else {
62 62 error = sigsendproc(p, sigsend);
63 63 if (error == 0 && sigsend->perm == 0)
64 64 error = EPERM;
65 65 }
66 66 mutex_exit(&pidlock);
67 67 } else {
68 68 int nfound = 0;
69 69 pid_t pgid;
70 70
71 71 if (pid == 0)
72 72 pgid = ttoproc(curthread)->p_pgrp;
73 73 else
74 74 pgid = -pid;
75 75
76 76 error = 0;
77 77 mutex_enter(&pidlock);
78 78 for (p = pgfind(pgid); p && !error; p = p->p_pglink) {
79 79 if (p->p_stat != SIDL) {
80 80 nfound++;
81 81 error = sigsendproc(p, sigsend);
82 82 }
83 83 }
84 84 mutex_exit(&pidlock);
85 85 if (nfound == 0)
86 86 error = ESRCH;
87 87 else if (error == 0 && sigsend->perm == 0)
88 88 error = EPERM;
89 89 }
90 90
91 91 return (error);
92 92 }
93 93
94 94
95 95 /*
96 96 * for implementations that don't require binary compatibility,
97 97 * the kill system call may be made into a library call to the
98 98 * sigsend system call
99 99 */
100 100 int
101 101 kill(pid_t pid, int sig)
102 102 {
103 103 int error;
104 104 sigsend_t v;
105 105
106 106 bzero(&v, sizeof (v));
107 107 v.sig = sig;
108 108 v.checkperm = 1;
109 109 v.sicode = SI_USER;
110 110 if ((error = sigqkill(pid, &v)) != 0)
111 111 return (set_errno(error));
112 112 return (0);
113 113 }
↓ open down ↓ |
61 lines elided |
↑ open up ↑ |
114 114
115 115 /*
116 116 * The handling of small unions, like the sigval argument to sigqueue,
117 117 * is architecture dependent. We have adopted the convention that the
118 118 * value itself is passed in the storage which crosses the kernel
119 119 * protection boundary. This procedure will accept a scalar argument,
120 120 * and store it in the appropriate value member of the sigsend_t structure.
121 121 */
122 122 int
123 123 sigqueue(pid_t pid, int sig, /* union sigval */ void *value,
124 - int si_code, int block)
124 + int si_code, int block)
125 125 {
126 126 int error;
127 127 sigsend_t v;
128 128 sigqhdr_t *sqh;
129 129 proc_t *p = curproc;
130 130
131 131 /* The si_code value must indicate the signal will be queued */
132 132 if (pid <= 0 || !sigwillqueue(sig, si_code))
133 133 return (set_errno(EINVAL));
134 134
135 135 if ((sqh = p->p_sigqhdr) == NULL) {
136 + rlim64_t sigqsz_max;
137 +
138 + mutex_enter(&p->p_lock);
139 + sigqsz_max = rctl_enforced_value(rc_process_sigqueue,
140 + p->p_rctls, p);
141 + mutex_exit(&p->p_lock);
142 +
136 143 /* Allocate sigqueue pool first time */
137 - sqh = sigqhdralloc(sizeof (sigqueue_t), _SIGQUEUE_MAX);
144 + sqh = sigqhdralloc(sizeof (sigqueue_t), (uint_t)sigqsz_max);
138 145 mutex_enter(&p->p_lock);
139 146 if (p->p_sigqhdr == NULL) {
140 147 /* hang the pool head on proc */
141 148 p->p_sigqhdr = sqh;
142 149 } else {
143 150 /* another lwp allocated the pool, free ours */
144 151 sigqhdrfree(sqh);
145 152 sqh = p->p_sigqhdr;
146 153 }
147 154 mutex_exit(&p->p_lock);
148 155 }
149 156
150 157 do {
151 158 bzero(&v, sizeof (v));
152 159 v.sig = sig;
153 160 v.checkperm = 1;
154 161 v.sicode = si_code;
155 162 v.value.sival_ptr = value;
156 163 if ((error = sigqkill(pid, &v)) != EAGAIN || !block)
157 164 break;
158 165 /* block waiting for another chance to allocate a sigqueue_t */
159 166 mutex_enter(&sqh->sqb_lock);
160 167 while (sqh->sqb_count == 0) {
161 168 if (!cv_wait_sig(&sqh->sqb_cv, &sqh->sqb_lock)) {
162 169 error = EINTR;
163 170 break;
164 171 }
165 172 }
166 173 mutex_exit(&sqh->sqb_lock);
167 174 } while (error == EAGAIN);
168 175
169 176 if (error)
170 177 return (set_errno(error));
171 178 return (0);
172 179 }
173 180
174 181 #ifdef _SYSCALL32_IMPL
175 182 /*
176 183 * sigqueue32 - System call entry point for 32-bit callers on LP64 kernel,
177 184 * needed to handle the 32-bit sigvals as correctly as we can. We always
178 185 * assume that a 32-bit caller is passing an int. A 64-bit recipient
179 186 * that expects an int will therefore get it correctly. A 32-bit
180 187 * recipient will also get it correctly since siginfo_kto32() uses
181 188 * sival_int in the conversion. Since a 32-bit pointer has the same
182 189 * size and address in the sigval, it also converts correctly so that
183 190 * two 32-bit apps can exchange a pointer value. However, this means
184 191 * that a pointer sent by a 32-bit caller will be seen in the upper half
185 192 * by a 64-bit recipient, and only the upper half of a 64-bit pointer will
186 193 * be seen by a 32-bit recipient. This is the best solution that does
187 194 * not require severe hacking of the sigval union. Anyways, what it
188 195 * means to be sending pointers between processes with dissimilar
189 196 * models is unclear.
190 197 */
191 198 int
192 199 sigqueue32(pid_t pid, int sig, /* union sigval32 */ caddr32_t value,
193 200 int si_code, int block)
194 201 {
195 202 union sigval sv;
196 203
197 204 bzero(&sv, sizeof (sv));
198 205 sv.sival_int = (int)value;
199 206 return (sigqueue(pid, sig, sv.sival_ptr, si_code, block));
200 207 }
201 208 #endif
↓ open down ↓ |
54 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX