Split out of #249, which is now closed by PR #254. #249 fixed the primary hole — an unbounded, unsigned Content-Length driving a buffer allocation — and named three related items as explicitly out of scope. Those are recorded here so they are not lost inside a closed issue.
1. readFields accumulates headers without a cap. ksrpc-sockets/src/commonMain/kotlin/PacketUtils.kt:40-55 builds a LinkedHashMap with no limit on entry count, and calls readUTF8Line() without passing a length limit. A peer that never sends the blank terminator line grows the map indefinitely; a peer that sends one enormous line is bounded only by whatever readUTF8Line's default is, which is not stated at the call site.
2. Inbound binary chunks buffer through an unbounded channel. ksrpc-packets/src/commonMain/kotlin/PacketChannelBase.kt:520 uses Channel(Channel.UNLIMITED), so a peer that outruns the consumer is bounded only by heap. Unlike item 1 this is a legitimate design choice for throughput — the question is whether it should be configurable rather than unbounded.
3. maxSize reads like an inbound frame limit and is not one. PacketChannelBase.kt:55,70,245, default 16 KiB, governs outgoing chunking only. Every usage is on the send path. The name invites the assumption that inbound frames are bounded, which is exactly the assumption #249 disproved — worth either a rename or a KDoc line saying what it does not do.
None of these is the same severity as #249: that one let a single short header cost the host its heap before any content was read. These need a peer to sustain an attack, and 2 is arguably not a defect at all.
They are filed together because they share a cause — no inbound resource is bounded anywhere in the packet path — and because a fix for any of them wants the same decision made first: whether inbound limits belong in KsrpcEnvironment as configuration, which is a public API change, or as constants like MAX_CONTENT_LENGTH now is.
Split out of #249, which is now closed by PR #254. #249 fixed the primary hole — an unbounded, unsigned
Content-Lengthdriving a buffer allocation — and named three related items as explicitly out of scope. Those are recorded here so they are not lost inside a closed issue.1.
readFieldsaccumulates headers without a cap.ksrpc-sockets/src/commonMain/kotlin/PacketUtils.kt:40-55builds aLinkedHashMapwith no limit on entry count, and callsreadUTF8Line()without passing a length limit. A peer that never sends the blank terminator line grows the map indefinitely; a peer that sends one enormous line is bounded only by whateverreadUTF8Line's default is, which is not stated at the call site.2. Inbound binary chunks buffer through an unbounded channel.
ksrpc-packets/src/commonMain/kotlin/PacketChannelBase.kt:520usesChannel(Channel.UNLIMITED), so a peer that outruns the consumer is bounded only by heap. Unlike item 1 this is a legitimate design choice for throughput — the question is whether it should be configurable rather than unbounded.3.
maxSizereads like an inbound frame limit and is not one.PacketChannelBase.kt:55,70,245, default 16 KiB, governs outgoing chunking only. Every usage is on the send path. The name invites the assumption that inbound frames are bounded, which is exactly the assumption #249 disproved — worth either a rename or a KDoc line saying what it does not do.None of these is the same severity as #249: that one let a single short header cost the host its heap before any content was read. These need a peer to sustain an attack, and 2 is arguably not a defect at all.
They are filed together because they share a cause — no inbound resource is bounded anywhere in the packet path — and because a fix for any of them wants the same decision made first: whether inbound limits belong in
KsrpcEnvironmentas configuration, which is a public API change, or as constants likeMAX_CONTENT_LENGTHnow is.