Use bounded 16-bit profile lengths in join member records

This commit is contained in:
evgeny committed 2026-10-06 12:44:18 +02:00
1 parent 76c02012eb
commit c04f51d424
3 files changed
+17 -13

No files matched your search

+11 -7
View File
@@ -104,8 +104,11 @@ static void _keys_free_all(struct UTUN_INSTANCE* inst) {
int chat_join_serialize_member(const struct join_member_data* m,
uint8_t* out, size_t out_sz, size_t* out_len) {
if (!m || !out || !out_len || !m->x25519 || !m->ed25519) return -1;
size_t ul = strnlen(m->userinfo, 255);
size_t need = 8 + 32 + 32 + 64 + 8 + 64 + 8 + 1 + ul;
size_t ul = strnlen(m->userinfo, sizeof(m->userinfo));
if (ul > MS_USERINFO_MAX) {
DEBUG_WARN(DEBUG_CATEGORY_MEMBER_SYNC, "chat_join: profile exceeds limit bytes=%zu", ul); return -1;
}
size_t need = 8 + 32 + 32 + 64 + 8 + 64 + 8 + 2 + ul;
if (need > out_sz) return -1;
size_t off = 0;
memcpy(out + off, &m->node_id, 8); off += 8;
@@ -115,7 +118,7 @@ int chat_join_serialize_member(const struct join_member_data* m,
memcpy(out + off, &m->join_ts, 8); off += 8;
if (m->update_sig) memcpy(out + off, m->update_sig, 64); else memset(out + off, 0, 64); off += 64;
memcpy(out + off, &m->update_ts, 8); off += 8;
out[off++] = (uint8_t)ul;
out[off++] = (uint8_t)(ul >> 8); out[off++] = (uint8_t)ul;
if (ul) memcpy(out + off, m->userinfo, ul);
off += ul;
*out_len = off;
@@ -123,7 +126,7 @@ int chat_join_serialize_member(const struct join_member_data* m,
}
int chat_join_parse_member(const uint8_t* data, size_t len, struct join_member_data* m) {
if (!data || !m || len < 8 + 32 + 32 + 64 + 8 + 64 + 8 + 1) return -1;
if (!data || !m || len < 8 + 32 + 32 + 64 + 8 + 64 + 8 + 2) return -1;
memset(m, 0, sizeof(*m));
size_t off = 0;
memcpy(&m->node_id, data + off, 8); off += 8;
@@ -133,9 +136,10 @@ int chat_join_parse_member(const uint8_t* data, size_t len, struct join_member_d
memcpy(&m->join_ts, data + off, 8); off += 8;
m->update_sig = data + off; off += 64;
memcpy(&m->update_ts, data + off, 8); off += 8;
uint8_t ul = data[off++];
if (off + ul > len) return -1;
if (ul > 255) ul = 255;
size_t ul = ((size_t)data[off] << 8) | data[off + 1]; off += 2;
if (ul > MS_USERINFO_MAX || off + ul != len || memchr(data + off, 0, ul)) {
DEBUG_WARN(DEBUG_CATEGORY_MEMBER_SYNC, "chat_join: invalid profile length bytes=%zu payload=%zu", ul, len); return -1;
}
memcpy(m->userinfo, data + off, ul);
m->userinfo[ul] = '\0';
return 0;
+1 -1
View File
@@ -109,7 +109,7 @@ struct join_member_data {
uint64_t join_ts; /* время подписи вступления, Unix seconds */
const uint8_t* update_sig; /* 64, может быть NULL */
uint64_t update_ts; /* версия подписанного блока участника */
char userinfo[256]; /* JSON, null-terminated */
char userinfo[1025]; /* JSON до MS_USERINFO_MAX байт, null-terminated */
};
/* Сериализовать member-блок (без join_key). Возвращает 0 и *out_len, -1 если не влез. */