Coverage Report

Created: 2024-10-03 06:24

/src/SockFuzzer/fuzz/fakes/mbuf.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2021 Google LLC
3
 *
4
 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5
 *
6
 * This file contains Original Code and/or Modifications of Original Code
7
 * as defined in and that are subject to the Apple Public Source License
8
 * Version 2.0 (the 'License'). You may not use this file except in
9
 * compliance with the License. The rights granted to you under the License
10
 * may not be used to create, or enable the creation or redistribution of,
11
 * unlawful or unlicensed copies of an Apple operating system, or to
12
 * circumvent, violate, or enable the circumvention or violation of, any
13
 * terms of an Apple operating system software license agreement.
14
 *
15
 * Please obtain a copy of the License at
16
 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17
 *
18
 * The Original Code and all software distributed under the License are
19
 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22
 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23
 * Please see the License for the specific language governing rights and
24
 * limitations under the License.
25
 *
26
 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27
 */
28
29
#include "bsd/machine/param.h"
30
#include "bsd/sys/mbuf.h"
31
32
// We link these in from libc/asan
33
void* malloc(size_t size);
34
void* calloc(size_t nmemb, size_t size);
35
void free(void* ptr);
36
int posix_memalign(void** memptr, size_t alignment, size_t size);
37
38
typedef struct {
39
  size_t bufsize;
40
  // Must we always return clusters?
41
  bool cluster_cache;
42
} mcache_t;
43
44
mcache_t* mcache_create(const char* name, size_t bufsize, size_t align,
45
7
                        u_int32_t flags, int wait) {
46
7
  mcache_t* cache = (mcache_t*)malloc(sizeof(mcache_t));
47
7
  cache->bufsize = bufsize;
48
7
  cache->cluster_cache = false;
49
7
  return cache;
50
7
}
51
52
// type doesn't match but we just need the address
53
void mbuf_cslab_alloc(void);
54
55
mcache_t* mcache_create_ext(const char* name, size_t bufsize, void* allocfn,
56
                            void* freefn, void* auditfn, void* logfn,
57
                            void* notifyfn, void* arg, u_int32_t flags,
58
7
                            int wait) {
59
7
  mcache_t* cache = (mcache_t*)malloc(sizeof(mcache_t));
60
7
  cache->bufsize = bufsize;
61
7
  cache->cluster_cache = allocfn == mbuf_cslab_alloc;
62
7
  return cache;
63
7
}
64
65
0
void assfail() { assert(false); }
66
67
struct mbuf* mbuf_create(const uint8_t* data, size_t size, bool is_header,
68
949k
                         bool force_ext, int mtype, int pktflags) {
69
949k
  struct mbuf* m = NULL;
70
949k
  assert(sizeof(struct mbuf) == MSIZE);
71
949k
  if (posix_memalign((void**)&m, MSIZE, sizeof(struct mbuf))) {
72
0
    return NULL;
73
0
  }
74
949k
  memset((void*)m, 0, sizeof(struct mbuf));
75
949k
  m->m_type = mtype;
76
  // TODO: use fuzzed data to create all kinds of mbuf chains
77
949k
  size_t max_size = MBIGCLBYTES;
78
949k
  if (njcl > 0) {
79
949k
    max_size = njclbytes;
80
949k
  }
81
949k
  if (size >= max_size) {
82
22
    size = max_size - 1;
83
22
  }
84
85
949k
  if (force_ext || size > sizeof(m->M_dat.MH.MH_dat.MH_databuf)) {
86
133k
    m->m_flags = M_EXT;
87
133k
    m->m_data = m->m_ext.ext_buf = (caddr_t)calloc(1, size);
88
133k
    m->m_ext.ext_size = size;
89
90
133k
    struct ext_ref* rfa = (struct ext_ref*)calloc(1, sizeof(struct ext_ref));
91
133k
    rfa->refcnt = 1;
92
133k
    rfa->minref = 1;
93
133k
    int EXTF_COMPOSITE = 0x1;
94
133k
    rfa->flags = EXTF_COMPOSITE;
95
133k
    m->m_ext.ext_refflags = (struct ext_ref*)rfa;
96
815k
  } else {
97
815k
    m->m_flags = M_PKTHDR;
98
815k
    m->m_data = m->m_pktdat;
99
815k
  }
100
101
949k
  if (data) memcpy(m->m_data, data, size);
102
949k
  m->m_len = size;
103
949k
  if (is_header) {
104
936k
    m->m_flags |= M_PKTHDR;
105
936k
    m->m_pkthdr.len = m->m_len;
106
936k
    m->m_pkthdr.redzone = ((u_int32_t)(uintptr_t)m);
107
936k
    m->m_pkthdr.pkt_flags = pktflags;
108
936k
  }
109
110
949k
  assert(m->m_len <= ((njcl > 0) ? njclbytes : MBIGCLBYTES));
111
112
0
  return m;
113
949k
}
114
115
296k
void* mcache_alloc(mcache_t* cp, int flags) {
116
296k
  if (cp->cluster_cache) {
117
12.7k
    return mbuf_create(NULL, cp->bufsize, false, cp->cluster_cache, MT_FREE, 0);
118
12.7k
  }
119
120
283k
  void* m = NULL;
121
283k
  if (posix_memalign((void**)&m, MSIZE, cp->bufsize)) {
122
0
    return NULL;
123
0
  }
124
283k
  return m;
125
283k
}
126
127
163k
uint16_t m_decref(struct mbuf* m) {
128
163k
  struct ext_ref* rfa = m->m_ext.ext_refflags;
129
163k
  if (rfa) {
130
163k
    rfa->refcnt--;
131
163k
    return rfa->refcnt;
132
163k
  }
133
0
  return 0;
134
163k
}
135
136
1.22M
struct mbuf* m_free(struct mbuf* m) {
137
1.22M
  if ((m->m_flags & M_EXT)) {
138
163k
    uint16_t refcnt = m_decref(m);
139
163k
    if (!refcnt) {
140
135k
      free(m->m_ext.ext_buf);
141
135k
      free(m->m_ext.ext_refflags);
142
135k
    }
143
163k
  }
144
1.22M
  struct mbuf* ret = m->m_next;
145
1.22M
  free(m);
146
1.22M
  return ret;
147
1.22M
}
148
149
0
void mcache_free(mcache_t* cp, void* buf) {
150
0
  if (cp->cluster_cache) {
151
0
    m_free((struct mbuf*)buf);
152
0
  } else {
153
0
    free(buf);
154
0
  }
155
0
}
156
157
1
void mcache_init() {
158
  // Nothing to do for mocked case.
159
1
}
160
161
0
void mcache_reap_now() { assert(false); }
162
163
0
int mcache_alloc_ext(mcache_t* cp, void** list, unsigned int num, int wait) {
164
0
  struct mbuf* m = (struct mbuf*)calloc(1, sizeof(struct mbuf));
165
0
  m->m_hdr.mh_next = NULL;
166
0
  m->m_hdr.mh_nextpkt = NULL;
167
0
  m->m_type = MT_FREE;
168
0
  m->m_flags = M_EXT;
169
0
  m->m_hdr.mh_data = (caddr_t)calloc(1, num * cp->bufsize);
170
0
  m->m_hdr.mh_len = num * cp->bufsize;
171
0
  *list = m;
172
0
  return 1;
173
0
}
174
175
0
void mcache_audit_cache() { assert(false); }
176
177
0
void mcache_audit_free_verify() { assert(false); }
178
179
0
void mcache_audit_free_verify_set() { assert(false); }
180
181
0
void mcache_bkt_isempty() { assert(false); }
182
183
0
void mcache_buffer_log() { assert(false); }
184
185
0
unsigned int mcache_cache_line_size() {
186
0
  return 64;
187
0
}
188
189
0
void mcache_dump_mca() { assert(false); }
190
191
0
void mcache_free_ext() { assert(false); }
192
193
1
unsigned int mcache_getflags() { return 0; }
194
195
0
void mcache_purge_cache() { assert(false); }
196
197
0
void mcache_reap() { assert(false); }
198
199
0
void mcache_set_pattern() { assert(false); }
200
201
0
void mcache_waiter_dec() { assert(false); }
202
203
0
void mcache_waiter_inc() { assert(false); }