aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorulfvonbelow <strilen@tilde.club>2023-01-29 06:38:07 -0600
committerMartin Schanzenbach <schanzen@gnunet.org>2023-02-06 14:03:14 +0900
commiteb1b1af264cfee84d2791bb68af9a8fd5d51b1f1 (patch)
tree9de77bbd79600ee622094134c10ffd622e123be1
parent1e8b9a46709eb816c40360b4007a0a4b93eaa6f0 (diff)
downloadgnunet-eb1b1af264cfee84d2791bb68af9a8fd5d51b1f1.tar.gz
gnunet-eb1b1af264cfee84d2791bb68af9a8fd5d51b1f1.zip
NAMESTORE: fix overread in handle_record_store.
A RecordStoreMessage looks like this: | header | key | recordset | A StoreActivity's rs field is supposed to point to the record set. handle_record_store tries to make a copy of this record set, but it does it by allocating enough memory for both key and recordset, then copying sizeof(key) + sizeof(recordset) bytes into it *starting from recordset*. This causes memcpy to read past the end of recordset by sizeof(key) bytes. There's still enough room in the allocated region for it, though, so it's only an overread. Signed-off-by: Martin Schanzenbach <schanzen@gnunet.org>
-rw-r--r--src/namestore/gnunet-service-namestore.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/src/namestore/gnunet-service-namestore.c b/src/namestore/gnunet-service-namestore.c
index d25287c9f..ed06b1dc5 100644
--- a/src/namestore/gnunet-service-namestore.c
+++ b/src/namestore/gnunet-service-namestore.c
@@ -1735,11 +1735,19 @@ handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
1735 ssize_t read; 1735 ssize_t read;
1736 size_t key_len; 1736 size_t key_len;
1737 size_t kb_read; 1737 size_t kb_read;
1738 size_t rp_msg_len;
1739 size_t rs_len;
1740 size_t rs_off;
1741 size_t body_len;
1738 struct StoreActivity *sa; 1742 struct StoreActivity *sa;
1739 struct RecordSet *rs; 1743 struct RecordSet *rs;
1740 enum GNUNET_ErrorCode res; 1744 enum GNUNET_ErrorCode res;
1741 1745
1742 key_len = ntohs (rp_msg->key_len); 1746 key_len = ntohs (rp_msg->key_len);
1747 rp_msg_len = ntohs (rp_msg->gns_header.header.size);
1748 body_len = rp_msg_len - sizeof (*rp_msg);
1749 rs_off = sizeof (*rp_msg) + key_len;
1750 rs_len = rp_msg_len - rs_off;
1743 if ((GNUNET_SYSERR == 1751 if ((GNUNET_SYSERR ==
1744 GNUNET_IDENTITY_read_private_key_from_buffer (&rp_msg[1], 1752 GNUNET_IDENTITY_read_private_key_from_buffer (&rp_msg[1],
1745 key_len, 1753 key_len,
@@ -1756,7 +1764,7 @@ handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
1756 "Received NAMESTORE_RECORD_STORE message\n"); 1764 "Received NAMESTORE_RECORD_STORE message\n");
1757 rid = ntohl (rp_msg->gns_header.r_id); 1765 rid = ntohl (rp_msg->gns_header.r_id);
1758 rd_set_count = ntohs (rp_msg->rd_set_count); 1766 rd_set_count = ntohs (rp_msg->rd_set_count);
1759 buf = (const char *) &rp_msg[1] + key_len; 1767 buf = (const char *) rp_msg + rs_off;
1760 for (int i = 0; i < rd_set_count; i++) 1768 for (int i = 0; i < rd_set_count; i++)
1761 { 1769 {
1762 rs = (struct RecordSet *) buf; 1770 rs = (struct RecordSet *) buf;
@@ -1770,15 +1778,12 @@ handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
1770 } 1778 }
1771 buf += read; 1779 buf += read;
1772 } 1780 }
1773 sa = GNUNET_malloc (sizeof(struct StoreActivity) 1781 sa = GNUNET_malloc (sizeof(struct StoreActivity) + rs_len);
1774 + ntohs (rp_msg->gns_header.header.size)
1775 - sizeof (*rp_msg));
1776 GNUNET_CONTAINER_DLL_insert (sa_head, sa_tail, sa); 1782 GNUNET_CONTAINER_DLL_insert (sa_head, sa_tail, sa);
1777 sa->nc = nc; 1783 sa->nc = nc;
1778 sa->rs = (struct RecordSet *) &sa[1]; 1784 sa->rs = (struct RecordSet *) &sa[1];
1779 sa->rd_set_count = rd_set_count; 1785 sa->rd_set_count = rd_set_count;
1780 GNUNET_memcpy (&sa[1], (char *) &rp_msg[1] + key_len, 1786 GNUNET_memcpy (&sa[1], (char *) rp_msg + rs_off, rs_len);
1781 ntohs (rp_msg->gns_header.header.size) - sizeof (*rp_msg));
1782 sa->rid = rid; 1787 sa->rid = rid;
1783 sa->rd_set_pos = 0; 1788 sa->rd_set_pos = 0;
1784 sa->private_key = zone; 1789 sa->private_key = zone;