diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-05-15 14:24:41 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-05-15 14:24:41 +0000 |
commit | 3b30625dd217ffb650584df0f00fe1cbb73e2619 (patch) | |
tree | bedf45cfbe9f168297484dde614c0b351575c794 | |
parent | f536ece4ac20ca0b6bb3cb4aa7e075125c322d69 (diff) | |
download | gnunet-3b30625dd217ffb650584df0f00fe1cbb73e2619.tar.gz gnunet-3b30625dd217ffb650584df0f00fe1cbb73e2619.zip |
-adding checks to avoid #2352 segfault
-rw-r--r-- | src/fs/fs_download.c | 87 |
1 files changed, 46 insertions, 41 deletions
diff --git a/src/fs/fs_download.c b/src/fs/fs_download.c index 4def42545..38b55ba4d 100644 --- a/src/fs/fs_download.c +++ b/src/fs/fs_download.c | |||
@@ -1063,7 +1063,6 @@ process_result_with_request (void *cls, const GNUNET_HashCode * key, | |||
1063 | if (is_recursive_download (dc)) | 1063 | if (is_recursive_download (dc)) |
1064 | GNUNET_FS_directory_list_contents (prc->size, pt, off, | 1064 | GNUNET_FS_directory_list_contents (prc->size, pt, off, |
1065 | &trigger_recursive_download, dc); | 1065 | &trigger_recursive_download, dc); |
1066 | |||
1067 | } | 1066 | } |
1068 | GNUNET_assert (dc->completed <= dc->length); | 1067 | GNUNET_assert (dc->completed <= dc->length); |
1069 | dr->state = BRS_DOWNLOAD_DOWN; | 1068 | dr->state = BRS_DOWNLOAD_DOWN; |
@@ -1120,6 +1119,13 @@ process_result_with_request (void *cls, const GNUNET_HashCode * key, | |||
1120 | switch (drc->state) | 1119 | switch (drc->state) |
1121 | { | 1120 | { |
1122 | case BRS_INIT: | 1121 | case BRS_INIT: |
1122 | if ((drc->chk_idx + 1) * sizeof (struct ContentHashKey) > prc->size) | ||
1123 | { | ||
1124 | /* 'chkarr' does not have enough space for this chk_idx; | ||
1125 | internal error! */ | ||
1126 | GNUNET_break (0); | ||
1127 | return GNUNET_SYSERR; | ||
1128 | } | ||
1123 | drc->chk = chkarr[drc->chk_idx]; | 1129 | drc->chk = chkarr[drc->chk_idx]; |
1124 | drc->state = BRS_CHK_SET; | 1130 | drc->state = BRS_CHK_SET; |
1125 | if (GNUNET_YES == dc->issue_requests) | 1131 | if (GNUNET_YES == dc->issue_requests) |
@@ -1518,45 +1524,44 @@ create_download_request (struct DownloadRequest *parent, | |||
1518 | dr->depth = depth; | 1524 | dr->depth = depth; |
1519 | dr->offset = dr_offset; | 1525 | dr->offset = dr_offset; |
1520 | dr->chk_idx = chk_idx; | 1526 | dr->chk_idx = chk_idx; |
1521 | if (depth > 0) | 1527 | if (0 == depth) |
1522 | { | 1528 | return dr; |
1523 | child_block_size = GNUNET_FS_tree_compute_tree_size (depth - 1); | 1529 | child_block_size = GNUNET_FS_tree_compute_tree_size (depth - 1); |
1524 | 1530 | ||
1525 | /* calculate how many blocks at this level are not interesting | 1531 | /* calculate how many blocks at this level are not interesting |
1526 | * from the start (rounded down), either because of the requested | 1532 | * from the start (rounded down), either because of the requested |
1527 | * file offset or because this IBlock is further along */ | 1533 | * file offset or because this IBlock is further along */ |
1528 | if (dr_offset < file_start_offset) | 1534 | if (dr_offset < file_start_offset) |
1529 | head_skip = file_start_offset / child_block_size; | 1535 | head_skip = file_start_offset / child_block_size; |
1530 | else | 1536 | else |
1531 | head_skip = 0; | 1537 | head_skip = 0; |
1532 | 1538 | ||
1533 | /* calculate index of last block at this level that is interesting (rounded up) */ | 1539 | /* calculate index of last block at this level that is interesting (rounded up) */ |
1534 | dr->num_children = (file_start_offset + desired_length - dr_offset) / child_block_size; | 1540 | dr->num_children = (file_start_offset + desired_length - dr_offset) / child_block_size; |
1535 | if (dr->num_children * child_block_size < | 1541 | if (dr->num_children * child_block_size < |
1536 | file_start_offset + desired_length - dr_offset) | 1542 | file_start_offset + desired_length - dr_offset) |
1537 | dr->num_children++; /* round up */ | 1543 | dr->num_children++; /* round up */ |
1538 | dr->num_children -= head_skip; | 1544 | dr->num_children -= head_skip; |
1539 | if (dr->num_children > CHK_PER_INODE) | 1545 | if (dr->num_children > CHK_PER_INODE) |
1540 | dr->num_children = CHK_PER_INODE; /* cap at max */ | 1546 | dr->num_children = CHK_PER_INODE; /* cap at max */ |
1541 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1547 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1542 | "Block at offset %llu and depth %u has %u children\n", | 1548 | "Block at offset %llu and depth %u has %u children\n", |
1543 | (unsigned long long) dr_offset, | 1549 | (unsigned long long) dr_offset, |
1544 | depth, | 1550 | depth, |
1545 | dr->num_children); | 1551 | dr->num_children); |
1546 | 1552 | ||
1547 | /* now we can get the total number of *interesting* children for this block */ | 1553 | /* now we can get the total number of *interesting* children for this block */ |
1548 | 1554 | ||
1549 | /* why else would we have gotten here to begin with? (that'd be a bad logic error) */ | 1555 | /* why else would we have gotten here to begin with? (that'd be a bad logic error) */ |
1550 | GNUNET_assert (dr->num_children > 0); | 1556 | GNUNET_assert (dr->num_children > 0); |
1551 | 1557 | ||
1552 | dr->children = | 1558 | dr->children = |
1553 | GNUNET_malloc (dr->num_children * sizeof (struct DownloadRequest *)); | 1559 | GNUNET_malloc (dr->num_children * sizeof (struct DownloadRequest *)); |
1554 | for (i = 0; i < dr->num_children; i++) | 1560 | for (i = 0; i < dr->num_children; i++) |
1555 | dr->children[i] = | 1561 | dr->children[i] = |
1556 | create_download_request (dr, i + head_skip, depth - 1, | 1562 | create_download_request (dr, i + head_skip, depth - 1, |
1557 | dr_offset + (i + head_skip) * child_block_size, | 1563 | dr_offset + (i + head_skip) * child_block_size, |
1558 | file_start_offset, desired_length); | 1564 | file_start_offset, desired_length); |
1559 | } | ||
1560 | return dr; | 1565 | return dr; |
1561 | } | 1566 | } |
1562 | 1567 | ||
@@ -1649,7 +1654,7 @@ reconstruct_cb (void *cls, const struct ContentHashKey *chk, uint64_t offset, | |||
1649 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1654 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1650 | "Block %u < %u irrelevant for our range\n", | 1655 | "Block %u < %u irrelevant for our range\n", |
1651 | chld, | 1656 | chld, |
1652 | dr->children[dr->num_children-1]->chk_idx); | 1657 | dr->children[0]->chk_idx); |
1653 | dc->task = GNUNET_SCHEDULER_add_now (&get_next_block, dc); | 1658 | dc->task = GNUNET_SCHEDULER_add_now (&get_next_block, dc); |
1654 | return; /* irrelevant block */ | 1659 | return; /* irrelevant block */ |
1655 | } | 1660 | } |