aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-05-15 14:24:41 +0000
committerChristian Grothoff <christian@grothoff.org>2012-05-15 14:24:41 +0000
commit3b30625dd217ffb650584df0f00fe1cbb73e2619 (patch)
treebedf45cfbe9f168297484dde614c0b351575c794
parentf536ece4ac20ca0b6bb3cb4aa7e075125c322d69 (diff)
downloadgnunet-3b30625dd217ffb650584df0f00fe1cbb73e2619.tar.gz
gnunet-3b30625dd217ffb650584df0f00fe1cbb73e2619.zip
-adding checks to avoid #2352 segfault
-rw-r--r--src/fs/fs_download.c87
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 }