Bug Summary

File:connect.c
Location:line 162, column 2
Description:Null pointer passed as an argument to a 'nonnull' parameter

Annotated Source Code

1/******************************************************************************
2
3
4Copyright 1993, 1998 The Open Group
5
6Permission to use, copy, modify, distribute, and sell this software and its
7documentation for any purpose is hereby granted without fee, provided that
8the above copyright notice appear in all copies and that both that
9copyright notice and this permission notice appear in supporting
10documentation.
11
12The above copyright notice and this permission notice shall be included in
13all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22Except as contained in this notice, the name of The Open Group shall not be
23used in advertising or otherwise to promote the sale, use or other dealings
24in this Software without prior written authorization from The Open Group.
25
26Author: Ralph Mor, X Consortium
27******************************************************************************/
28
29#ifdef HAVE_CONFIG_H1
30#include <config.h>
31#endif
32#include <X11/ICE/ICElib.h>
33#include "ICElibint.h"
34#include <X11/Xtrans/Xtrans.h>
35#include "globals.h"
36
37static XtransConnInfo ConnectToPeer(char *networkIdsList,
38 char **actualConnectionRet);
39
40#define Strstrstrstr strstr
41
42IceConn
43IceOpenConnection (
44 char *networkIdsList,
45 IcePointer context,
46 Boolint mustAuthenticate,
47 int majorOpcodeCheck,
48 int errorLength,
49 char *errorStringRet
50)
51{
52 IceConn iceConn;
53 int extra, i, j;
54 int endian;
55 Boolint gotReply, ioErrorOccured;
56 unsigned long setup_sequence;
57 iceByteOrderMsg *pByteOrderMsg;
58 iceConnectionSetupMsg *pSetupMsg;
59 char *pData;
60 IceReplyWaitInfo replyWait;
61 _IceReply reply;
62 int authUsableCount;
63 int authUsableFlags[MAX_ICE_AUTH_NAMES32];
64 int authIndices[MAX_ICE_AUTH_NAMES32];
65
66 if (errorStringRet && errorLength > 0)
1
Taking false branch
67 *errorStringRet = '\0';
68
69 if (networkIdsList == NULL((void*)0) || *networkIdsList == '\0')
2
Assuming 'networkIdsList' is not equal to null
3
Taking false branch
70 {
71 strncpy (errorStringRet,
72 "networkIdsList argument is NULL", errorLength);
73 return (NULL((void*)0));
74 }
75
76 /*
77 * Check to see if we can use a previously created ICE connection.
78 *
79 * If iceConn->want_to_close is True, or iceConn->free_asap is True,
80 * we can not use the iceConn.
81 *
82 * If 'context' is non-NULL, we will only use a previously opened ICE
83 * connection if the specified 'context' is equal to the context
84 * associated with the ICE connection, or if the context associated
85 * with the ICE connection is NULL.
86 *
87 * If 'majorOpcodeCheck' is non-zero, it will contain a protocol major
88 * opcode that we should make sure is not already active on the ICE
89 * connection. Some clients will want two seperate connections for the
90 * same protocol to the same destination client.
91 */
92
93 for (i = 0; i < _IceConnectionCount; i++)
4
Assuming 'i' is >= '_IceConnectionCount'
5
Loop condition is false. Execution continues on line 147
94 {
95 char *strptr;
96 if ((strptr = (char *) Strstrstrstr (
97 networkIdsList, _IceConnectionStrings[i])) != NULL((void*)0))
98 {
99 char ch = *(strptr + strlen (_IceConnectionStrings[i]));
100 if (ch == ',' || ch == '\0')
101 {
102 /*
103 * OK, we found a connection. Make sure we can reuse it.
104 */
105
106 IceConn iceConn = _IceConnectionObjs[i];
107
108 if (iceConn->want_to_close || iceConn->free_asap ||
109 (context && iceConn->context &&
110 iceConn->context != context))
111 {
112 /* force a new connection to be created */
113 break;
114 }
115
116 if (majorOpcodeCheck)
117 {
118 for (j = iceConn->his_min_opcode;
119 j <= iceConn->his_max_opcode; j++)
120 {
121 if (iceConn->process_msg_info[
122 j - iceConn->his_min_opcode].in_use &&
123 iceConn->process_msg_info[
124 j - iceConn->his_min_opcode].my_opcode ==
125 majorOpcodeCheck)
126 break;
127 }
128
129 if (j <= iceConn->his_max_opcode ||
130 (iceConn->protosetup_to_you &&
131 iceConn->protosetup_to_you->my_opcode ==
132 majorOpcodeCheck))
133 {
134 /* force a new connection to be created */
135 break;
136 }
137 }
138
139 iceConn->open_ref_count++;
140 if (context && !iceConn->context)
141 iceConn->context = context;
142 return (iceConn);
143 }
144 }
145 }
146
147 if ((iceConn = (IceConn) malloc (sizeof (struct _IceConn))) == NULL((void*)0))
6
Taking false branch
148 {
149 strncpy (errorStringRet, "Can't malloc", errorLength);
150 return (NULL((void*)0));
151 }
152
153
154 /*
155 * Open a network connection with the peer client.
156 */
157
158 if ((iceConn->trans_conn = ConnectToPeer (networkIdsList,
7
Taking true branch
159 &iceConn->connection_string)) == NULL((void*)0))
160 {
161 free ((char *) iceConn);
162 strncpy (errorStringRet, "Could not open network socket", errorLength);
8
Null pointer passed as an argument to a 'nonnull' parameter
163 return (NULL((void*)0));
164 }
165
166 /*
167 * Set close-on-exec so that programs that fork() don't get confused.
168 */
169
170 _IceTransSetOption (iceConn->trans_conn, TRANS_CLOSEONEXEC2, 1);
171
172 iceConn->listen_obj = NULL((void*)0);
173
174 iceConn->connection_status = IceConnectPending;
175 iceConn->io_ok = True1;
176 iceConn->dispatch_level = 0;
177 iceConn->context = context;
178 iceConn->my_ice_version_index = 0;
179 iceConn->send_sequence = 0;
180 iceConn->receive_sequence = 0;
181
182 iceConn->vendor = NULL((void*)0);
183 iceConn->release = NULL((void*)0);
184 iceConn->outbuf = NULL((void*)0);
185
186 iceConn->scratch = NULL((void*)0);
187 iceConn->scratch_size = 0;
188
189 iceConn->process_msg_info = NULL((void*)0);
190
191 iceConn->connect_to_you = NULL((void*)0);
192 iceConn->protosetup_to_you = NULL((void*)0);
193
194 iceConn->connect_to_me = NULL((void*)0);
195 iceConn->protosetup_to_me = NULL((void*)0);
196
197 if ((iceConn->inbuf = iceConn->inbufptr =
198 (char *) malloc (ICE_INBUFSIZE1024)) == NULL((void*)0))
199 {
200 _IceFreeConnection (iceConn);
201 strncpy (errorStringRet, "Can't malloc", errorLength);
202 return (NULL((void*)0));
203 }
204
205 iceConn->inbufmax = iceConn->inbuf + ICE_INBUFSIZE1024;
206
207 if ((iceConn->outbuf = iceConn->outbufptr =
208 (char *) calloc (1, ICE_OUTBUFSIZE1024)) == NULL((void*)0))
209 {
210 _IceFreeConnection (iceConn);
211 strncpy (errorStringRet, "Can't malloc", errorLength);
212 return (NULL((void*)0));
213 }
214
215 iceConn->outbufmax = iceConn->outbuf + ICE_OUTBUFSIZE1024;
216
217 iceConn->open_ref_count = 1;
218 iceConn->proto_ref_count = 0;
219
220 iceConn->skip_want_to_close = False0;
221 iceConn->want_to_close = False0;
222 iceConn->free_asap = False0;
223
224 iceConn->saved_reply_waits = NULL((void*)0);
225 iceConn->ping_waits = NULL((void*)0);
226
227 iceConn->connect_to_you = (_IceConnectToYouInfo *) malloc (
228 sizeof (_IceConnectToYouInfo));
229 iceConn->connect_to_you->auth_active = 0;
230
231 /*
232 * Send our byte order.
233 */
234
235 IceGetHeader (iceConn, 0, ICE_ByteOrder,if ((iceConn->outbufptr + 8) > iceConn->outbufmax) IceFlush
(iceConn); pByteOrderMsg = (iceByteOrderMsg *) iceConn->outbufptr
; pByteOrderMsg->majorOpcode = 0; pByteOrderMsg->minorOpcode
= 1; pByteOrderMsg->length = (8 - 8) >> 3; iceConn->
outbufptr += 8; iceConn->send_sequence++
236 SIZEOF (iceByteOrderMsg), iceByteOrderMsg, pByteOrderMsg)if ((iceConn->outbufptr + 8) > iceConn->outbufmax) IceFlush
(iceConn); pByteOrderMsg = (iceByteOrderMsg *) iceConn->outbufptr
; pByteOrderMsg->majorOpcode = 0; pByteOrderMsg->minorOpcode
= 1; pByteOrderMsg->length = (8 - 8) >> 3; iceConn->
outbufptr += 8; iceConn->send_sequence++
;
237
238 endian = 1;
239 if (*(char *) &endian)
240 pByteOrderMsg->byteOrder = IceLSBfirst0;
241 else
242 pByteOrderMsg->byteOrder = IceMSBfirst1;
243
244 IceFlush (iceConn);
245
246
247 /*
248 * Now read the ByteOrder message from the other client.
249 * iceConn->swap should be set to the appropriate boolean
250 * value after the call to IceProcessMessages.
251 */
252
253 iceConn->waiting_for_byteorder = True1;
254
255 ioErrorOccured = False0;
256 while (iceConn->waiting_for_byteorder == True1 && !ioErrorOccured)
257 {
258 ioErrorOccured = (IceProcessMessages (
259 iceConn, NULL((void*)0), NULL((void*)0)) == IceProcessMessagesIOError);
260 }
261
262 if (ioErrorOccured)
263 {
264 _IceFreeConnection (iceConn);
265 strncpy (errorStringRet, "IO error occured opening connection",
266 errorLength);
267 return (NULL((void*)0));
268 }
269
270 if (iceConn->connection_status == IceConnectRejected)
271 {
272 /*
273 * We failed to get the required ByteOrder message.
274 */
275
276 _IceFreeConnection (iceConn);
277 strncpy (errorStringRet,
278 "Internal error - did not receive the expected ByteOrder message",
279 errorLength);
280 return (NULL((void*)0));
281 }
282
283
284 /*
285 * Determine which authentication methods are available for
286 * the Connection Setup authentication.
287 */
288
289 _IceGetPoValidAuthIndices (
290 "ICE", iceConn->connection_string,
291 _IceAuthCount, _IceAuthNames, &authUsableCount, authIndices);
292
293 for (i = 0; i < _IceAuthCount; i++)
294 {
295 authUsableFlags[i] = 0;
296 for (j = 0; j < authUsableCount && !authUsableFlags[i]; j++)
297 authUsableFlags[i] = (authIndices[j] == i);
298 }
299
300
301 /*
302 * Now send a Connection Setup message.
303 */
304
305 extra = STRING_BYTES (IceVendorString)(2 + strlen ("MIT") + ((4 - ((unsigned int) (2 + strlen ("MIT"
)) % 4)) % 4))
+ STRING_BYTES (IceReleaseString)(2 + strlen ("1.0") + ((4 - ((unsigned int) (2 + strlen ("1.0"
)) % 4)) % 4))
;
306
307 for (i = 0; i < _IceAuthCount; i++)
308 if (authUsableFlags[i])
309 {
310 extra += STRING_BYTES (_IceAuthNames[i])(2 + strlen (_IceAuthNames[i]) + ((4 - ((unsigned int) (2 + strlen
(_IceAuthNames[i])) % 4)) % 4))
;
311 }
312
313 extra += (_IceVersionCount * 4);
314
315 IceGetHeaderExtra (iceConn, 0, ICE_ConnectionSetup,if ((iceConn->outbufptr + 16 + (((((unsigned int) ((extra)
+ 7)) >> 3)) << 3)) > iceConn->outbufmax) IceFlush
(iceConn); pSetupMsg = (iceConnectionSetupMsg *) iceConn->
outbufptr; if ((iceConn->outbufptr + 16 + (((((unsigned int
) ((extra) + 7)) >> 3)) << 3)) <= iceConn->
outbufmax) pData = (char *) pSetupMsg + 16; else pData = ((void
*)0); pSetupMsg->majorOpcode = 0; pSetupMsg->minorOpcode
= 2; pSetupMsg->length = ((16 - 8) >> 3) + ((((unsigned
int) ((extra) + 7)) >> 3)); iceConn->outbufptr += (
16 + (((((unsigned int) ((extra) + 7)) >> 3)) << 3
)); iceConn->send_sequence++
316 SIZEOF (iceConnectionSetupMsg), WORD64COUNT (extra),if ((iceConn->outbufptr + 16 + (((((unsigned int) ((extra)
+ 7)) >> 3)) << 3)) > iceConn->outbufmax) IceFlush
(iceConn); pSetupMsg = (iceConnectionSetupMsg *) iceConn->
outbufptr; if ((iceConn->outbufptr + 16 + (((((unsigned int
) ((extra) + 7)) >> 3)) << 3)) <= iceConn->
outbufmax) pData = (char *) pSetupMsg + 16; else pData = ((void
*)0); pSetupMsg->majorOpcode = 0; pSetupMsg->minorOpcode
= 2; pSetupMsg->length = ((16 - 8) >> 3) + ((((unsigned
int) ((extra) + 7)) >> 3)); iceConn->outbufptr += (
16 + (((((unsigned int) ((extra) + 7)) >> 3)) << 3
)); iceConn->send_sequence++
317 iceConnectionSetupMsg, pSetupMsg, pData)if ((iceConn->outbufptr + 16 + (((((unsigned int) ((extra)
+ 7)) >> 3)) << 3)) > iceConn->outbufmax) IceFlush
(iceConn); pSetupMsg = (iceConnectionSetupMsg *) iceConn->
outbufptr; if ((iceConn->outbufptr + 16 + (((((unsigned int
) ((extra) + 7)) >> 3)) << 3)) <= iceConn->
outbufmax) pData = (char *) pSetupMsg + 16; else pData = ((void
*)0); pSetupMsg->majorOpcode = 0; pSetupMsg->minorOpcode
= 2; pSetupMsg->length = ((16 - 8) >> 3) + ((((unsigned
int) ((extra) + 7)) >> 3)); iceConn->outbufptr += (
16 + (((((unsigned int) ((extra) + 7)) >> 3)) << 3
)); iceConn->send_sequence++
;
318
319 setup_sequence = iceConn->send_sequence;
320
321 pSetupMsg->versionCount = _IceVersionCount;
322 pSetupMsg->authCount = authUsableCount;
323 pSetupMsg->mustAuthenticate = mustAuthenticate;
324
325 STORE_STRING (pData, IceVendorString){ CARD16 _len = strlen ("MIT"); { *((CARD16 *) pData) = _len;
pData += 2; }; memcpy (pData, "MIT", _len); pData += _len; if
(((4 - ((unsigned int) (2 + _len) % 4)) % 4)) pData += ((4 -
((unsigned int) (2 + _len) % 4)) % 4); }
;
326 STORE_STRING (pData, IceReleaseString){ CARD16 _len = strlen ("1.0"); { *((CARD16 *) pData) = _len;
pData += 2; }; memcpy (pData, "1.0", _len); pData += _len; if
(((4 - ((unsigned int) (2 + _len) % 4)) % 4)) pData += ((4 -
((unsigned int) (2 + _len) % 4)) % 4); }
;
327
328 for (i = 0; i < _IceAuthCount; i++)
329 if (authUsableFlags[i])
330 {
331 STORE_STRING (pData, _IceAuthNames[i]){ CARD16 _len = strlen (_IceAuthNames[i]); { *((CARD16 *) pData
) = _len; pData += 2; }; memcpy (pData, _IceAuthNames[i], _len
); pData += _len; if (((4 - ((unsigned int) (2 + _len) % 4)) %
4)) pData += ((4 - ((unsigned int) (2 + _len) % 4)) % 4); }
;
332 }
333
334 for (i = 0; i < _IceVersionCount; i++)
335 {
336 STORE_CARD16 (pData, _IceVersions[i].major_version){ *((CARD16 *) pData) = _IceVersions[i].major_version; pData +=
2; }
;
337 STORE_CARD16 (pData, _IceVersions[i].minor_version){ *((CARD16 *) pData) = _IceVersions[i].minor_version; pData +=
2; }
;
338 }
339
340 IceFlush (iceConn);
341
342
343 /*
344 * Process messages until we get a Connection Reply or an Error Message.
345 * Authentication will take place behind the scenes.
346 */
347
348 replyWait.sequence_of_request = setup_sequence;
349 replyWait.major_opcode_of_request = 0;
350 replyWait.minor_opcode_of_request = ICE_ConnectionSetup2;
351 replyWait.reply = (IcePointer) &reply;
352
353 gotReply = False0;
354 ioErrorOccured = False0;
355
356 while (!gotReply && !ioErrorOccured)
357 {
358 ioErrorOccured = (IceProcessMessages (
359 iceConn, &replyWait, &gotReply) == IceProcessMessagesIOError);
360
361 if (ioErrorOccured)
362 {
363 strncpy (errorStringRet, "IO error occured opening connection",
364 errorLength);
365 _IceFreeConnection (iceConn);
366 iceConn = NULL((void*)0);
367 }
368 else if (gotReply)
369 {
370 if (reply.type == ICE_CONNECTION_REPLY1)
371 {
372 if (reply.connection_reply.version_index >= _IceVersionCount)
373 {
374 strncpy (errorStringRet,
375 "Got a bad version index in the Connection Reply",
376 errorLength);
377
378 free (reply.connection_reply.vendor);
379 free (reply.connection_reply.release);
380 _IceFreeConnection (iceConn);
381 iceConn = NULL((void*)0);
382 }
383 else
384 {
385 iceConn->my_ice_version_index =
386 reply.connection_reply.version_index;
387 iceConn->vendor = reply.connection_reply.vendor;
388 iceConn->release = reply.connection_reply.release;
389
390 _IceConnectionObjs[_IceConnectionCount] = iceConn;
391 _IceConnectionStrings[_IceConnectionCount] =
392 iceConn->connection_string;
393 _IceConnectionCount++;
394
395 free ((char *) iceConn->connect_to_you);
396 iceConn->connect_to_you = NULL((void*)0);
397
398 iceConn->connection_status = IceConnectAccepted;
399 }
400 }
401 else /* reply.type == ICE_CONNECTION_ERROR */
402 {
403 /* Connection failed */
404
405 strncpy (errorStringRet, reply.connection_error.error_message,
406 errorLength);
407
408 free (reply.connection_error.error_message);
409
410 _IceFreeConnection (iceConn);
411 iceConn = NULL((void*)0);
412 }
413 }
414 }
415
416 if (iceConn && _IceWatchProcs)
417 {
418 /*
419 * Notify the watch procedures that an iceConn was opened.
420 */
421
422 _IceConnectionOpened (iceConn);
423 }
424
425 return (iceConn);
426}
427
428
429
430IcePointer
431IceGetConnectionContext (
432 IceConn iceConn
433)
434{
435 return (iceConn->context);
436}
437
438
439
440/* ------------------------------------------------------------------------- *
441 * local routines *
442 * ------------------------------------------------------------------------- */
443
444#define ICE_CONNECTION_RETRIES5 5
445
446
447static XtransConnInfo
448ConnectToPeer (char *networkIdsList, char **actualConnectionRet)
449{
450 char addrbuf[256];
451 char* address;
452 char *ptr, *endptr, *delim;
453 int madeConnection = 0;
454 int len, retry;
455 int connect_stat;
456 int address_size;
457 XtransConnInfo trans_conn = NULL((void*)0);
458
459 *actualConnectionRet = NULL((void*)0);
460
461 ptr = networkIdsList;
462 len = strlen (networkIdsList);
463 endptr = networkIdsList + len;
464
465 if (len < sizeof addrbuf)
466 {
467 address = addrbuf;
468 address_size = 256;
469 }
470 else
471 {
472 address = malloc (len + 1);
473 address_size = len;
474 }
475
476 while (ptr < endptr && !madeConnection)
477 {
478 if ((delim = (char *) strchr (ptr, ',')) == NULL((void*)0))
479 delim = endptr;
480
481 len = delim - ptr;
482 if (len > address_size - 1)
483 len = address_size - 1;
484 strncpy (address, ptr, len);
485 address[len] = '\0';
486
487 ptr = delim + 1;
488
489 for (retry = ICE_CONNECTION_RETRIES5; retry >= 0; retry--)
490 {
491 if ((trans_conn = _IceTransOpenCOTSClient (address)) == NULL((void*)0))
492 {
493 break;
494 }
495
496 if ((connect_stat = _IceTransConnect (trans_conn, address)) < 0)
497 {
498 _IceTransClose (trans_conn);
499
500 if (connect_stat == TRANS_TRY_CONNECT_AGAIN-2)
501 {
502 sleep(1);
503 continue;
504 }
505 else
506 break;
507 }
508 else
509 {
510 madeConnection = 1;
511 break;
512 }
513 }
514 }
515
516 if (madeConnection)
517 {
518 /*
519 * We need to return the actual network connection string
520 */
521
522 *actualConnectionRet = strdup(address);
523
524 /*
525 * Return the file descriptor
526 */
527 }
528 else trans_conn = NULL((void*)0);
529
530 if (address != addrbuf) free (address);
531
532 return trans_conn;
533}