demikernel icon indicating copy to clipboard operation
demikernel copied to clipboard

[inetstack] The Ephemeral Port Allocator Wastes Memory and is Predictable

Open BrianZill opened this issue 3 years ago • 1 comments

Description

First the good: catnip's Ephemeral Port allocator uses the correct (RFC 6335 designated) range. And it allocates them in a random fashion (recommended to thwart certain types of attacks).

The bad is that the mechanism it uses to provide the randomization is to put every possible ephemeral port number into a Vec, and then randomly shuffle them. It keeps this Vec around for the life of the system, in order to preserve the random ordering. Since there are 16,384 ephemeral ports, and each consumes 2 bytes, this Vec uses a minimum of 32 KiB of memory, which seems quite wasteful. I suppose that alloc/free can be made quite fast with this scheme, however. alloc() is a simple pop, and free() a simple push.

Another problem is that the whole goal of the randomization is to make it hard for an attacker to guess what the next allocated port number will be. But by using a Vec<> (which is used as a stack), the most recently freed port number will be the next allocated port number. Ideally, one should use a Deque<> and pop from the front of the double-ended queue, and push onto the rear. That would keep the next allocated port number unpredictable.

Finally, this method of allocating ephemeral port numbers doesn't take into account that a user could themselves pick an ephemeral port number and bind it to a socket, making that port number "in use". This allocator could then also "allocate" the same port number as this allocator assumes it is the only one handing out ephemeral ports. There needs to be a registry somewhere of which ports are "in use" to avoid this (see related Issue demikernel/demikernel#190).

BrianZill avatar Feb 17 '22 02:02 BrianZill