Coverage Report

Created: 2026-02-14 06:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fuzz_header.h
Line
Count
Source
1
/* Copyright 2021 Google LLC
2
Licensed under the Apache License, Version 2.0 (the "License");
3
you may not use this file except in compliance with the License.
4
You may obtain a copy of the License at
5
      http://www.apache.org/licenses/LICENSE-2.0
6
Unless required by applicable law or agreed to in writing, software
7
distributed under the License is distributed on an "AS IS" BASIS,
8
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9
See the License for the specific language governing permissions and
10
limitations under the License.
11
*/
12
13
#include "dnsmasq.h"
14
15
extern void fuzz_blockdata_cleanup();
16
17
// Simple garbage collector 
18
153k
#define GB_SIZE 100
19
20
void *pointer_arr[GB_SIZE];
21
static int pointer_idx = 0;
22
23
// If the garbage collector is used then this must be called as first thing
24
// during a fuzz run.
25
762
void gb_init() {
26
762
  pointer_idx = 0;
27
28
76.9k
   for (int i = 0; i < GB_SIZE; i++) {
29
76.2k
     pointer_arr[i] = NULL;
30
76.2k
   }
31
762
}
32
33
762
void gb_cleanup() {
34
76.9k
  for(int i = 0; i < GB_SIZE; i++) {
35
76.2k
    if (pointer_arr[i] != NULL) {
36
33.5k
      free(pointer_arr[i]);
37
33.5k
    }
38
76.2k
  }
39
762
}
40
41
18.8k
char *get_len_null_terminated(const uint8_t **data, size_t *size, size_t to_get) {
42
18.8k
  if (*size < to_get || (int)*size < 0) {
43
728
    return NULL;
44
728
  }
45
46
18.1k
  char *new_s = malloc(to_get + 1);
47
18.1k
  memcpy(new_s, *data, to_get);
48
18.1k
  new_s[to_get] = '\0';
49
50
18.1k
  *data = *data+to_get;
51
18.1k
  *size -= to_get;
52
18.1k
  return new_s;
53
18.8k
}
54
55
17.2k
char *get_null_terminated(const uint8_t **data, size_t *size) {
56
17.2k
#define STR_SIZE 75
57
17.2k
  return get_len_null_terminated(data, size, STR_SIZE);
58
17.2k
}
59
60
4.03k
char *gb_get_random_data(const uint8_t **data, size_t *size, size_t to_get) {
61
4.03k
  if (*size < to_get || (int)*size < 0) {
62
61
    return NULL;
63
61
  }
64
65
3.97k
  char *new_s = malloc(to_get);
66
3.97k
  memcpy(new_s, *data, to_get);
67
68
3.97k
  pointer_arr[pointer_idx++] = (void*)new_s;
69
  
70
3.97k
  *data = *data + to_get;
71
3.97k
  *size -= to_get;
72
73
3.97k
  return new_s;
74
4.03k
}
75
76
17.2k
char *gb_get_null_terminated(const uint8_t **data, size_t *size) {
77
78
17.2k
  char *nstr = get_null_terminated(data, size);
79
17.2k
  if (nstr == NULL) {
80
557
    return NULL;
81
557
  }
82
16.6k
  pointer_arr[pointer_idx++] = (void*)nstr;
83
16.6k
  return nstr;
84
17.2k
}
85
86
1.66k
char *gb_get_len_null_terminated(const uint8_t **data, size_t *size, size_t to_get) {
87
88
1.66k
  char *nstr = get_len_null_terminated(data, size, to_get);
89
1.66k
  if (nstr != NULL) {
90
1.49k
    pointer_arr[pointer_idx++] = (void*)nstr;
91
1.49k
  }
92
1.66k
  return nstr;
93
1.66k
}
94
95
11.4k
char *gb_alloc_data(size_t len) {
96
11.4k
  char *ptr = calloc(1, len);
97
11.4k
  pointer_arr[pointer_idx++] = (void*)ptr;
98
  
99
11.4k
  return ptr;
100
11.4k
}
101
102
1.19k
short get_short(const uint8_t **data, size_t *size) {
103
1.19k
  if (*size <= 0) return 0;
104
1.18k
  short c = (short)(*data)[0];
105
1.18k
  *data += 1;
106
1.18k
  *size-=1;
107
1.18k
  return c;
108
1.19k
}
109
110
6.99k
int get_int(const uint8_t **data, size_t *size) {
111
6.99k
  if (*size <= 4) return 0;
112
6.92k
  const uint8_t *ptr = *data;
113
6.92k
  int val = *((int*)ptr);
114
6.92k
  *data += 4;
115
6.92k
  *size -= 4;
116
6.92k
  return val;
117
6.99k
}
118
// end simple garbage collector.
119
120
const uint8_t *syscall_data = NULL;
121
size_t syscall_size = 0;
122
123
124
0
int fuzz_ioctl(int fd, unsigned long request, void *arg) {
125
0
  int fd2 = fd;
126
0
  unsigned long request2 = request;
127
0
  void *arg_ptr = arg;
128
129
  // SIOCGSTAMP
130
0
  if (request == SIOCGSTAMP) {
131
0
    struct timeval *tv = (struct timeval*)arg_ptr;
132
0
    if (tv == NULL) {
133
0
      return 0;
134
0
    }
135
136
0
    char *rand_tv = gb_get_random_data(&syscall_data, &syscall_size, sizeof(struct timeval));
137
0
    if (rand_tv == NULL) {
138
0
      return -1;
139
0
    }
140
141
0
    memcpy(tv, rand_tv, sizeof(struct timeval));
142
0
    return 0;
143
0
  }
144
145
0
  if (request == SIOCGIFNAME) {
146
    //printf("We got a SIOCGIFNAME\n");
147
0
    struct ifreq *ifr = (struct ifreq*)arg_ptr;
148
0
    if (ifr == NULL) {
149
0
      return -1;
150
0
    }
151
0
    for (int i = 0; i < IF_NAMESIZE; i++) {
152
0
      if (syscall_size > 0 && syscall_data != NULL) {
153
0
        ifr->ifr_name[i] = (char)*syscall_data;
154
0
        syscall_data += 1;
155
0
        syscall_size -= 1;
156
0
      }
157
0
      else {
158
0
        ifr->ifr_name[i] = 'A';
159
0
      }
160
0
    }
161
0
    ifr->ifr_name[IF_NAMESIZE-1] = '\0';
162
0
    return 0;
163
    //return -1;
164
0
  }
165
0
  if (request == SIOCGIFFLAGS) {
166
0
    return 0;
167
0
  }
168
0
  if (request == SIOCGIFADDR) {
169
0
    return 0;
170
0
  }
171
172
  // 
173
0
  int retval = ioctl(fd2, request2, arg_ptr); 
174
0
  return retval;
175
0
}
176
177
178
// Sysytem call wrappers
179
static char v = 0;
180
0
ssize_t fuzz_recvmsg(int sockfd, struct msghdr *msg, int flags) {
181
  
182
0
  struct iovec *target = msg->msg_iov;
183
184
  //printf("recvmsg 1 \n");
185
0
  if (syscall_size > 1) {
186
0
    char r = *syscall_data;
187
0
    syscall_data += 1;
188
0
    syscall_size -= 1;
189
190
0
    if (r == 12) {
191
      //printf("recvmsg 2\n");
192
0
      return -1;
193
0
    }
194
0
  }
195
196
0
  int j = 0;
197
0
  if (msg->msg_control != NULL) {
198
0
    for (;j < CMSG_SPACE(sizeof(struct in_pktinfo)); j++)
199
0
    {
200
0
      if (syscall_size > 0 && syscall_data != NULL) {
201
0
        ((char*)msg->msg_control)[j] = *syscall_data;
202
0
        syscall_data += 1;
203
0
        syscall_size -= 1;
204
0
      }
205
0
      else {
206
0
        ((char*)msg->msg_control)[j] = 'A';
207
0
      }
208
0
    }
209
0
  }
210
211
0
  int i = 0;
212
0
  for (; i < target->iov_len; i++) {
213
0
    if (syscall_size > 0 && syscall_data != NULL) {
214
0
      ((char*)target->iov_base)[i] = *syscall_data;
215
0
      syscall_data += 1;
216
0
      syscall_size -= 1;
217
0
    }
218
0
    else {
219
0
      ((char*)target->iov_base)[i] = 'A';
220
0
    }
221
0
  }
222
223
0
  if (msg->msg_namelen > 0) {
224
0
    memset(msg->msg_name, 0, msg->msg_namelen);
225
0
  }
226
227
0
  return i;
228
0
}
229
230
231
// dnsmasq specific stuff
232
762
int init_daemon(const uint8_t **data2, size_t *size2) {
233
762
  const uint8_t *data = *data2;
234
762
  size_t size = *size2;
235
236
762
  int retval = 0;
237
238
32.3k
#define CLEAN_IF_NULL(arg) if (arg == NULL) goto cleanup;
239
240
  // Initialize daemon
241
762
  daemon = (struct daemon*)gb_alloc_data(sizeof(struct daemon));
242
762
  CLEAN_IF_NULL(daemon)
243
244
  // daemon misc
245
762
  daemon->max_ttl = get_int(&data, &size);
246
762
  daemon->neg_ttl = get_int(&data, &size);
247
762
  daemon->local_ttl = get_int(&data, &size);
248
762
  daemon->min_cache_ttl = get_int(&data, &size);
249
250
  // daemon->namebuff.
251
762
  char *daemon_namebuff = gb_get_len_null_terminated(&data, &size, MAXDNAME);
252
762
  daemon->namebuff = daemon_namebuff;
253
254
  // daemon->naptr
255
762
  struct naptr *naptr_ptr = (struct naptr*)gb_alloc_data(sizeof(struct naptr));
256
762
  char *naptr_name = gb_get_null_terminated(&data, &size);
257
762
  char *naptr_replace = gb_get_null_terminated(&data, &size);
258
762
  char *naptr_regexp = gb_get_null_terminated(&data, &size);
259
762
  char *naptr_services = gb_get_null_terminated(&data, &size);
260
762
  char *naptr_flags = gb_get_null_terminated(&data, &size);
261
  
262
762
  CLEAN_IF_NULL(naptr_ptr)
263
762
  CLEAN_IF_NULL(naptr_name)
264
727
  CLEAN_IF_NULL(naptr_replace)
265
720
  CLEAN_IF_NULL(naptr_regexp)
266
717
  CLEAN_IF_NULL(naptr_services)
267
710
  CLEAN_IF_NULL(naptr_flags)
268
269
707
  naptr_ptr->name = naptr_name;
270
707
  naptr_ptr->replace = naptr_replace;
271
707
  naptr_ptr->regexp = naptr_regexp;
272
707
  naptr_ptr->services = naptr_services;
273
707
  naptr_ptr->flags = naptr_flags;
274
275
707
  daemon->naptr = naptr_ptr;
276
277
  // daemon->int_names
278
707
  struct interface_name *int_namses = (struct interface_name*)gb_alloc_data(sizeof(struct interface_name));
279
280
707
  char *int_name = gb_get_null_terminated(&data, &size);
281
707
  char *int_intr = gb_get_null_terminated(&data, &size);
282
707
  CLEAN_IF_NULL(int_namses)
283
707
  CLEAN_IF_NULL(int_name)
284
692
  CLEAN_IF_NULL(int_intr)
285
682
  int_namses->name = int_name;
286
682
  int_namses->intr = int_intr;
287
288
682
  struct addrlist *d_addrlist = (struct addrlist*)gb_alloc_data(sizeof(struct addrlist));
289
682
  CLEAN_IF_NULL(d_addrlist)
290
682
  d_addrlist->flags = get_int(&data, &size);
291
682
  d_addrlist->prefixlen = get_int(&data, &size);
292
682
  int_namses->addr = d_addrlist;
293
294
682
  daemon->int_names = int_namses;
295
296
682
  if (size > *size2) {
297
0
    goto cleanup;
298
0
  }
299
300
  // daemon->addrbuf
301
682
  char *adbuf = gb_alloc_data(200);
302
682
  CLEAN_IF_NULL(adbuf)
303
682
  daemon->addrbuff = adbuf;
304
305
  // daemon->auth_zones
306
682
  struct auth_zone *d_az = (struct auth_zone*)gb_alloc_data(sizeof(struct auth_zone));
307
682
  char *auth_domain = gb_get_null_terminated(&data, &size);
308
  
309
682
  CLEAN_IF_NULL(d_az)
310
682
  CLEAN_IF_NULL(auth_domain)
311
656
  d_az->domain = auth_domain;
312
656
  daemon->auth_zones = d_az;
313
314
  // deamon->mxnames
315
656
  struct mx_srv_record *mx_srv_rec = (struct mx_srv_record*)gb_alloc_data(sizeof(struct mx_srv_record));
316
656
  char *mx_name = gb_get_null_terminated(&data, &size);
317
656
  char *mx_target = gb_get_null_terminated(&data, &size);
318
319
656
  CLEAN_IF_NULL(mx_srv_rec)
320
656
  CLEAN_IF_NULL(mx_target)
321
646
  CLEAN_IF_NULL(mx_name)
322
323
646
  mx_srv_rec->next = daemon->mxnames;
324
646
  daemon->mxnames = mx_srv_rec;
325
646
  mx_srv_rec->name = mx_name;
326
646
  mx_srv_rec->target = mx_target;
327
646
  mx_srv_rec->issrv = get_int(&data, &size);
328
646
  mx_srv_rec->weight = get_int(&data, &size);
329
646
  mx_srv_rec->priority = get_int(&data, &size);
330
646
  mx_srv_rec->srvport = get_int(&data, &size);
331
  //data += 40;
332
  //size -= 40;
333
334
646
  if (size > *size2) {
335
0
    goto cleanup;
336
0
  }
337
338
  // daemon->txt
339
646
  struct txt_record *txt_record = (struct txt_record *)gb_alloc_data(sizeof(struct txt_record));
340
646
  char *txt_record_name =  gb_get_null_terminated(&data, &size);
341
646
  char *txt_record_txt = gb_get_null_terminated(&data, &size);
342
343
646
  CLEAN_IF_NULL(txt_record)
344
646
  CLEAN_IF_NULL(txt_record_name)
345
618
  CLEAN_IF_NULL(txt_record_txt)
346
347
611
  txt_record->name = txt_record_name;
348
611
  txt_record->txt = (unsigned char*)txt_record_txt;
349
611
  txt_record->class2 = (get_short(&data, &size) % 10);
350
611
  daemon->txt = txt_record;
351
352
  // daemon->rr
353
611
  struct txt_record *rr_record = (struct txt_record *)gb_alloc_data(sizeof(struct txt_record));
354
611
  char *rr_record_name =  gb_get_null_terminated(&data, &size);
355
611
  char *rr_record_txt = gb_get_null_terminated(&data, &size);
356
357
611
  CLEAN_IF_NULL(rr_record)
358
611
  CLEAN_IF_NULL(rr_record_name)
359
600
  CLEAN_IF_NULL(rr_record_txt)
360
361
580
  rr_record->name = rr_record_name;
362
580
  rr_record->txt = (unsigned char*)rr_record_txt;
363
580
  rr_record->class2 = (get_short(&data, &size) % 10);
364
580
  daemon->rr = rr_record;
365
366
580
  if (size > *size2) {
367
0
    goto cleanup;
368
0
  }
369
370
  // daemon->relay4
371
  //struct dhcp_relay *dr = (struct dhcp_relay*)gb_alloc_data(sizeof(struct dhcp_relay));
372
580
  struct dhcp_relay *dr = (struct dhcp_relay*)gb_get_random_data(&data, &size, sizeof(struct dhcp_relay));
373
580
  char *dr_interface = gb_get_null_terminated(&data, &size);
374
  
375
580
  CLEAN_IF_NULL(dr)
376
563
  CLEAN_IF_NULL(dr_interface)
377
552
  dr->interface = dr_interface;
378
552
  dr->next = NULL;
379
  //dr->current = NULL;
380
552
  daemon->relay4 = dr;
381
382
  // deamon->bridges
383
552
  struct dhcp_bridge *db = (struct dhcp_bridge*)gb_alloc_data(sizeof(struct dhcp_bridge));
384
552
  char *db_interface = gb_get_null_terminated(&data, &size);
385
386
552
  CLEAN_IF_NULL(db)
387
552
  CLEAN_IF_NULL(db_interface)
388
389
545
  if (strlen(db_interface) > IF_NAMESIZE) {
390
5.72k
    for (int i = 0; i < IF_NAMESIZE; i++) {
391
5.39k
      db->iface[i] = db_interface[i];
392
5.39k
    }
393
337
  } else {
394
1.00k
    for (int i = 0; i < strlen(db_interface); i++) {
395
800
      db->iface[i] = db_interface[i];
396
800
    }
397
208
  }
398
399
400
545
  struct dhcp_bridge *db_alias = (struct dhcp_bridge*)gb_alloc_data(sizeof(struct dhcp_bridge));
401
  //struct dhcp_bridge *db_alias = (struct dhcp_bridge*)gb_get_random_data(&data, &size, sizeof(struct dhcp_bridge));
402
545
  char *db_alias_interface = gb_get_null_terminated(&data, &size);
403
404
545
  CLEAN_IF_NULL(db_alias)
405
545
  CLEAN_IF_NULL(db_alias_interface)
406
407
528
  if (strlen(db_alias_interface) > IF_NAMESIZE) {
408
5.50k
    for (int i = 0; i < IF_NAMESIZE; i++) {
409
5.18k
      db_alias->iface[i] = db_alias_interface[i];
410
5.18k
    }
411
324
  } else {
412
982
    for (int i = 0; i < strlen(db_alias_interface); i++) {
413
778
      db_alias->iface[i] = db_alias_interface[i];
414
778
    }
415
204
  }
416
528
  db->alias = db_alias;
417
528
  daemon->bridges = db;
418
419
  // daemon->if_names
420
528
  struct iname *in = (struct iname*)gb_get_random_data(&data, &size, sizeof(struct iname));
421
528
  char *iname_name = gb_get_null_terminated(&data, &size);
422
  
423
528
  CLEAN_IF_NULL(in)
424
510
  CLEAN_IF_NULL(iname_name)
425
426
507
  in->name = iname_name;
427
507
  in->next = NULL;
428
429
507
  daemon->if_names = in;
430
431
  // daemon->if_addrs
432
507
  struct iname *in_addr = (struct iname*)gb_get_random_data(&data, &size, sizeof(struct iname));
433
507
  char *iname_name_addr = gb_get_null_terminated(&data, &size);
434
  
435
507
  CLEAN_IF_NULL(in_addr)
436
504
  CLEAN_IF_NULL(iname_name_addr)
437
438
502
  in_addr->name = iname_name_addr;
439
502
  in_addr->next = NULL;
440
441
502
  daemon->if_addrs = in_addr;
442
443
  // daemon->if_except
444
502
  struct iname *in_except = (struct iname*)gb_get_random_data(&data, &size, sizeof(struct iname));
445
502
  char *iname_name_except = gb_get_null_terminated(&data, &size);
446
  
447
502
  CLEAN_IF_NULL(in_except)
448
500
  CLEAN_IF_NULL(iname_name_except)
449
450
499
  in_except->name = iname_name_except;
451
499
  in_except->next = NULL;
452
453
499
  daemon->if_except = in_except;
454
455
  // daemon->dhcp_except
456
499
  struct iname *except = (struct iname*)gb_get_random_data(&data, &size, sizeof(struct iname));
457
499
  char *name_except = gb_get_null_terminated(&data, &size);
458
  
459
499
  CLEAN_IF_NULL(except)
460
493
  CLEAN_IF_NULL(name_except)
461
462
492
  except->name = name_except;
463
492
  except->next = NULL;
464
465
492
  daemon->dhcp_except = except;
466
467
  // daemon->authinterface
468
492
  struct iname *auth_interface = (struct iname*)gb_get_random_data(&data, &size, sizeof(struct iname));
469
492
  char *auth_name = gb_get_null_terminated(&data, &size);
470
  
471
492
  CLEAN_IF_NULL(auth_interface)
472
484
  CLEAN_IF_NULL(auth_name)
473
474
480
  auth_interface->name = auth_name;
475
480
  auth_interface->next = NULL;
476
477
480
  daemon->authinterface = auth_interface;
478
479
480
  // daemon->cnames
481
480
  struct cname *cn = (struct cname*)gb_alloc_data(sizeof(struct cname));
482
480
  char *cname_alias = gb_get_null_terminated(&data, &size);
483
480
  char *cname_target = gb_get_null_terminated(&data, &size);
484
485
480
  CLEAN_IF_NULL(cn)
486
480
  CLEAN_IF_NULL(cname_alias)
487
476
  CLEAN_IF_NULL(cname_target)
488
489
473
  cn->alias = cname_alias;
490
473
  cn->target = cname_target;
491
473
  daemon->cnames = cn;
492
493
494
  // daemon->ptr
495
473
  struct ptr_record *ptr = (struct ptr_record *)gb_alloc_data(sizeof(struct ptr_record));
496
473
  CLEAN_IF_NULL(ptr)
497
498
473
  char *ptr_name = gb_get_null_terminated(&data, &size);
499
473
  CLEAN_IF_NULL(ptr_name)
500
470
  ptr->name = ptr_name;
501
470
  daemon->ptr = ptr;
502
503
470
  if (size > *size2) {
504
0
    goto cleanup;
505
0
  }
506
507
  // daemon->dhcp
508
470
  struct dhcp_context *dhcp_c = (struct dhcp_context *) gb_get_random_data(&data, &size, sizeof(struct dhcp_context));
509
  
510
470
  char *dhcp_c_temp_in = gb_get_null_terminated(&data, &size);
511
512
470
  struct dhcp_netid *dhcp_c_netid = (struct dhcp_netid *) gb_alloc_data(sizeof(struct dhcp_netid));
513
470
  char *dhcp_netid_net = gb_get_null_terminated(&data, &size);
514
515
470
  CLEAN_IF_NULL(dhcp_c)
516
465
  CLEAN_IF_NULL(dhcp_c_temp_in)
517
463
  CLEAN_IF_NULL(dhcp_c_netid)
518
463
  CLEAN_IF_NULL(dhcp_netid_net)
519
520
460
  dhcp_c->next = NULL;
521
460
  dhcp_c->current = NULL;
522
460
  dhcp_c_netid->net = dhcp_netid_net;
523
460
  dhcp_c->filter = dhcp_c_netid;
524
460
  dhcp_c->template_interface = dhcp_c_temp_in;
525
526
460
  daemon->dhcp = dhcp_c;
527
528
529
  // daemon->dhcp6
530
460
  struct dhcp_context *dhcp6_c = (struct dhcp_context *) gb_get_random_data(&data, &size, sizeof(struct dhcp_context));
531
  
532
460
  char *dhcp6_c_temp_in = gb_get_null_terminated(&data, &size);
533
534
460
  struct dhcp_netid *dhcp6_c_netid = (struct dhcp_netid *) gb_alloc_data(sizeof(struct dhcp_netid));
535
460
  char *dhcp6_netid_net = gb_get_null_terminated(&data, &size);
536
537
460
  CLEAN_IF_NULL(dhcp6_c)
538
458
  CLEAN_IF_NULL(dhcp6_c_temp_in)
539
453
  CLEAN_IF_NULL(dhcp6_c_netid)
540
453
  CLEAN_IF_NULL(dhcp6_netid_net)
541
542
452
  dhcp6_c->next = NULL;
543
452
  dhcp6_c->current = NULL;
544
452
  dhcp6_c_netid->net = dhcp6_netid_net;
545
452
  dhcp6_c->filter = dhcp6_c_netid;
546
452
  dhcp6_c->template_interface = dhcp6_c_temp_in;
547
548
452
  daemon->dhcp6 = dhcp6_c;
549
550
  // daemon->doing_dhcp6
551
452
  daemon->doing_dhcp6 = 1;
552
553
  // daemon->dhcp_buffs
554
452
  char *dhcp_buff = gb_alloc_data(DHCP_BUFF_SZ);
555
452
  char *dhcp_buff2 = gb_alloc_data(DHCP_BUFF_SZ);
556
452
  char *dhcp_buff3 = gb_alloc_data(DHCP_BUFF_SZ);
557
558
452
  CLEAN_IF_NULL(dhcp_buff)
559
452
  CLEAN_IF_NULL(dhcp_buff2)
560
452
  CLEAN_IF_NULL(dhcp_buff3)
561
562
452
  daemon->dhcp_buff = dhcp_buff;
563
452
  daemon->dhcp_buff2 = dhcp_buff2;
564
452
  daemon->dhcp_buff3 = dhcp_buff3;
565
566
567
568
  // daemon->ignore_addr
569
452
  struct bogus_addr *bb = (struct bogus_addr *)gb_alloc_data(sizeof(struct bogus_addr));
570
452
  CLEAN_IF_NULL(bb)
571
572
452
  daemon->ignore_addr = bb;
573
574
  // daemon->doctors
575
452
  if (size > *size2) {
576
0
    goto cleanup;
577
0
  }
578
579
452
  struct doctor *doctors = (struct doctor *)gb_alloc_data(sizeof(struct doctor));
580
452
  CLEAN_IF_NULL(doctors)
581
582
452
  doctors->next = NULL;
583
452
  daemon->doctors = doctors;
584
585
452
  retval = 0;
586
452
  goto ret;
587
310
cleanup:
588
310
  retval = -1;
589
590
762
ret:
591
762
  return retval;
592
310
}