Bug Summary

File:libs/apr/misc/unix/otherchild.c
Location:line 99, column 27
Description:Access to field 'p' results in a dereference of a null pointer (loaded from variable 'cur')

Annotated Source Code

1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "apr.h"
18#include "apr_arch_misc.h"
19#include "apr_arch_threadproc.h"
20#include "apr_arch_file_io.h"
21
22#if APR_HAS_OTHER_CHILD1
23
24#ifdef HAVE_TIME_H1
25#include <sys/time.h>
26#endif
27#ifdef HAVE_SYS_SELECT_H1
28#include <sys/select.h>
29#endif
30#if APR_HAVE_SYS_WAIT_H1
31#include <sys/wait.h>
32#endif
33#ifdef BEOS
34#include <sys/socket.h> /* for fd_set definition! */
35#endif
36
37static apr_other_child_rec_t *other_children = NULL((void*)0);
38
39static apr_status_t other_child_cleanup(void *data)
40{
41 apr_other_child_rec_t **pocr, *nocr;
42
43 for (pocr = &other_children; *pocr; pocr = &(*pocr)->next) {
44 if ((*pocr)->data == data) {
45 nocr = (*pocr)->next;
46 (*(*pocr)->maintenance) (APR_OC_REASON_UNREGISTER3, (*pocr)->data, -1);
47 *pocr = nocr;
48 /* XXX: um, well we've just wasted some space in pconf ? */
49 return APR_SUCCESS0;
50 }
51 }
52 return APR_SUCCESS0;
53}
54
55APR_DECLARE(void)void apr_proc_other_child_register(apr_proc_t *proc,
56 void (*maintenance) (int reason, void *, int status),
57 void *data, apr_file_t *write_fd, apr_pool_t *p)
58{
59 apr_other_child_rec_t *ocr;
60
61 ocr = apr_palloc(p, sizeof(*ocr));
62 ocr->p = p;
63 ocr->proc = proc;
64 ocr->maintenance = maintenance;
65 ocr->data = data;
66 if (write_fd == NULL((void*)0)) {
67 ocr->write_fd = (apr_os_file_t) -1;
68 }
69 else {
70#ifdef WIN32
71 /* This should either go away as part of eliminating apr_proc_probe_writable_fds
72 * or write_fd should point to an apr_file_t
73 */
74 ocr->write_fd = write_fd->filehand;
75#else
76 ocr->write_fd = write_fd->filedes;
77#endif
78
79 }
80 ocr->next = other_children;
81 other_children = ocr;
82 apr_pool_cleanup_register(p, ocr->data, other_child_cleanup,
83 apr_pool_cleanup_null);
84}
85
86APR_DECLARE(void)void apr_proc_other_child_unregister(void *data)
87{
88 apr_other_child_rec_t *cur;
89
90 cur = other_children;
1
Value assigned to 'cur'
91 while (cur) {
2
Assuming pointer value is null
3
Loop condition is false. Execution continues on line 99
92 if (cur->data == data) {
93 break;
94 }
95 cur = cur->next;
96 }
97
98 /* segfault if this function called with invalid parm */
99 apr_pool_cleanup_kill(cur->p, cur->data, other_child_cleanup);
4
Access to field 'p' results in a dereference of a null pointer (loaded from variable 'cur')
100 other_child_cleanup(data);
101}
102
103APR_DECLARE(apr_status_t)apr_status_t apr_proc_other_child_alert(apr_proc_t *proc,
104 int reason,
105 int status)
106{
107 apr_other_child_rec_t *ocr, *nocr;
108
109 for (ocr = other_children; ocr; ocr = nocr) {
110 nocr = ocr->next;
111 if (ocr->proc->pid != proc->pid)
112 continue;
113
114 ocr->proc = NULL((void*)0);
115 (*ocr->maintenance) (reason, ocr->data, status);
116 return APR_SUCCESS0;
117 }
118 return APR_EPROC_UNKNOWN(20000 + 27);
119}
120
121APR_DECLARE(void)void apr_proc_other_child_refresh(apr_other_child_rec_t *ocr,
122 int reason)
123{
124 /* Todo:
125 * Implement code to detect if pipes are still alive.
126 */
127#ifdef WIN32
128 DWORD status;
129
130 if (ocr->proc == NULL((void*)0))
131 return;
132
133 if (!ocr->proc->hproc) {
134 /* Already mopped up, perhaps we apr_proc_kill'ed it,
135 * they should have already unregistered!
136 */
137 ocr->proc = NULL((void*)0);
138 (*ocr->maintenance) (APR_OC_REASON_LOST4, ocr->data, -1);
139 }
140 else if (!GetExitCodeProcess(ocr->proc->hproc, &status)) {
141 CloseHandle(ocr->proc->hproc);
142 ocr->proc->hproc = NULL((void*)0);
143 ocr->proc = NULL((void*)0);
144 (*ocr->maintenance) (APR_OC_REASON_LOST4, ocr->data, -1);
145 }
146 else if (status == STILL_ACTIVE) {
147 (*ocr->maintenance) (reason, ocr->data, -1);
148 }
149 else {
150 CloseHandle(ocr->proc->hproc);
151 ocr->proc->hproc = NULL((void*)0);
152 ocr->proc = NULL((void*)0);
153 (*ocr->maintenance) (APR_OC_REASON_DEATH0, ocr->data, status);
154 }
155
156#else /* ndef Win32 */
157 pid_t waitret;
158 int status;
159
160 if (ocr->proc == NULL((void*)0))
161 return;
162
163 waitret = waitpid(ocr->proc->pid, &status, WNOHANG1);
164 if (waitret == ocr->proc->pid) {
165 ocr->proc = NULL((void*)0);
166 (*ocr->maintenance) (APR_OC_REASON_DEATH0, ocr->data, status);
167 }
168 else if (waitret == 0) {
169 (*ocr->maintenance) (reason, ocr->data, -1);
170 }
171 else if (waitret == -1) {
172 /* uh what the heck? they didn't call unregister? */
173 ocr->proc = NULL((void*)0);
174 (*ocr->maintenance) (APR_OC_REASON_LOST4, ocr->data, -1);
175 }
176#endif
177}
178
179APR_DECLARE(void)void apr_proc_other_child_refresh_all(int reason)
180{
181 apr_other_child_rec_t *ocr, *next_ocr;
182
183 for (ocr = other_children; ocr; ocr = next_ocr) {
184 next_ocr = ocr->next;
185 apr_proc_other_child_refresh(ocr, reason);
186 }
187}
188
189#else /* !APR_HAS_OTHER_CHILD */
190
191APR_DECLARE(void)void apr_proc_other_child_register(apr_proc_t *proc,
192 void (*maintenance) (int reason, void *, int status),
193 void *data, apr_file_t *write_fd, apr_pool_t *p)
194{
195 return;
196}
197
198APR_DECLARE(void)void apr_proc_other_child_unregister(void *data)
199{
200 return;
201}
202
203APR_DECLARE(apr_status_t)apr_status_t apr_proc_other_child_alert(apr_proc_t *proc,
204 int reason,
205 int status)
206{
207 return APR_ENOTIMPL((20000 + 50000) + 23);
208}
209
210APR_DECLARE(void)void apr_proc_other_child_refresh(apr_other_child_rec_t *ocr,
211 int reason)
212{
213 return;
214}
215
216APR_DECLARE(void)void apr_proc_other_child_refresh_all(int reason)
217{
218 return;
219}
220
221#endif /* APR_HAS_OTHER_CHILD */