summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Wilgus <wilgus.william@gmail.com>2021-07-30 02:13:57 -0400
committerWilliam Wilgus <wilgus.william@gmail.com>2021-07-31 10:44:02 -0400
commitecf0d631e7e06db2ee1a0de98436ae1eb20c822c (patch)
tree26e8f99df4e4ef5e0ce068d28524382959993e1f
parent74134424113cb1325b97a896594d71db00ac1808 (diff)
downloadrockbox-ecf0d631e7e06db2ee1a0de98436ae1eb20c822c.tar.gz
rockbox-ecf0d631e7e06db2ee1a0de98436ae1eb20c822c.zip
tagcache.c Fix potential buffer overruns WIP
Needs tested Change-Id: I373b72c72f98777dc7a2d8085e975aeac164c297
-rw-r--r--apps/tagcache.c102
1 files changed, 70 insertions, 32 deletions
diff --git a/apps/tagcache.c b/apps/tagcache.c
index 4c09336641..f8b5a55321 100644
--- a/apps/tagcache.c
+++ b/apps/tagcache.c
@@ -363,12 +363,13 @@ static int open_tag_fd(struct tagcache_header *hdr, int tag, bool write)
363{ 363{
364 int fd; 364 int fd;
365 char buf[MAX_PATH]; 365 char buf[MAX_PATH];
366 const int bufsz = sizeof(buf);
366 int rc; 367 int rc;
367 368
368 if (TAGCACHE_IS_NUMERIC(tag) || tag < 0 || tag >= TAG_COUNT) 369 if (TAGCACHE_IS_NUMERIC(tag) || tag < 0 || tag >= TAG_COUNT)
369 return -1; 370 return -1;
370 371
371 snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, tag); 372 snprintf(buf, bufsz, TAGCACHE_FILE_INDEX, tag);
372 373
373 fd = open(buf, write ? O_RDWR : O_RDONLY); 374 fd = open(buf, write ? O_RDWR : O_RDONLY);
374 if (fd < 0) 375 if (fd < 0)
@@ -508,6 +509,7 @@ static long find_entry_disk(const char *filename_raw, bool localfd)
508 struct tagfile_entry tfe; 509 struct tagfile_entry tfe;
509 int fd; 510 int fd;
510 char buf[TAG_MAXLEN+32]; 511 char buf[TAG_MAXLEN+32];
512 const long bufsz = sizeof(buf);
511 int i; 513 int i;
512 int pos = -1; 514 int pos = -1;
513 515
@@ -549,7 +551,7 @@ static long find_entry_disk(const char *filename_raw, bool localfd)
549 break ; 551 break ;
550 } 552 }
551 553
552 if (tfe.tag_length >= (long)sizeof(buf)) 554 if (tfe.tag_length >= bufsz)
553 { 555 {
554 logf("too long tag #1"); 556 logf("too long tag #1");
555 close(fd); 557 close(fd);
@@ -568,6 +570,7 @@ static long find_entry_disk(const char *filename_raw, bool localfd)
568 last_pos = -1; 570 last_pos = -1;
569 return -3; 571 return -3;
570 } 572 }
573 buf[tfe.tag_length] = '\0';
571 574
572 if (!strcmp(filename, buf)) 575 if (!strcmp(filename, buf))
573 { 576 {
@@ -1056,6 +1059,7 @@ static bool check_clauses(struct tagcache_search *tcs,
1056 { 1059 {
1057 int seek; 1060 int seek;
1058 char buf[256]; 1061 char buf[256];
1062 const int bufsz = sizeof(buf);
1059 char *str = buf; 1063 char *str = buf;
1060 struct tagcache_search_clause *clause = clauses[i]; 1064 struct tagcache_search_clause *clause = clauses[i];
1061 1065
@@ -1076,7 +1080,7 @@ static bool check_clauses(struct tagcache_search *tcs,
1076 || clause->tag == tag_virt_basename) 1080 || clause->tag == tag_virt_basename)
1077 { 1081 {
1078 retrieve(tcs, IF_DIRCACHE(tcs->idx_id,) idx, tag_filename, 1082 retrieve(tcs, IF_DIRCACHE(tcs->idx_id,) idx, tag_filename,
1079 buf, sizeof buf); 1083 buf, bufsz);
1080 } 1084 }
1081 else 1085 else
1082 { 1086 {
@@ -1102,13 +1106,18 @@ static bool check_clauses(struct tagcache_search *tcs,
1102 int fd = tcs->idxfd[tag]; 1106 int fd = tcs->idxfd[tag];
1103 lseek(fd, seek, SEEK_SET); 1107 lseek(fd, seek, SEEK_SET);
1104 ecread_tagfile_entry(fd, &tfe); 1108 ecread_tagfile_entry(fd, &tfe);
1105 if (tfe.tag_length >= (int)sizeof(buf)) 1109 if (tfe.tag_length >= bufsz)
1106 { 1110 {
1107 logf("Too long tag read!"); 1111 logf("Too long tag read!");
1108 return false; 1112 return false;
1109 } 1113 }
1110 1114
1111 read(fd, str, tfe.tag_length); 1115 if (read(fd, str, tfe.tag_length)!= tfe.tag_length)
1116 {
1117 logf("read error #15");
1118 return false;
1119 }
1120
1112 str[tfe.tag_length] = '\0'; 1121 str[tfe.tag_length] = '\0';
1113 1122
1114 /* Check if entry has been deleted. */ 1123 /* Check if entry has been deleted. */
@@ -1303,7 +1312,8 @@ static void remove_files(void)
1303{ 1312{
1304 int i; 1313 int i;
1305 char buf[MAX_PATH]; 1314 char buf[MAX_PATH];
1306 1315 const int bufsz = sizeof(buf);
1316
1307 tc_stat.ready = false; 1317 tc_stat.ready = false;
1308 tc_stat.ramcache = false; 1318 tc_stat.ramcache = false;
1309 tc_stat.econ = false; 1319 tc_stat.econ = false;
@@ -1313,7 +1323,7 @@ static void remove_files(void)
1313 if (TAGCACHE_IS_NUMERIC(i)) 1323 if (TAGCACHE_IS_NUMERIC(i))
1314 continue; 1324 continue;
1315 1325
1316 snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, i); 1326 snprintf(buf, bufsz, TAGCACHE_FILE_INDEX, i);
1317 remove(buf); 1327 remove(buf);
1318 } 1328 }
1319} 1329}
@@ -1463,8 +1473,9 @@ bool tagcache_search_add_clause(struct tagcache_search *tcs,
1463 if (!TAGCACHE_IS_NUMERIC(clause->tag) && tcs->idxfd[clause->tag] < 0) 1473 if (!TAGCACHE_IS_NUMERIC(clause->tag) && tcs->idxfd[clause->tag] < 0)
1464 { 1474 {
1465 char buf[MAX_PATH]; 1475 char buf[MAX_PATH];
1466 1476 const int bufsz = sizeof(buf);
1467 snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, clause->tag); 1477
1478 snprintf(buf, bufsz, TAGCACHE_FILE_INDEX, clause->tag);
1468 tcs->idxfd[clause->tag] = open(buf, O_RDONLY); 1479 tcs->idxfd[clause->tag] = open(buf, O_RDONLY);
1469 } 1480 }
1470 } 1481 }
@@ -1477,7 +1488,9 @@ bool tagcache_search_add_clause(struct tagcache_search *tcs,
1477 1488
1478static bool get_next(struct tagcache_search *tcs) 1489static bool get_next(struct tagcache_search *tcs)
1479{ 1490{
1491 /* WARNING pointers into buf are used in outside functions */
1480 static char buf[TAG_MAXLEN+32]; 1492 static char buf[TAG_MAXLEN+32];
1493 const int bufsz = sizeof(buf);
1481 struct tagfile_entry entry; 1494 struct tagfile_entry entry;
1482#if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE) 1495#if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE)
1483 long flag = 0; 1496 long flag = 0;
@@ -1540,7 +1553,7 @@ static bool get_next(struct tagcache_search *tcs)
1540 1553
1541 if (TAGCACHE_IS_NUMERIC(tcs->type)) 1554 if (TAGCACHE_IS_NUMERIC(tcs->type))
1542 { 1555 {
1543 snprintf(buf, sizeof(buf), "%ld", tcs->position); 1556 snprintf(buf, bufsz, "%ld", tcs->position);
1544 tcs->result = buf; 1557 tcs->result = buf;
1545 tcs->result_len = strlen(buf) + 1; 1558 tcs->result_len = strlen(buf) + 1;
1546 return true; 1559 return true;
@@ -1600,8 +1613,8 @@ static bool get_next(struct tagcache_search *tcs)
1600 tcs->valid = false; 1613 tcs->valid = false;
1601 return false; 1614 return false;
1602 } 1615 }
1603 1616
1604 if (entry.tag_length > (long)sizeof(buf)) 1617 if (entry.tag_length > (long)bufsz)
1605 { 1618 {
1606 tcs->valid = false; 1619 tcs->valid = false;
1607 logf("too long tag #2"); 1620 logf("too long tag #2");
@@ -1621,6 +1634,7 @@ static bool get_next(struct tagcache_search *tcs)
1621 if filters or clauses are being used). 1634 if filters or clauses are being used).
1622 */ 1635 */
1623 tcs->position += sizeof(struct tagfile_entry) + entry.tag_length; 1636 tcs->position += sizeof(struct tagfile_entry) + entry.tag_length;
1637 buf[entry.tag_length] = '\0';
1624 tcs->result = buf; 1638 tcs->result = buf;
1625 tcs->result_len = strlen(tcs->result) + 1; 1639 tcs->result_len = strlen(tcs->result) + 1;
1626 tcs->idx_id = entry.idx_id; 1640 tcs->idx_id = entry.idx_id;
@@ -2014,8 +2028,9 @@ static bool tempbuf_insert(char *str, int id, int idx_id, bool unique)
2014 unsigned crc32; 2028 unsigned crc32;
2015 unsigned *crcbuf = (unsigned *)&tempbuf[tempbuf_size-4]; 2029 unsigned *crcbuf = (unsigned *)&tempbuf[tempbuf_size-4];
2016 char buf[TAG_MAXLEN+32]; 2030 char buf[TAG_MAXLEN+32];
2017 2031 const int bufsz = sizeof(buf);
2018 for (i = 0; str[i] != '\0' && i < (int)sizeof(buf)-1; i++) 2032
2033 for (i = 0; str[i] != '\0' && i < bufsz-1; i++)
2019 buf[i] = tolower(str[i]); 2034 buf[i] = tolower(str[i]);
2020 buf[i] = '\0'; 2035 buf[i] = '\0';
2021 2036
@@ -2227,7 +2242,9 @@ static bool build_numeric_indices(struct tagcache_header *h, int tmpfd)
2227 int max_entries; 2242 int max_entries;
2228 int entries_processed = 0; 2243 int entries_processed = 0;
2229 int i, j; 2244 int i, j;
2230 char buf[TAG_MAXLEN]; 2245
2246 char buf[TAG_MAXLEN + 32];
2247 const int bufsz = sizeof(buf);
2231 2248
2232 max_entries = tempbuf_size / sizeof(struct temp_file_entry) - 1; 2249 max_entries = tempbuf_size / sizeof(struct temp_file_entry) - 1;
2233 2250
@@ -2279,7 +2296,7 @@ static bool build_numeric_indices(struct tagcache_header *h, int tmpfd)
2279 */ 2296 */
2280#define tmpdb_read_string_tag(tag) \ 2297#define tmpdb_read_string_tag(tag) \
2281 lseek(tmpfd, tfe->tag_offset[tag], SEEK_CUR); \ 2298 lseek(tmpfd, tfe->tag_offset[tag], SEEK_CUR); \
2282 if ((unsigned long)tfe->tag_length[tag] > sizeof buf) \ 2299 if ((unsigned long)tfe->tag_length[tag] > (unsigned long)bufsz) \
2283 { \ 2300 { \
2284 logf("read fail: buffer overflow"); \ 2301 logf("read fail: buffer overflow"); \
2285 close(masterfd); \ 2302 close(masterfd); \
@@ -2293,6 +2310,7 @@ static bool build_numeric_indices(struct tagcache_header *h, int tmpfd)
2293 close(masterfd); \ 2310 close(masterfd); \
2294 return false; \ 2311 return false; \
2295 } \ 2312 } \
2313 buf[tfe->tag_length[tag]] = '\0'; \
2296 \ 2314 \
2297 tfe->tag_offset[tag] = crc_32(buf, strlen(buf), 0xffffffff); \ 2315 tfe->tag_offset[tag] = crc_32(buf, strlen(buf), 0xffffffff); \
2298 lseek(tmpfd, datastart, SEEK_SET) 2316 lseek(tmpfd, datastart, SEEK_SET)
@@ -2467,6 +2485,7 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd)
2467 struct index_entry idxbuf[IDX_BUF_DEPTH]; 2485 struct index_entry idxbuf[IDX_BUF_DEPTH];
2468 int idxbuf_pos; 2486 int idxbuf_pos;
2469 char buf[TAG_MAXLEN+32]; 2487 char buf[TAG_MAXLEN+32];
2488 const long bufsz = sizeof(buf);
2470 int fd = -1, masterfd; 2489 int fd = -1, masterfd;
2471 bool error = false; 2490 bool error = false;
2472 int init; 2491 int init;
@@ -2543,6 +2562,7 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd)
2543 if (tempbuf_left - TAGFILE_ENTRY_AVG_LENGTH * commit_entry_count < 0) 2562 if (tempbuf_left - TAGFILE_ENTRY_AVG_LENGTH * commit_entry_count < 0)
2544 { 2563 {
2545 logf("Buffer way too small!"); 2564 logf("Buffer way too small!");
2565 close(fd);
2546 return 0; 2566 return 0;
2547 } 2567 }
2548 2568
@@ -2569,7 +2589,7 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd)
2569 return -2; 2589 return -2;
2570 } 2590 }
2571 2591
2572 if (entry.tag_length >= (int)sizeof(buf)) 2592 if (entry.tag_length >= bufsz)
2573 { 2593 {
2574 logf("too long tag #3"); 2594 logf("too long tag #3");
2575 close(fd); 2595 close(fd);
@@ -2582,7 +2602,7 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd)
2582 close(fd); 2602 close(fd);
2583 return -2; 2603 return -2;
2584 } 2604 }
2585 2605 buf[entry.tag_length] = '\0';
2586 /* Skip deleted entries. */ 2606 /* Skip deleted entries. */
2587 if (buf[0] == '\0') 2607 if (buf[0] == '\0')
2588 continue; 2608 continue;
@@ -2613,7 +2633,7 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd)
2613 * Creating new index file to store the tags. No need to preload 2633 * Creating new index file to store the tags. No need to preload
2614 * anything whether the index type is sorted or not. 2634 * anything whether the index type is sorted or not.
2615 */ 2635 */
2616 snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, index_type); 2636 snprintf(buf, bufsz, TAGCACHE_FILE_INDEX, index_type);
2617 fd = open(buf, O_WRONLY | O_CREAT | O_TRUNC, 0666); 2637 fd = open(buf, O_WRONLY | O_CREAT | O_TRUNC, 0666);
2618 if (fd < 0) 2638 if (fd < 0)
2619 { 2639 {
@@ -2715,7 +2735,7 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd)
2715 } 2735 }
2716 2736
2717 /* Read data. */ 2737 /* Read data. */
2718 if (entry.tag_length[index_type] >= (long)sizeof(buf)) 2738 if (entry.tag_length[index_type] >= (long)bufsz)
2719 { 2739 {
2720 logf("too long entry!"); 2740 logf("too long entry!");
2721 error = true; 2741 error = true;
@@ -2730,6 +2750,7 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd)
2730 error = true; 2750 error = true;
2731 goto error_exit; 2751 goto error_exit;
2732 } 2752 }
2753 buf[entry.tag_length[index_type]] = '\0';
2733 2754
2734 if (TAGCACHE_IS_UNIQUE(index_type)) 2755 if (TAGCACHE_IS_UNIQUE(index_type))
2735 error = !tempbuf_insert(buf, i, -1, true); 2756 error = !tempbuf_insert(buf, i, -1, true);
@@ -3306,9 +3327,11 @@ void tagcache_update_numeric(int idx_id, int tag, long data)
3306static bool write_tag(int fd, const char *tagstr, const char *datastr) 3327static bool write_tag(int fd, const char *tagstr, const char *datastr)
3307{ 3328{
3308 char buf[512]; 3329 char buf[512];
3330 const int bufsz = sizeof(buf);
3309 int i; 3331 int i;
3310 3332
3311 snprintf(buf, sizeof buf, "%s=\"", tagstr); 3333 snprintf(buf, bufsz, "%s=\"", tagstr);
3334
3312 for (i = strlen(buf); i < (long)sizeof(buf)-4; i++) 3335 for (i = strlen(buf); i < (long)sizeof(buf)-4; i++)
3313 { 3336 {
3314 if (*datastr == '\0') 3337 if (*datastr == '\0')
@@ -3327,7 +3350,8 @@ static bool write_tag(int fd, const char *tagstr, const char *datastr)
3327 buf[i] = *(datastr++); 3350 buf[i] = *(datastr++);
3328 } 3351 }
3329 3352
3330 strcpy(&buf[i], "\" "); 3353 buf[bufsz - 1] = '\0';
3354 strlcpy(&buf[i], "\" ", (bufsz - i - 1));
3331 3355
3332 write(fd, buf, i + 2); 3356 write(fd, buf, i + 2);
3333 3357
@@ -3487,6 +3511,7 @@ bool tagcache_import_changelog(void)
3487 int clfd; 3511 int clfd;
3488 long masterfd; 3512 long masterfd;
3489 char buf[2048]; 3513 char buf[2048];
3514 const int bufsz = sizeof(buf);
3490 3515
3491 if (!tc_stat.ready) 3516 if (!tc_stat.ready)
3492 return false; 3517 return false;
@@ -3510,8 +3535,8 @@ bool tagcache_import_changelog(void)
3510 write_lock++; 3535 write_lock++;
3511 3536
3512 filenametag_fd = open_tag_fd(&tch, tag_filename, false); 3537 filenametag_fd = open_tag_fd(&tch, tag_filename, false);
3513 3538
3514 fast_readline(clfd, buf, sizeof buf, (void *)(intptr_t)masterfd, 3539 fast_readline(clfd, buf, bufsz, (void *)(intptr_t)masterfd,
3515 parse_changelog_line); 3540 parse_changelog_line);
3516 3541
3517 close(clfd); 3542 close(clfd);
@@ -3537,6 +3562,7 @@ bool tagcache_create_changelog(struct tagcache_search *tcs)
3537 struct master_header myhdr; 3562 struct master_header myhdr;
3538 struct index_entry idx; 3563 struct index_entry idx;
3539 char buf[TAG_MAXLEN+32]; 3564 char buf[TAG_MAXLEN+32];
3565 const int bufsz = sizeof(buf);
3540 char temp[32]; 3566 char temp[32];
3541 int clfd; 3567 int clfd;
3542 int i, j; 3568 int i, j;
@@ -3600,7 +3626,7 @@ bool tagcache_create_changelog(struct tagcache_search *tcs)
3600 } 3626 }
3601 3627
3602 tcs->type = j; 3628 tcs->type = j;
3603 tagcache_retrieve(tcs, i, tcs->type, buf, sizeof buf); 3629 tagcache_retrieve(tcs, i, tcs->type, buf, bufsz);
3604 write_tag(clfd, tagcache_tag_to_str(j), buf); 3630 write_tag(clfd, tagcache_tag_to_str(j), buf);
3605 } 3631 }
3606 3632
@@ -3623,6 +3649,7 @@ static bool delete_entry(long idx_id)
3623 struct index_entry idx, myidx; 3649 struct index_entry idx, myidx;
3624 struct master_header myhdr; 3650 struct master_header myhdr;
3625 char buf[TAG_MAXLEN+32]; 3651 char buf[TAG_MAXLEN+32];
3652 const int bufsz = sizeof(buf);
3626 int in_use[TAG_COUNT]; 3653 int in_use[TAG_COUNT];
3627 3654
3628 logf("delete_entry(): %ld", idx_id); 3655 logf("delete_entry(): %ld", idx_id);
@@ -3737,11 +3764,18 @@ static bool delete_entry(long idx_id)
3737 goto cleanup; 3764 goto cleanup;
3738 } 3765 }
3739 3766
3767 if (tfe.tag_length >= (long)bufsz)
3768 {
3769 logf("too long tag #4");
3770 goto cleanup;
3771 }
3772
3740 if (read(fd, buf, tfe.tag_length) != tfe.tag_length) 3773 if (read(fd, buf, tfe.tag_length) != tfe.tag_length)
3741 { 3774 {
3742 logf("delete_entry(): read error #4"); 3775 logf("delete_entry(): read error #4");
3743 goto cleanup; 3776 goto cleanup;
3744 } 3777 }
3778 buf[tfe.tag_length] = '\0';
3745 3779
3746 myidx.tag_seek[tag] = crc_32(buf, strlen(buf), 0xffffffff); 3780 myidx.tag_seek[tag] = crc_32(buf, strlen(buf), 0xffffffff);
3747 } 3781 }
@@ -4254,10 +4288,11 @@ static bool check_deleted_files(void)
4254{ 4288{
4255 int fd; 4289 int fd;
4256 char buf[TAG_MAXLEN+32]; 4290 char buf[TAG_MAXLEN+32];
4291 const int bufsz = sizeof(buf);
4257 struct tagfile_entry tfe; 4292 struct tagfile_entry tfe;
4258 4293
4259 logf("reverse scan..."); 4294 logf("reverse scan...");
4260 snprintf(buf, sizeof buf, TAGCACHE_FILE_INDEX, tag_filename); 4295 snprintf(buf, bufsz, TAGCACHE_FILE_INDEX, tag_filename);
4261 fd = open(buf, O_RDONLY); 4296 fd = open(buf, O_RDONLY);
4262 4297
4263 if (fd < 0) 4298 if (fd < 0)
@@ -4270,7 +4305,7 @@ static bool check_deleted_files(void)
4270 while (ecread_tagfile_entry(fd, &tfe) == sizeof(struct tagfile_entry) 4305 while (ecread_tagfile_entry(fd, &tfe) == sizeof(struct tagfile_entry)
4271 && !check_event_queue()) 4306 && !check_event_queue())
4272 { 4307 {
4273 if (tfe.tag_length >= (long)sizeof(buf)-1) 4308 if (tfe.tag_length >= (long)bufsz-1)
4274 { 4309 {
4275 logf("too long tag"); 4310 logf("too long tag");
4276 close(fd); 4311 close(fd);
@@ -4283,6 +4318,7 @@ static bool check_deleted_files(void)
4283 close(fd); 4318 close(fd);
4284 return false; 4319 return false;
4285 } 4320 }
4321 buf[tfe.tag_length] = '\0';
4286 4322
4287 /* Check if the file has already deleted from the db. */ 4323 /* Check if the file has already deleted from the db. */
4288 if (*buf == '\0') 4324 if (*buf == '\0')
@@ -4314,12 +4350,13 @@ static void NO_INLINE check_ignore(const char *dirname,
4314 int *ignore, int *unignore) 4350 int *ignore, int *unignore)
4315{ 4351{
4316 char newpath[MAX_PATH]; 4352 char newpath[MAX_PATH];
4353 const int bufsz = sizeof(newpath);
4317 4354
4318 /* check for a database.ignore file */ 4355 /* check for a database.ignore file */
4319 snprintf(newpath, MAX_PATH, "%s/database.ignore", dirname); 4356 snprintf(newpath, bufsz, "%s/database.ignore", dirname);
4320 *ignore = file_exists(newpath); 4357 *ignore = file_exists(newpath);
4321 /* check for a database.unignore file */ 4358 /* check for a database.unignore file */
4322 snprintf(newpath, MAX_PATH, "%s/database.unignore", dirname); 4359 snprintf(newpath, bufsz, "%s/database.unignore", dirname);
4323 *unignore = file_exists(newpath); 4360 *unignore = file_exists(newpath);
4324} 4361}
4325 4362
@@ -4365,6 +4402,7 @@ static bool add_search_root(const char *name)
4365#ifndef WIN32 4402#ifndef WIN32
4366 struct search_roots_ll *this, *prev = NULL; 4403 struct search_roots_ll *this, *prev = NULL;
4367 char target[MAX_PATH]; 4404 char target[MAX_PATH];
4405 const int target_bufsz = sizeof(target);
4368 /* Okay, realpath() is almost completely broken on android 4406 /* Okay, realpath() is almost completely broken on android
4369 * 4407 *
4370 * It doesn't accept NULL for resolved_name to dynamically allocate 4408 * It doesn't accept NULL for resolved_name to dynamically allocate
@@ -4378,7 +4416,7 @@ static bool add_search_root(const char *name)
4378 static char abs_target[PATH_MAX]; 4416 static char abs_target[PATH_MAX];
4379 ssize_t len; 4417 ssize_t len;
4380 4418
4381 len = readlink(name, target, sizeof(target)-1); 4419 len = readlink(name, target, target_bufsz-1);
4382 if (len < 0) 4420 if (len < 0)
4383 return false; 4421 return false;
4384 4422
@@ -4396,7 +4434,7 @@ static bool add_search_root(const char *name)
4396 { 4434 {
4397 size_t len = strlen(abs_target) + 1; /* count \0 */ 4435 size_t len = strlen(abs_target) + 1; /* count \0 */
4398 this = malloc(sizeof(struct search_roots_ll) + len ); 4436 this = malloc(sizeof(struct search_roots_ll) + len );
4399 if (!this || len > MAX_PATH) 4437 if (!this || len > MIN(PATH_MAX, MAX_PATH))
4400 { 4438 {
4401 logf("Error at adding a search root: %s", this ? "path too long":"OOM"); 4439 logf("Error at adding a search root: %s", this ? "path too long":"OOM");
4402 free(this); 4440 free(this);
@@ -4583,7 +4621,7 @@ void do_tagcache_build(const char *path[])
4583 /* check_dir might add new roots */ 4621 /* check_dir might add new roots */
4584 for(this = &roots_ll[0]; this; this = this->next) 4622 for(this = &roots_ll[0]; this; this = this->next)
4585 { 4623 {
4586 strcpy(curpath, this->path); 4624 strlcpy(curpath, this->path, sizeof(curpath));
4587 ret = ret && check_dir(this->path, true); 4625 ret = ret && check_dir(this->path, true);
4588 } 4626 }
4589 free_search_roots(&roots_ll[0]); 4627 free_search_roots(&roots_ll[0]);