diff options
author | ulfvonbelow <strilen@tilde.club> | 2023-01-29 06:38:07 -0600 |
---|---|---|
committer | Martin Schanzenbach <schanzen@gnunet.org> | 2023-02-06 14:03:14 +0900 |
commit | eb1b1af264cfee84d2791bb68af9a8fd5d51b1f1 (patch) | |
tree | 9de77bbd79600ee622094134c10ffd622e123be1 | |
parent | 1e8b9a46709eb816c40360b4007a0a4b93eaa6f0 (diff) | |
download | gnunet-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.c | 17 |
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; |