Where there is no hardware support, the real world overhead is 35%+ (which this paper finds as well), and you end up with other issues to contend with (you have to de-tag the pointers in a bunch of cases, most kernels don't like them, etc), so software-only approaches have mostly not been bothered with.
I am not specifically familiar with the 35%+ numbers, but you should take into account the cost of any defense on top of the cost of putting tags in pointers, because that makes all the difference.
We found in our experiments on SPEC CPU2006 that, without static analysis for optimizations, the cost of pointer tagging itself (tagging + masking) is 22% geomean, which is almost entirely due to masking on loads/stores. This is with a 64-bit masking constant (0x80000000ffffffff) which is unique to our approach and is relatively inefficient on x86. With 32-bit masking (0xffffffff constant), which is more common, the number is about 14%.
This only covers metadata management and is not useful on its own, so you need to implement some kind of defense on top of this which is usually costly. The hardware support used by HWAsan only removes masking overhead by having the (ARM) hardware ignore the upper byte of the pointer, which is a nice way to not having to pay for masking.
By the way, source code for Delta Pointers is online since today!
This is confusing to me
Last sentence of second paragraph of your paper:
"We show that Delta Pointers are effective in detecting arbitrary
buffer overflows and, at 35% overhead on SPEC, offer much better
performance than competing solutions."
This only covers metadata management and is not useful on its own, so you need to implement some kind of defense on top of this which is usually costly. The hardware support used by HWAsan only removes masking overhead by having the (ARM) hardware ignore the upper byte of the pointer, which is a nice way to not having to pay for masking."
I'm aware :)
There are thoughts and plans here.
Where to put the tag is a problem for replacing pointers generically, but I think it's still pretty reasonable to use the 64-bit pointer version with just a minimum of language support. The trickiest buffers are often under 64K and we usually want to keep them small to live in cache, so if you have a "safe_alloc" function, all your IO loops, parsers, etc. that are dealing with user input could benefit from this.
"Tagging within existing sized pointers",
ARM does have some hardware support for (see http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc....)
It won't verify tags, but it has explicit support for ignoring bits, which is very helpful.
Or you can go with a GIL (but for compiled code) the way Python and early Ruby/JS implementations did, but that hasn't worked out terribly well for them either.
I'm aware of SPARC ADI :)
It does not have fatter-than-normal pointers, it uses 4 bit tagging of the memory address by reusing bits 63-60 of the pointer.
That is "tagging within existing pointers"
passing by the Xerox PARC machines, Lisp Machines and many others, including the ill fated iAPX 432.
If you could afford a Sparc M7, C on Solaris has been more type safe since version 11
The main issue is not if the CPU provide support, rather forcing the devs to actually bother to use them.
But since many want speed at any cost, it will only get there with a new generation, more open to trade performance for actually secure code.
> User-space pointers in Linux are 47 bits. We limit this to 32 bits to support 32-bit tags.