3 ms·
It's true, there's no way of getting around it. There are four requirements here: 1. Stable ABI 2. A library that can change the size of its opaque struct 3.
by OskarS 7y ago
It's true, there's no way of getting around it. There are four requirements here:
1. Stable ABI
2. A library that can change the size of its opaque struct
3. Stack allocation of the opaque struct
4. Statically sized stack frames (i.e. no VLAs or alloca)
Pick (any) three of them. You can't have all four.
- kazinator 7y agoThe value passed to alloca, in this case, will be a reasonably small, bounded integer that can reasonably be expected not to be controllable by a remote attacker when the application is running. (Or so it has to be painstakingly ensured.) An alternative would be to use padded structs: when the struct is newly introduced, make it substantially larger than necessary. Then all the clients are reserving the room already. A transparent (or not) union between the real struct type and some array can be used, or padding members. Additional requirements may be that the unused stuff must be initialized to zero by everyone, or else some version field has to be initialized or whatever. Versioned symbols are another solution. Binary clients that are allocating the smaller, older structure are routed to compatibility functions, at least for those functions where it matters. This approach is seen inside glibc for instance. An approach found in numerous places in Microsoft's WIN32 is to store the structure's size, as known at compile time to the given client, into a dedicated size field. The API then knows it is called by older compiled clients when the size they are passing is smaller than the current sizeof (that_struct).