Skip to content

Commit 3e8e607

Browse files
xiaojingrichlijinxia
authored andcommitted
tools: acrn-crashlog: Fix potential issues under acrnprobe
This patch is to fix potential issues, which are reported by static analysis tool, for acrnprobe. Changes: 1. Check the return value of sender_id() and get_sender_by_name(), since it could be -1 or NULL. 2. Remove the parameter len from create_event, take parameter path as a NULL-terminated string as default. 3. Modify for_each_* functions to avoid overflow. Signed-off-by: Liu Xinwu <xinwu.liu@intel.com> Reviewed-by: Zhi Jin <zhi.jin@intel.com> Acked-by: Chen Gang <gang.c.chen@intel.com>
1 parent 0c39b9c commit 3e8e607

File tree

7 files changed

+123
-67
lines changed

7 files changed

+123
-67
lines changed

tools/acrn-crashlog/acrnprobe/android_events.c

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,17 +119,22 @@ static int refresh_key_synced_stage1(struct sender_t *sender, struct vm_t *vm,
119119
char *key, enum refresh_type_t type)
120120
{
121121
char log_new[64];
122-
char *log_vmrecordid = sender->log_vmrecordid;
122+
char *log_vmrecordid;
123+
int sid;
123124

124125
if (!key || !sender || !vm)
125126
return -1;
126127

128+
sid = sender_id(sender);
129+
if (sid == -1)
130+
return -1;
131+
log_vmrecordid = sender->log_vmrecordid;
127132
/* the length of key must be 20, and its value can not be
128133
* 00000000000000000000.
129134
*/
130135
if ((strlen(key) == 20) &&
131136
strcmp(key, "00000000000000000000")) {
132-
sprintf(vm->last_synced_line_key[sender_id(sender)],
137+
sprintf(vm->last_synced_line_key[sid],
133138
"%s", key);
134139
if (type == MM_ONLY)
135140
return 0;
@@ -158,6 +163,9 @@ static int refresh_key_synced_stage2(struct mm_file_t *m_vm_records, char *key)
158163
if (*key) {
159164
begin = strstr(m_vm_records->begin, " <==");
160165
end = strrstr(m_vm_records->begin, key);
166+
if (!begin || !end)
167+
return -1;
168+
161169
end = strchr(end, '\n');
162170

163171
for (p = begin; p < end; p++) {
@@ -183,6 +191,8 @@ static int get_vm_history(struct vm_t *vm, struct sender_t *sender,
183191
return -1;
184192

185193
sid = sender_id(sender);
194+
if (sid == -1)
195+
return -1;
186196

187197
snprintf(vm_history, sizeof(vm_history), "/tmp/%s_%s",
188198
"vm_hist", vm->name);
@@ -221,6 +231,9 @@ static void sync_lines_stage1(struct sender_t *sender, void *data[])
221231
char *vm_format = "%*[^ ]%*[ ]%[^ ]%*c";
222232

223233
sid = sender_id(sender);
234+
if (sid == -1)
235+
return;
236+
224237
for_each_vm(id, vm, conf) {
225238
if (!vm)
226239
continue;
@@ -287,6 +300,10 @@ static void sync_lines_stage2(struct sender_t *sender, void *data[],
287300
strerror(errno));
288301
return;
289302
}
303+
if (!m_vm_records->size) {
304+
LOGE("size(0b) of (%s)\n", sender->log_vmrecordid);
305+
return;
306+
}
290307

291308
cursor = strstr(m_vm_records->begin, " <==");
292309
if (!cursor)
@@ -334,11 +351,19 @@ static void sync_lines_stage2(struct sender_t *sender, void *data[],
334351
static void get_last_line_synced(struct sender_t *sender)
335352
{
336353
int id;
354+
int sid;
337355
int ret;
338356
struct vm_t *vm;
339357
char vmkey[SHA_DIGEST_LENGTH + 10] = {0};
340358
char word[256];
341359

360+
if (!sender)
361+
return;
362+
363+
sid = sender_id(sender);
364+
if (sid == -1)
365+
return;
366+
342367
for_each_vm(id, vm, conf) {
343368
if (!vm)
344369
continue;
@@ -347,7 +372,7 @@ static void get_last_line_synced(struct sender_t *sender)
347372
continue;
348373

349374
/* generally only exec for each vm once */
350-
if (vm->last_synced_line_key[sender_id(sender)][0])
375+
if (vm->last_synced_line_key[sid][0])
351376
continue;
352377

353378
snprintf(word, sizeof(word), "%s ", vm->name);
@@ -406,6 +431,7 @@ static char *setup_loop_dev(void)
406431
* launch_UOS.sh, we need mount its data partition to loop device
407432
*/
408433
char *out;
434+
char *end;
409435
char loop_dev_tmp[32];
410436
int i;
411437

@@ -440,7 +466,9 @@ static char *setup_loop_dev(void)
440466
}
441467
}
442468
}
443-
*strchr(loop_dev, '\n') = 0;
469+
end = strchr(loop_dev, '\n');
470+
if (end)
471+
*end = 0;
444472

445473
out = exec_out2mem("fdisk -lu %s", android_img);
446474
if (!out) {

tools/acrn-crashlog/acrnprobe/channels.c

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ static struct channel_t channels[] = {
4141
};
4242

4343
#define for_each_channel(i, channel) \
44-
for (i = 0, channel = &channels[0]; \
45-
i < (int)ARRAY_SIZE(channels); \
46-
i++, channel++)
44+
for (i = 0; \
45+
(i < (int)ARRAY_SIZE(channels)) && (channel = &channels[i]); \
46+
i++)
4747

4848
/**
4949
* Helper function to create a event and fill event_t structure.
@@ -53,30 +53,35 @@ static struct channel_t channels[] = {
5353
* @param private The corresponding configuration info to the event.
5454
* @param watchfd For watch channel, so far, only used by inotify.
5555
* @param path File which trigger this event.
56-
* @param len Length of path.
5756
*
5857
* @return a pointer to the filled event if successful,
5958
* or NULL on error.
6059
*/
6160
static struct event_t *create_event(enum event_type_t event_type,
6261
char *channel, void *private,
63-
int watchfd, char *path, int len)
62+
int watchfd, char *path)
6463
{
6564
struct event_t *e;
65+
int path_len = 0;
6666

67-
if (len < 0)
68-
return NULL;
67+
if (path) {
68+
path_len = strlen(path);
69+
if (path_len > PATH_MAX) {
70+
LOGE("invalid path, drop event.\n");
71+
return NULL;
72+
}
73+
}
6974

70-
e = malloc(sizeof(*e) + len + 1);
75+
e = malloc(sizeof(*e) + path_len + 1);
7176
if (e) {
72-
memset(e, 0, sizeof(*e) + len + 1);
77+
memset(e, 0, sizeof(*e) + path_len + 1);
7378
e->watchfd = watchfd;
7479
e->channel = channel;
75-
e->private = (void *)private;
80+
e->private = private;
7681
e->event_type = event_type;
77-
if (path && (len > 0)) {
78-
e->len = len;
79-
strncpy(e->path, path, len);
82+
if (path_len > 0) {
83+
e->len = path_len;
84+
memcpy(e->path, path, path_len + 1);
8085
}
8186
} else {
8287
LOGE("malloc failed, error (%s)\n", strerror(errno));
@@ -100,7 +105,7 @@ static void channel_oneshot(struct channel_t *cnl)
100105

101106
LOGD("initializing channel %s ...\n", cname);
102107

103-
e = create_event(REBOOT, cname, NULL, 0, NULL, 0);
108+
e = create_event(REBOOT, cname, NULL, 0, NULL);
104109
if (e)
105110
event_enqueue(e);
106111

@@ -116,8 +121,7 @@ static void channel_oneshot(struct channel_t *cnl)
116121
!strcmp("file", crash->trigger->type) &&
117122
file_exists(crash->trigger->path)) {
118123
e = create_event(CRASH, cname, (void *)crash,
119-
0, crash->trigger->path,
120-
strlen(crash->trigger->path));
124+
0, crash->trigger->path);
121125
if (e)
122126
event_enqueue(e);
123127
}
@@ -134,7 +138,7 @@ static void channel_oneshot(struct channel_t *cnl)
134138
!strcmp("file", info->trigger->type) &&
135139
file_exists(info->trigger->path)) {
136140
e = create_event(INFO, cname, (void *)info,
137-
0, NULL, 0);
141+
0, NULL);
138142
if (e)
139143
event_enqueue(e);
140144
}
@@ -156,7 +160,7 @@ static struct polling_job_t {
156160
static void polling_vm(union sigval v __attribute__((unused)))
157161
{
158162

159-
struct event_t *e = create_event(VM, "polling", NULL, 0, NULL, 0);
163+
struct event_t *e = create_event(VM, "polling", NULL, 0, NULL);
160164

161165
if (e)
162166
event_enqueue(e);
@@ -319,6 +323,7 @@ static int receive_inotify_events(struct channel_t *channel)
319323
int read_left;
320324
char buf[256];
321325
char *p;
326+
char *name;
322327
struct event_t *e;
323328
struct inotify_event *ievent;
324329
enum event_type_t event_type;
@@ -360,9 +365,14 @@ static int receive_inotify_events(struct channel_t *channel)
360365
if (event_type == UNKNOWN) {
361366
LOGE("get a unknown event\n");
362367
} else {
368+
if (!ievent->len)
369+
name = NULL;
370+
else
371+
name = ievent->name;
372+
363373
e = create_event(event_type, channel->name,
364374
private, channel->fd,
365-
ievent->name, ievent->len);
375+
name);
366376
if (e)
367377
event_enqueue(e);
368378
}
@@ -384,7 +394,7 @@ static int receive_inotify_events(struct channel_t *channel)
384394
*/
385395
static void heart_beat(void)
386396
{
387-
struct event_t *e = create_event(HEART_BEAT, NULL, NULL, 0, NULL, 0);
397+
struct event_t *e = create_event(HEART_BEAT, NULL, NULL, 0, NULL);
388398

389399
if (e)
390400
event_enqueue(e);

tools/acrn-crashlog/acrnprobe/crash_reclassify.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ static struct crash_t *crash_reclassify_by_content(struct crash_t *rcrash,
233233
return NULL;
234234

235235
if (trfile) {
236-
ret = read_full_binary_file(trfile, &size, &file);
236+
ret = read_file(trfile, &size, &file);
237237
if (ret == -1) {
238238
LOGE("read %s failed, error (%s)\n",
239239
trfile, strerror(errno));

tools/acrn-crashlog/acrnprobe/history.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,16 +132,21 @@ void hist_raise_event(char *event, char *type, char *log, char *lastuptime,
132132

133133
/* here means user have configured the crashlog sender */
134134
crashlog = get_sender_by_name("crashlog");
135+
if (!crashlog)
136+
return;
137+
135138
maxlines = atoi(crashlog->maxlines);
136139
if (++current_lines >= maxlines) {
137140
LOGW("lines of (%s) meet quota %d, backup... Pls clean!\n",
138141
history_file, maxlines);
139142
backup_history();
140143
}
141144

142-
get_current_time_long(eventtime);
143-
entry.eventtime = eventtime;
145+
ret = get_current_time_long(eventtime);
146+
if (ret <= 0)
147+
return;
144148

149+
entry.eventtime = eventtime;
145150
entry_to_history_line(&entry, line);
146151
ret = append_file(history_file, line);
147152
if (ret < 0) {
@@ -165,6 +170,9 @@ void hist_raise_uptime(char *lastuptime)
165170

166171
/* user have configured the crashlog sender */
167172
crashlog = get_sender_by_name("crashlog");
173+
if (!crashlog)
174+
return;
175+
168176
uptime = crashlog->uptime;
169177
uptime_hours = atoi(uptime->eventhours);
170178

tools/acrn-crashlog/acrnprobe/include/load_conf.h

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -111,54 +111,54 @@ struct conf_t {
111111
struct conf_t conf;
112112

113113
#define for_each_sender(id, sender, conf) \
114-
for (id = 0, sender = conf.sender[0]; \
115-
id < SENDER_MAX; \
116-
id++, sender = conf.sender[id])
114+
for (id = 0; \
115+
id < SENDER_MAX && (sender = conf.sender[id]); \
116+
id++)
117117

118118
#define for_each_trigger(id, trigger, conf) \
119-
for (id = 0, trigger = conf.trigger[0]; \
120-
id < TRIGGER_MAX; \
121-
id++, trigger = conf.trigger[id])
119+
for (id = 0; \
120+
id < TRIGGER_MAX && (trigger = conf.trigger[id]); \
121+
id++)
122122

123123
#define for_each_vm(id, vm, conf) \
124-
for (id = 0, vm = conf.vm[0]; \
125-
id < VM_MAX; \
126-
id++, vm = conf.vm[id])
124+
for (id = 0; \
125+
id < VM_MAX && (vm = conf.vm[id]); \
126+
id++)
127127

128128
#define for_each_syncevent_vm(id, event, vm) \
129-
for (id = 0, event = vm->syncevent[0]; \
130-
id < VM_EVENT_TYPE_MAX; \
131-
id++, event = vm->syncevent[id])
129+
for (id = 0; \
130+
id < VM_EVENT_TYPE_MAX && (event = vm->syncevent[id]); \
131+
id++)
132132

133133
#define for_each_info(id, info, conf) \
134-
for (id = 0, info = conf.info[0]; \
135-
id < INFO_MAX; \
136-
id++, info = conf.info[id])
134+
for (id = 0; \
135+
id < INFO_MAX && (info = conf.info[id]); \
136+
id++)
137137

138138
#define for_each_log(id, log, conf) \
139-
for (id = 0, log = conf.log[0]; \
140-
id < LOG_MAX; \
141-
id++, log = conf.log[id])
139+
for (id = 0; \
140+
id < LOG_MAX && (log = conf.log[id]); \
141+
id++)
142142

143143
#define for_each_crash(id, crash, conf) \
144-
for (id = 0, crash = conf.crash[0]; \
145-
id < CRASH_MAX; \
146-
id++, crash = conf.crash[id])
144+
for (id = 0; \
145+
id < CRASH_MAX && (crash = conf.crash[id]); \
146+
id++)
147147

148148
#define for_each_log_collect(id, log, type) \
149-
for (id = 0, log = type->log[0]; \
150-
id < LOG_MAX; \
151-
id++, log = type->log[id])
149+
for (id = 0; \
150+
id < LOG_MAX && (log = type->log[id]); \
151+
id++)
152152

153153
#define for_each_content_crash(id, content, crash) \
154-
for (id = 0, content = crash->content[0]; \
155-
id < CONTENT_MAX; \
156-
id++, content = crash->content[id])
154+
for (id = 0; \
155+
id < CONTENT_MAX && (content = crash->content[id]); \
156+
id++)
157157

158158
#define for_each_content_expression(id, content, exp) \
159-
for (id = 0, content = exp[0]; \
160-
id < CONTENT_MAX; \
161-
id++, content = exp[id])
159+
for (id = 0; \
160+
id < CONTENT_MAX && (content = exp[id]); \
161+
id++)
162162

163163
#define exp_valid(exp) \
164164
(__extension__ \
@@ -175,9 +175,9 @@ struct conf_t conf;
175175
)
176176

177177
#define for_each_expression_crash(id, exp, crash) \
178-
for (id = 0, exp = crash->mightcontent[0]; \
179-
id < EXPRESSION_MAX; \
180-
id++, exp = crash->mightcontent[id])
178+
for (id = 0; \
179+
id < EXPRESSION_MAX && (exp = crash->mightcontent[id]); \
180+
id++)
181181

182182
#define for_crash_children(crash, tcrash) \
183183
TAILQ_FOREACH(crash, &tcrash->children, entries)

0 commit comments

Comments
 (0)