CTSRD-CHERI / clang

DO NOT USE. Use llvm-project instead
Other
9 stars 8 forks source link

taking a reference to an array element via a capability pointer does not produce a capability #185

Closed brooksdavis closed 6 years ago

brooksdavis commented 6 years ago

This code:

struct as {
        char name[10];
};
void
afunc(struct as * __capability asc)
{
        char * __capability namep = &asc->name[0];
}

produces:

$ clang -target cheri-unknown-freebsd -march=mips4 -mabi=64 -mcpu=mips4 -cheri=128 -c -o /dev/null foo.c  
foo.c:7:30: error: converting non-capability type 'char *' to capability type
      'char * __capability' without an explicit cast; if this is intended use
      __cheri_tocap
        char * __capability namep = &asc->name[0];
                                    ^
                                    (__cheri_tocap char * __capability)
1 error generated.

Removing the [0] avoids the error, but both should do the same thing.

brooksdavis commented 6 years ago

This seems to be a variant on #180

brooksdavis commented 6 years ago

Likewise &ujob->_aiocb_private.error when ujob is a capability looses capabilityness.

arichardson commented 6 years ago

The current fix only looks up one level so it looks at as::name which is a pointer in the hybrid ABI and therefore concludes that the result should be a pointer and not a capability. Same issue for &ujob->_aiocb_private.error

brooksdavis commented 6 years ago

It's worth noting the we need to do this to arbitrary depth. The compiler is wrong in thinking that it can turn an arbitrary capability into a pointer as there's no assurance a virtual address accessible via a capability is accessible via dcc. There is in-fact no assurance that the virtual address has any meaning at all relative to ddc in the general case of capability systems. That just happens to be true in our current implementation. (An implementation where each ring had its own capability type and shared the same virtual address space range would be interesting.)