Bug Summary

File:aol.c
Location:line 46, column 5
Description:Null pointer argument in call to memory copy function

Annotated Source Code

1#include "aol.h"
2#include "data.h"
3#include "oleg.h"
4#include "logging.h"
5#include "errhandle.h"
6#include "lz4.h"
7
8#include <stdio.h>
9#include <unistd.h>
10#include <fcntl.h>
11#include <stdlib.h>
12#include <time.h>
13#include <math.h>
14
15int ol_aol_init(ol_database *db) {
16 if (db->is_enabled(OL_F_APPENDONLY, &db->feature_set)) {
17 debug("Opening append only log");
18 debug("Append only log: %s", db->aol_file);
19 db->aolfd = fopen(db->aol_file, "ab+");
20 check(db->aolfd != NULL, "Error opening append only file")if(!(db->aolfd != ((void *)0))){fprintf(__stderrp,"[ERROR] (%s:%d: errno: %s) "
"Error opening append only file" "\n", "src/aol.c",20,((* __error
()) == 0 ? "None" : strerror((* __error())))); (* __error())=
0; goto error;}
;
21 }
22
23 return 0;
24error:
25 return -1;
26}
27
28int ol_aol_fsync(FILE *fd) {
29 check(fflush(fd) == 0, "Could not fflush.")if(!(fflush(fd) == 0)){fprintf(__stderrp,"[ERROR] (%s:%d: errno: %s) "
"Could not fflush." "\n", "src/aol.c",29,((* __error()) == 0
? "None" : strerror((* __error())))); (* __error())=0; goto error
;}
;
30 check(fsync(fileno(fd)) == 0, "Could not fsync")if(!(fsync((!__isthreaded ? ((fd)->_file) : (fileno)(fd)))
== 0)){fprintf(__stderrp,"[ERROR] (%s:%d: errno: %s) " "Could not fsync"
"\n", "src/aol.c",30,((* __error()) == 0 ? "None" : strerror
((* __error())))); (* __error())=0; goto error;}
;
31 return 0;
32error:
33 return -1;
34}
35
36static inline void _serialize_time(struct tm *time, char *buf) {
37 strftime(buf, 21, "%FT%TZ", time);
38}
39
40void _deserialize_time(struct tm *fillout, char *buf) {
41 /* Example 8601 datestamp: 2014-03-08T11:17:39Z */
42 char year[4]={0}, month[2]={0}, day[2]={0};
43 char hour[2]={0}, min[2]={0}, sec[2]={0};
44
45 memcpy(&year, &buf, 4);
46 memcpy(&month, &buf[5], 2);
22
Null pointer argument in call to memory copy function
47 memcpy(&day, &buf[8], 2);
48
49 memcpy(&hour, &buf[11], 2);
50 memcpy(&min, &buf[14], 2);
51 memcpy(&sec, &buf[17], 2);
52
53 memset(fillout, '\0', sizeof(struct tm));
54 fillout->tm_year = strtol(year, NULL((void *)0), 10) - 1900;
55 fillout->tm_mon = strtol(month, NULL((void *)0), 10) - 1;
56 fillout->tm_mday = strtol(day, NULL((void *)0), 10);
57
58 fillout->tm_hour = strtol(hour, NULL((void *)0), 10);
59 fillout->tm_min = strtol(min, NULL((void *)0), 10);
60 fillout->tm_sec = strtol(sec, NULL((void *)0), 10);
61}
62
63#define intlen(value)(value == 0 ? 1 : (int)floor(log10(value)+1)) (value == 0 ? 1 : (int)floor(log10(value)+1))
64
65int ol_aol_write_cmd(ol_database *db, const char *cmd, ol_bucket *bct) {
66 int ret;
67
68 if (strncmp(cmd, "JAR", 3) == 0) {
69 /* I'LL RIGOR YER MORTIS */
70 debug("Writing: \"%.*s\"", (int)bct->klen, bct->key);
71 char aol_str[] =
72 ":%zu:%s" /* cmd length, cmd */
73 ":%zu:%s" /* klen size, key */
74 ":%zu:%s" /* ctype size, content_type */
75 ":%d:%d" /* sizeof(original_size), original_size */
76 ":%d:%d" /* sizeof(size_t), data_size */
77 ":%d:%d"; /* sizeof(size_t), offset into file */
78
79 ret = fprintf(db->aolfd, aol_str,
80 strlen(cmd), cmd,
81 bct->klen, bct->key,
82 bct->ctype_size, bct->content_type,
83 intlen(bct->original_size)(bct->original_size == 0 ? 1 : (int)floor(log10(bct->original_size
)+1))
, bct->original_size,
84 intlen(bct->data_size)(bct->data_size == 0 ? 1 : (int)floor(log10(bct->data_size
)+1))
, bct->data_size,
85 intlen(bct->data_offset)(bct->data_offset == 0 ? 1 : (int)floor(log10(bct->data_offset
)+1))
, bct->data_offset);
86 check(ret > -1, "Error writing to file.")if(!(ret > -1)){fprintf(__stderrp,"[ERROR] (%s:%d: errno: %s) "
"Error writing to file." "\n", "src/aol.c",86,((* __error())
== 0 ? "None" : strerror((* __error())))); (* __error())=0; goto
error;}
;
87 ret = fprintf(db->aolfd, "\n");
88 } else if (strncmp(cmd, "SCOOP", 5) == 0) {
89 ret = fprintf(db->aolfd, ":%zu:%s:%zu:%s\n",
90 strlen(cmd), cmd,
91 bct->klen, bct->key);
92 check(ret > -1, "Error writing to file.")if(!(ret > -1)){fprintf(__stderrp,"[ERROR] (%s:%d: errno: %s) "
"Error writing to file." "\n", "src/aol.c",92,((* __error())
== 0 ? "None" : strerror((* __error())))); (* __error())=0; goto
error;}
;
93 } else if (strncmp(cmd, "SPOIL", 5) == 0) {
94 char exptime[21] = {'\0'};
95 _serialize_time(bct->expiration, exptime);
96
97 ret = fprintf(db->aolfd, ":%zu:%s:%zu:%s:%zu:%*s\n",
98 strlen(cmd), cmd,
99 bct->klen, bct->key,
100 strlen(exptime), 20, exptime);
101 check(ret > -1, "Error writing to file.")if(!(ret > -1)){fprintf(__stderrp,"[ERROR] (%s:%d: errno: %s) "
"Error writing to file." "\n", "src/aol.c",101,((* __error()
) == 0 ? "None" : strerror((* __error())))); (* __error())=0;
goto error;}
;
102 } else {
103 ol_log_msg(LOG_ERR6, "No such command '%s'", cmd);
104 return -1;
105 }
106
107 check(ret > -1, "Error writing to file.")if(!(ret > -1)){fprintf(__stderrp,"[ERROR] (%s:%d: errno: %s) "
"Error writing to file." "\n", "src/aol.c",107,((* __error()
) == 0 ? "None" : strerror((* __error())))); (* __error())=0;
goto error;}
;
108
109 /* Force the OS to flush write to hardware */
110 check(ol_aol_fsync(db->aolfd) == 0, "Could not fsync. Panic!")if(!(ol_aol_fsync(db->aolfd) == 0)){fprintf(__stderrp,"[ERROR] (%s:%d: errno: %s) "
"Could not fsync. Panic!" "\n", "src/aol.c",110,((* __error(
)) == 0 ? "None" : strerror((* __error())))); (* __error())=0
; goto error;}
;
111 return 0;
112error:
113 return -1;
114}
115
116ol_string *_ol_read_data(FILE *fd) {
117 ol_string *data = calloc(1, sizeof(ol_string));
118
119 int c = fgetc(fd);
120 if (c == ':'){
121 int i = 0;
122 size_t l = 0;
123 char buf[20] = {0};
124 while ((c = fgetc(fd)) != ':') {
125 buf[i] = c;
126 ++i;
127 }
128 buf[i + 1] = '\0';
129 l = (size_t)strtol(buf, NULL((void *)0), 10);
130 const size_t total_size = l+1;
131 data->data = calloc(1, total_size);
132 check(fread(data->data, l, 1, fd) == 1, "Could not read from AOL file.")if(!(fread(data->data, l, 1, fd) == 1)){fprintf(__stderrp,
"[ERROR] (%s:%d: errno: %s) " "Could not read from AOL file."
"\n", "src/aol.c",132,((* __error()) == 0 ? "None" : strerror
((* __error())))); (* __error())=0; goto error;}
;
133 data->data[l] = '\0';
134 data->dlen = total_size;
135 return data;
136 } else if (c == EOF(-1)) {
137 data->dlen = 0;
138 data->data = NULL((void *)0);
139 return data; /* A NULL ol_string means EOF was reached */
140 }
141
142 free(data);
143 return NULL((void *)0);
144
145error:
146 ol_string_free(&data);
147 return NULL((void *)0);
148}
149
150int ol_aol_restore(ol_database *db) {
151 ol_string *command = NULL((void *)0),
152 *key = NULL((void *)0),
153 *value = NULL((void *)0),
154 *ct = NULL((void *)0),
155 *read_data_size = NULL((void *)0),
156 *read_org_size = NULL((void *)0);
157
158 FILE *fd = fopen(db->aol_file, "r");
159 check(fd, "Error opening file")if(!(fd)){fprintf(__stderrp,"[ERROR] (%s:%d: errno: %s) " "Error opening file"
"\n", "src/aol.c",159,((* __error()) == 0 ? "None" : strerror
((* __error())))); (* __error())=0; goto error;}
;
160 while (!feof(fd)(!__isthreaded ? (((fd)->_flags & 0x0020) != 0) : (feof
)(fd))
) {
1
Loop condition is true. Entering loop body
6
Loop condition is true. Entering loop body
11
Loop condition is true. Entering loop body
16
Loop condition is true. Entering loop body
161 command = _ol_read_data(fd);
162 check(command, "Error reading")if(!(command)){fprintf(__stderrp,"[ERROR] (%s:%d: errno: %s) "
"Error reading" "\n", "src/aol.c",162,((* __error()) == 0 ? "None"
: strerror((* __error())))); (* __error())=0; goto error;}
;
163
164 /* Kind of a hack to check for EOF. If the struct is blank, then we
165 * read past EOF in _ol_read_data. feof is rarely useful I guess... */
166 if (command->data == NULL((void *)0)) {
2
Taking false branch
7
Taking false branch
12
Taking false branch
17
Taking false branch
167 free(command);
168 break;
169 }
170
171 key = _ol_read_data(fd);
172 check(key, "Error reading")if(!(key)){fprintf(__stderrp,"[ERROR] (%s:%d: errno: %s) " "Error reading"
"\n", "src/aol.c",172,((* __error()) == 0 ? "None" : strerror
((* __error())))); (* __error())=0; goto error;}
; /* Everything needs a key */
173
174 if (strncmp(command->data, "JAR", 3) == 0) {
3
Taking false branch
8
Taking false branch
13
Taking false branch
18
Taking false branch
175 ct = _ol_read_data(fd);
176 check(ct, "Error reading")if(!(ct)){fprintf(__stderrp,"[ERROR] (%s:%d: errno: %s) " "Error reading"
"\n", "src/aol.c",176,((* __error()) == 0 ? "None" : strerror
((* __error())))); (* __error())=0; goto error;}
;
177
178 read_org_size = _ol_read_data(fd);
179 check(read_org_size, "Error reading")if(!(read_org_size)){fprintf(__stderrp,"[ERROR] (%s:%d: errno: %s) "
"Error reading" "\n", "src/aol.c",179,((* __error()) == 0 ? "None"
: strerror((* __error())))); (* __error())=0; goto error;}
;
180
181 read_data_size = _ol_read_data(fd);
182 check(read_data_size, "Error reading")if(!(read_data_size)){fprintf(__stderrp,"[ERROR] (%s:%d: errno: %s) "
"Error reading" "\n", "src/aol.c",182,((* __error()) == 0 ? "None"
: strerror((* __error())))); (* __error())=0; goto error;}
;
183
184 value = _ol_read_data(fd);
185 check(value, "Error reading")if(!(value)){fprintf(__stderrp,"[ERROR] (%s:%d: errno: %s) " "Error reading"
"\n", "src/aol.c",185,((* __error()) == 0 ? "None" : strerror
((* __error())))); (* __error())=0; goto error;}
;
186
187 size_t original_size = (size_t)strtol(read_org_size->data, NULL((void *)0), 10);
188 size_t compressed_size = (size_t)strtol(read_data_size->data, NULL((void *)0), 10);
189 size_t data_offset = (size_t)strtol(value->data, NULL((void *)0), 10);
190
191 unsigned char *data_ptr = db->values + data_offset;
192
193 /* If key is not deleted */
194 if (data_ptr[0] != '\0') {
195 /* Data is compressed */
196 if (original_size != compressed_size) {
197 /* Data is compressed, gotta deal with that. */
198 char *tmp_data = calloc(1, original_size);
199 check(tmp_data != NULL, "Could not initialize tmp_data parameter.")if(!(tmp_data != ((void *)0))){fprintf(__stderrp,"[ERROR] (%s:%d: errno: %s) "
"Could not initialize tmp_data parameter." "\n", "src/aol.c"
,199,((* __error()) == 0 ? "None" : strerror((* __error()))))
; (* __error())=0; goto error;}
;
200
201 int processed = LZ4_decompress_fast((const char*)data_ptr, tmp_data, original_size);
202 check(processed == compressed_size, "Could not decompress data. Data may have been previously deleted. %d != %d", (int)processed, (int)compressed_size)if(!(processed == compressed_size)){fprintf(__stderrp,"[ERROR] (%s:%d: errno: %s) "
"Could not decompress data. Data may have been previously deleted. %d != %d"
"\n", "src/aol.c",202,((* __error()) == 0 ? "None" : strerror
((* __error()))), (int)processed, (int)compressed_size); (* __error
())=0; goto error;}
;
203
204 ol_jar_ct(db, key->data, key->dlen, (unsigned char*)tmp_data, original_size, ct->data, ct->dlen);
205 free(tmp_data);
206 } else {
207 /* Data is uncompressed, no need for trickery. */
208 ol_jar_ct(db, key->data, key->dlen, data_ptr, compressed_size, ct->data, ct->dlen);
209 }
210 } else {
211 ol_log_msg(LOG_WARN3, "No data in values file that corresponds with this key. Deleted?");
212 }
213 ol_string_free(&read_org_size);
214 ol_string_free(&read_data_size);
215 ol_string_free(&ct);
216 ol_string_free(&value);
217 } else if (strncmp(command->data, "SCOOP", 5) == 0) {
4
Taking false branch
9
Taking false branch
14
Taking false branch
19
Taking false branch
218 ol_scoop(db, key->data, key->dlen);
219 } else if (strncmp(command->data, "SPOIL", 5) == 0) {
5
Taking false branch
10
Taking false branch
15
Taking false branch
20
Taking true branch
220 ol_string *spoil = _ol_read_data(fd);
221 check(spoil != NULL, "Could not read the rest of SPOIL command for AOL.")if(!(spoil != ((void *)0))){fprintf(__stderrp,"[ERROR] (%s:%d: errno: %s) "
"Could not read the rest of SPOIL command for AOL." "\n", "src/aol.c"
,221,((* __error()) == 0 ? "None" : strerror((* __error()))))
; (* __error())=0; goto error;}
;
222
223 struct tm time = {0};
224 _deserialize_time(&time, spoil->data);
21
Calling '_deserialize_time'
225
226 check(spoil, "Error reading")if(!(spoil)){fprintf(__stderrp,"[ERROR] (%s:%d: errno: %s) " "Error reading"
"\n", "src/aol.c",226,((* __error()) == 0 ? "None" : strerror
((* __error())))); (* __error())=0; goto error;}
;
227 ol_spoil(db, key->data, key->dlen, &time);
228 ol_string_free(&spoil);
229 }
230
231 /* Strip the newline char after each "record" */
232 char c;
233 check(fread(&c, 1, 1, fd) != 0, "Error reading")if(!(fread(&c, 1, 1, fd) != 0)){fprintf(__stderrp,"[ERROR] (%s:%d: errno: %s) "
"Error reading" "\n", "src/aol.c",233,((* __error()) == 0 ? "None"
: strerror((* __error())))); (* __error())=0; goto error;}
;
234 check(c == '\n', "Could not strip newline")if(!(c == '\n')){fprintf(__stderrp,"[ERROR] (%s:%d: errno: %s) "
"Could not strip newline" "\n", "src/aol.c",234,((* __error(
)) == 0 ? "None" : strerror((* __error())))); (* __error())=0
; goto error;}
;
235
236 ol_string_free(&command);
237 ol_string_free(&key);
238 }
239 fclose(fd);
240 return 0;
241
242error:
243 ol_log_msg(LOG_ERR6, "Restore failed. Corrupt AOL?");
244
245 /* Free all the stuff */
246 ol_string_free(&command);
247 ol_string_free(&key);
248 ol_string_free(&value);
249 ol_string_free(&ct);
250 ol_string_free(&read_org_size);
251 ol_string_free(&read_data_size);
252 if (fd != NULL((void *)0)) {
253 fclose(fd);
254 }
255
256 return -1;
257}