News for hackers. Stuff that matters.
Re:Pointer Authentication by choeger on Sunday December 15, 2019 @02:53PM (#21798520)
Neat. But how do you make this modular and still safe? When the code invoking qsort() does not know about how many callbacks there are, can you still deal with it?
Re:Pointer Authentication by tedunangst on Sunday December 15, 2019 @04:54PM (#21799246)
The idea is you have some struct that is in peril. Perhaps it will be overflowed, or used after free, etc. It has a function pointer.

    struct danger {
        sort_fn sorter;
        char data[16];
    };
    danger->sorter(danger); /* what if it's a bad pointer? */
You replace that with this.

    int add_sort_fn(sort_fn sorter) {
        sort_fns[num_sorts++] = sorter;
        return num_sorts;
    }
    struct lessdanger {
        int sortidx;
        char data[16];
    };
    danger->sortidx = add_sort_fn(sorter);
    /* could clean this up a bit more */
    sort_fns[danger->sortidx % num_sorts](danger);
There's still the possibility of calling the wrong function, but only one from a finite set of possibilities. There's no direct control over the pointer value.

You can make the sort_fns array resizeable, but in practice there's usually only so many targets.

Re:Pointer Authentication by geocar on Sunday December 15, 2019 @06:02PM (#21799588)
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.
Re:Pointer Authentication by zozbot234 on Sunday December 15, 2019 @06:18PM (#21799662)
This 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.
Re:Pointer Authentication by yuubi on Sunday December 15, 2019 @10:41PM (#21800638)
Have 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.

Re:Pointer Authentication by geocar on Monday December 16, 2019 @12:04PM (#21804596)
gcc (ld actually) makes __start_sort_callbacks and __end_sort_callbacks for you, so you shouldn't need a custom linker script.