Skip to content

Commit cb39bad

Browse files
xiaojingrichlijinxia
authored andcommitted
tools: acrn-crashlog: fix potential issues under common and usercrash
This patch is to fix buffer overflow, return value not unified and variable type not matched issues. And add some judge logic to improve code quality. Changes: 1. Handle the fd properly in the failing case. 2. Fix buffer overflow issues and null pointer access issues. 3. Fix the format issue in log_sys.c. 4. Remove the useless branch and adjust the function logic. 5. Add some checks for the string length before using strcpy/strcat/memcpy. 6. Fix strncpy null-terminated issues. 7. Change the return value to unify the return type. Signed-off-by: CHEN Gang <gang.c.chen@intel.com> Signed-off-by: xiaojin2 <xiaojing.liu@intel.com> Reviewed-by: Zhi Jin <zhi.jin@intel.com> Reviewed-by: Liu Xinwu <xinwu.liu@intel.com> Acked-by: Zhang Di <di.zhang@intel.com>
1 parent 48067b1 commit cb39bad

File tree

10 files changed

+112
-81
lines changed

10 files changed

+112
-81
lines changed

tools/acrn-crashlog/common/cmdutils.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ int execv_out2file(char *argv[], char *outfile)
4747

4848
if (pid == 0) {
4949
int res;
50-
int fd;
50+
int fd = -1;
5151

5252
if (outfile) {
5353
fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, 0664);
@@ -65,6 +65,8 @@ int execv_out2file(char *argv[], char *outfile)
6565

6666
res = execvp(argv[0], argv);
6767
if (res == -1) {
68+
if (fd > 0)
69+
close(fd);
6870
LOGE("execvp (%s) failed, error (%s)\n", argv[0],
6971
strerror(errno));
7072
return -1;
@@ -211,8 +213,10 @@ char *exec_out2mem(char *fmt, ...)
211213
memsize += 1024;
212214
new = realloc(out, memsize);
213215
if (!new) {
214-
if (out)
216+
if (out) {
215217
free(out);
218+
out = NULL;
219+
}
216220
goto end;
217221
} else {
218222
out = new;

tools/acrn-crashlog/common/fsutils.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,12 @@ char *mm_get_line(struct mm_file_t *mfile, int line)
114114

115115
if (line <= 0 || line > mm_count_lines(mfile))
116116
return NULL;
117-
else if (line == 1)
117+
118+
if (line == 1)
118119
ret = begin;
119120
else {
120121
next = begin;
121-
for (i = 2; i <= line; i++)
122+
for (i = 2; i <= line && next; i++)
122123
next = strchr(next, '\n') + 1;
123124
ret = next;
124125
}
@@ -820,7 +821,7 @@ int read_full_binary_file(const char *path, unsigned long *size, void **data)
820821
close_file(path, f);
821822

822823
*data = buf;
823-
*size = (unsigned int)_size;
824+
*size = (unsigned long)_size;
824825

825826
return 0;
826827

@@ -1112,7 +1113,7 @@ int read_file(const char *path, unsigned long *size, void **data)
11121113
int len = 0;
11131114
int fd = 0;
11141115
int memsize = 1; /* for '\0' */
1115-
size_t result = 0;
1116+
ssize_t result = 0;
11161117
char *out = NULL;
11171118
char *new;
11181119

@@ -1129,6 +1130,8 @@ int read_file(const char *path, unsigned long *size, void **data)
11291130
result = read(fd, (void *)tmp, 1024);
11301131
if (result == 0)
11311132
break;
1133+
else if (result == -1)
1134+
goto free;
11321135

11331136
memsize += result;
11341137
new = realloc(out, memsize);
@@ -1145,7 +1148,7 @@ int read_file(const char *path, unsigned long *size, void **data)
11451148
close(fd);
11461149

11471150
*data = out;
1148-
*size = (unsigned int)len;
1151+
*size = (unsigned long)len;
11491152

11501153
return 0;
11511154

tools/acrn-crashlog/common/log_sys.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ void do_log(const int level,
1919
char log[MAX_LOG_LEN];
2020
int n = 0;
2121
#ifdef DEBUG_ACRN_CRASHLOG
22-
const char header_fmt[] = "<%-20s%d>: ";
22+
const char header_fmt[] = "<%-20s%5d>: ";
2323
#endif
2424

2525
if (level > LOG_LEVEL)
@@ -37,7 +37,7 @@ void do_log(const int level,
3737
#ifdef DEBUG_ACRN_CRASHLOG
3838
/* header */
3939
n = snprintf(log, sizeof(log), header_fmt, func, line);
40-
if (n < 0 || n >= sizeof(log))
40+
if (n < 0 || (size_t)n >= sizeof(log))
4141
n = 0;
4242
#endif
4343
/* msg */

tools/acrn-crashlog/common/strutils.c

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,20 +74,29 @@ static char *strtriml(char *str)
7474

7575
static char *strtrimr(char *str)
7676
{
77-
char *end = str + strlen(str) - 1;
78-
79-
while (*end == ' ' && end >= str) {
80-
*end = 0;
81-
end--;
77+
size_t len;
78+
char *end;
79+
80+
len = strlen(str);
81+
if (len > 0) {
82+
end = str + strlen(str) - 1;
83+
while (*end == ' ' && end >= str) {
84+
*end = 0;
85+
end--;
86+
}
8287
}
8388

8489
return str;
8590
}
8691

8792
char *strtrim(char *str)
8893
{
89-
strtrimr(str);
90-
return strtriml(str);
94+
if (str) {
95+
strtrimr(str);
96+
return strtriml(str);
97+
}
98+
99+
return NULL;
91100
}
92101

93102
int strcnt(char *str, char c)

tools/acrn-crashlog/usercrash/client.c

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -72,24 +72,29 @@ static int set_timeout(int sockfd)
7272
* usercrashd_connect is used to connect to server, and get the crash file fd
7373
* from server
7474
*/
75-
bool usercrashd_connect(int pid, int *usercrashd_socket,
76-
int *output_fd, char *name)
75+
static int usercrashd_connect(int pid, int *usercrashd_socket,
76+
int *output_fd, const char *name)
7777
{
7878
int sockfd;
7979
int tmp_output_fd;
8080
ssize_t rc;
8181
int flags;
8282
struct crash_packet packet = {0};
8383

84+
if (name == NULL) {
85+
LOGE("crash process name is NULL\n");
86+
return -1;
87+
}
8488
sockfd = socket_local_client(SOCKET_NAME, SOCK_SEQPACKET);
8589
if (sockfd == -1) {
8690
LOGE("failed to connect to usercrashd, error (%s)\n",
8791
strerror(errno));
88-
return false;
92+
return -1;
8993
}
9094
packet.packet_type = kDumpRequest;
9195
packet.pid = pid;
92-
strncpy(packet.name, name, COMM_NAME_LEN - 1);
96+
strncpy(packet.name, name, COMM_NAME_LEN);
97+
packet.name[COMM_NAME_LEN - 1] = '\0';
9398
if (set_timeout(sockfd)) {
9499
close(sockfd);
95100
return -1;
@@ -99,7 +104,7 @@ bool usercrashd_connect(int pid, int *usercrashd_socket,
99104
LOGE("failed to write DumpRequest packet, error (%s)\n",
100105
strerror(errno));
101106
close(sockfd);
102-
return false;
107+
return -1;
103108
}
104109

105110
rc = recv_fd(sockfd, &packet, sizeof(packet),
@@ -108,7 +113,7 @@ bool usercrashd_connect(int pid, int *usercrashd_socket,
108113
LOGE("failed to read response to DumpRequest packet, ");
109114
LOGE("error (%s)\n", strerror(errno));
110115
close(sockfd);
111-
return false;
116+
return -1;
112117
} else if (rc != sizeof(packet)) {
113118
LOGE("received DumpRequest response packet of incorrect ");
114119
LOGE("length (expected %lu, got %ld)\n", sizeof(packet), rc);
@@ -135,11 +140,11 @@ bool usercrashd_connect(int pid, int *usercrashd_socket,
135140
*usercrashd_socket = sockfd;
136141
*output_fd = tmp_output_fd;
137142

138-
return true;
143+
return 0;
139144
fail:
140145
close(sockfd);
141146
close(tmp_output_fd);
142-
return false;
147+
return -1;
143148

144149
}
145150

@@ -149,7 +154,7 @@ bool usercrashd_connect(int pid, int *usercrashd_socket,
149154
* dump, the server will pop another crash from the queue and execute the dump
150155
* process
151156
*/
152-
bool usercrashd_notify_completion(int usercrashd_socket)
157+
static int usercrashd_notify_completion(int usercrashd_socket)
153158
{
154159
struct crash_packet packet = {0};
155160

@@ -160,14 +165,15 @@ bool usercrashd_notify_completion(int usercrashd_socket)
160165
}
161166
if (write(usercrashd_socket, &packet,
162167
sizeof(packet)) != sizeof(packet)) {
163-
return false;
168+
return -1;
164169
}
165-
return true;
170+
return 0;
166171
}
167172

168173
static void print_usage(void)
169174
{
170-
printf("It's the client role of usercrash.\n");
175+
printf("usercrash - tool to dump crash info for the crashes in the ");
176+
printf("userspace on sos. It's the client role of usercrash.\n");
171177
printf("[Usage]\n");
172178
printf("\t--coredump, usercrash_c <pid> <comm> <sig> ");
173179
printf("(root role to run)\n");
@@ -209,14 +215,14 @@ int main(int argc, char *argv[])
209215
pid = atoi(argv[1]);
210216
sig = atoi(argv[3]);
211217
ret = usercrashd_connect(pid, &sock, &out_fd, argv[2]);
212-
if (!ret) {
218+
if (ret) {
213219
LOGE("usercrashd_connect failed, error (%s)\n",
214220
strerror(errno));
215221
exit(EXIT_FAILURE);
216222
}
217223
crash_dump(pid, sig, out_fd);
218224
close(out_fd);
219-
if (!usercrashd_notify_completion(sock)) {
225+
if (usercrashd_notify_completion(sock)) {
220226
LOGE("failed to notify usercrashd of completion");
221227
close(sock);
222228
exit(EXIT_FAILURE);

tools/acrn-crashlog/usercrash/crash_dump.c

Lines changed: 29 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -79,43 +79,35 @@ static const char *get_signame(int sig)
7979
*/
8080
static int save_coredump(const char *filename)
8181
{
82-
size_t read;
82+
size_t read_len;
83+
size_t write_len;
8384
char input_buffer[BUFFER_SIZE];
8485
FILE *dump_file;
8586

8687
/* open dump file in write and binary mode */
8788
dump_file = fopen(filename, "wb");
88-
if (dump_file != NULL) {
89-
/* Read from STDIN and write to dump file */
90-
while (1) {
91-
read = fread(input_buffer, 1, BUFFER_SIZE, stdin);
92-
if (read > 0) {
93-
if (fwrite(input_buffer, 1, read, dump_file) <=
94-
0) {
95-
LOGE("fwrite error\n");
96-
goto fail;
97-
}
98-
continue;
99-
} else if (read == 0) {
100-
break;
101-
}
102-
103-
LOGE("fread error\n");
104-
goto fail;
89+
if (dump_file == NULL) {
90+
LOGE("fopen core file failed\n");
91+
return -1;
92+
}
93+
/* Read from STDIN and write to dump file */
94+
while (1) {
95+
read_len = fread(input_buffer, 1, BUFFER_SIZE, stdin);
96+
if (read_len == 0)
97+
break;
98+
write_len = fwrite(input_buffer, 1, read_len, dump_file);
99+
if (write_len == 0) {
100+
LOGE("fwrite error\n");
101+
fclose(dump_file);
102+
return -1;
105103
}
106-
fclose(dump_file);
107-
return 0;
108104
}
109105

110-
LOGE("fopen core file failed\n");
111-
return -1;
112-
113-
fail:
114106
fclose(dump_file);
115-
return -1;
107+
return 0;
116108
}
117109

118-
static int get_backtrace(int pid, int fd, int sig, char *comm)
110+
static int get_backtrace(int pid, int fd, int sig, const char *comm)
119111
{
120112
char *membkt;
121113
char format[512];
@@ -150,7 +142,7 @@ static int get_backtrace(int pid, int fd, int sig, char *comm)
150142
* @name: a string save to file
151143
* return 0 on success, or -1 on error
152144
*/
153-
static int save_proc_info(int pid, int fd, char *path, char *name)
145+
static int save_proc_info(int pid, int fd, const char *path, const char *name)
154146
{
155147
int ret;
156148
char *data;
@@ -171,7 +163,7 @@ static int save_proc_info(int pid, int fd, char *path, char *name)
171163

172164
}
173165

174-
static int get_openfiles(int pid, int fd, char *path, char *name)
166+
static int get_openfiles(int pid, int fd, const char *path, const char *name)
175167
{
176168
int ret;
177169
int loop;
@@ -205,7 +197,7 @@ static int get_openfiles(int pid, int fd, char *path, char *name)
205197
return 0;
206198
}
207199

208-
static int save_usercrash_file(int pid, int tgid, char *comm,
200+
static int save_usercrash_file(int pid, int tgid, const char *comm,
209201
int sig, int out_fd)
210202
{
211203
int ret;
@@ -242,7 +234,8 @@ static int save_usercrash_file(int pid, int tgid, char *comm,
242234
return 0;
243235
}
244236

245-
static int get_key_value(int pid, char *path, char *key, char *value)
237+
static int get_key_value(int pid, const char *path, const char *key,
238+
char *value, size_t value_len)
246239
{
247240
int len;
248241
int ret;
@@ -256,7 +249,7 @@ static int get_key_value(int pid, char *path, char *key, char *value)
256249
memset(format, 0, sizeof(format));
257250
snprintf(format, sizeof(format), path, pid);
258251
ret = read_file(format, &size, (void *)&data);
259-
if (ret) {
252+
if (ret || !data) {
260253
LOGE("read file failed\n");
261254
return -1;
262255
}
@@ -271,6 +264,10 @@ static int get_key_value(int pid, char *path, char *key, char *value)
271264
end = data + size;
272265
start = msg + strlen(key);
273266
len = end - start;
267+
if (len >= (int)value_len) {
268+
free(data);
269+
return -1;
270+
}
274271
memcpy(value, start, len);
275272
*(value + len) = 0;
276273
free(data);
@@ -301,7 +298,7 @@ void crash_dump(int pid, int sig, int out_fd)
301298
}
302299
comm[ret] = '\0';
303300

304-
ret = get_key_value(pid, GET_TID, "Tgid:", result);
301+
ret = get_key_value(pid, GET_TID, "Tgid:", result, sizeof(result));
305302
if (ret) {
306303
LOGE("get Tgid error\n");
307304
return;

tools/acrn-crashlog/usercrash/debugger.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,9 @@
1919
*/
2020
static void print_usage(void)
2121
{
22-
printf("debugger - tool to dump process info of a running process. ");
22+
printf("debugger - tool to dump process info of a running process.\n");
2323
printf("[Usage]\n");
2424
printf("\t--shell cmd, debugger <pid> (root role to run)\n");
25-
printf("(root role to run)\n");
2625
printf("[Option]\n");
2726
printf("\t-h: print this usage message\n");
2827
printf("\t-v: print debugger version\n");
@@ -48,7 +47,7 @@ int main(int argc, char *argv[])
4847
print_usage();
4948

5049
if (getuid() != 0) {
51-
LOGE("failed to execute debugger, root is required\n");
50+
printf("failed to execute debugger, root is required\n");
5251
exit(EXIT_FAILURE);
5352
}
5453

0 commit comments

Comments
 (0)