5 ms·
Our qsort() caller is an application with at most 256 different comparators. Let us call that an ABI limit. The addresses are in read-only memory so they cannot
by geocar 7y ago
Our qsort() caller is an application with at most 256 different comparators. Let us call that an ABI limit. The addresses are in read-only memory so they cannot be changed- new addresses simply cannot be introduced at run-time, so there is no risk of qsort being tricked into “jumping into the middle of a function”. The implementation of my qsort() does not need to know if there are fewer- the entry will be null and the program will crash.
- zozbot234 7y agoThis is a whole-program transformation though, it doesn't seem to be possible to make it modular. Unless you manage to map some module-specific dispatch table whenever you're running code from that module - in a way that cannot easily be subverted by exploit code! Not sure how to do this however.
- yuubi 7y agoHave a section of callback pointers and check against the bounds of the section? G++ uses this mechanism for static constructors, but it's general purpose (Linux uses it to collect lists of drivers to initialize, for instance, with macros like IRQCHIP_DECLARE that populate a section for each type of entity, which then gets scanned at boot time). You would need a linker script to collect the callbacks into a section and provide a symbol for the end, and define variables something like int (my_sort_callback_ptr)(void , void *) __attribute__((section, "sort_callbacks"))=my_sort_comparator; You would, of course, use a macro for that.
- geocar 7y agogcc (ld actually) makes __start_sort_callbacks and __end_sort_callbacks for you, so you shouldn't need a custom linker script.