Capability to integer casts on CheriBSD

Julien ÉLIE julien at trigofacile.com
Sun Oct 29 20:36:52 UTC 2023


Hi all,

I've just tried a build on CheriBSD, using Clang 13.
It is said to implement memory protection and software 
compartmentalization features enabled by CHERI-extended CPUs.

Interestingly, one of the test for checking the validity of a header 
field body in the test suite core dumps, because of an access to a char 
before the start of a string.
It is easily fixed, but what strikes me most is that the error had still 
not popped up on any other systems, nor was found by static analysers.

(I bet it would be interesting to run an INN instance for a while on 
CheriBSD to see it does not core dumps at other places.)


--- a/lib/headers.c
+++ b/lib/headers.c
@@ -47,6 +47,7 @@ bool
  IsValidHeaderBody(const char *p)
  {
      bool emptycontentline = true;
+    const char *start = p;

      /* Not NULL and not empty. */
      if (p == NULL || *p == '\0')
@@ -73,7 +74,7 @@ IsValidHeaderBody(const char *p)
               * re-initialize emptycontentline to true. */
              emptycontentline = true;
              continue;
-        } else if (p[-1] == '\r') {
+        } else if (p > start && p[-1] == '\r') {
              /* Case of CR not followed by LF (handled at the previous
               * if statement). */
              return false;




That said, the reason I am writing is for two Clang warnings I am unsure 
they are genuine errors to fix (and also how to fix them if they should).


In lib/mmap.c, with inn__msync_page(void *p, size_t length, int flags):

mmap.c:29:33: error: cast from capability type 'void *' to 
non-capability, non-address type 'size_t' (aka 'unsigned long') is most 
likely an error [-Werror,-Wcapability-to-integer-cast]
         char *start = (char *) ((size_t) p & mask);
                                 ^~~~~~~~~~
mmap.c:29:23: error: cast from provenance-free integer type to pointer 
type will give pointer that can not be dereferenced 
[-Werror,-Wcheri-capability-misuse]
         char *start = (char *) ((size_t) p & mask);
                       ^
mmap.c:30:32: error: cast from capability type 'void *' to 
non-capability, non-address type 'size_t' (aka 'unsigned long') is most 
likely an error [-Werror,-Wcapability-to-integer-cast]
         char *end = (char *) (((size_t) p + length + pagesize) & mask);
                                ^~~~~~~~~~
mmap.c:30:21: error: cast from provenance-free integer type to pointer 
type will give pointer that can not be dereferenced 
[-Werror,-Wcheri-capability-misuse]
         char *end = (char *) (((size_t) p + length + pagesize) & mask);
                     ^



Same thing for CNFS:

cnfs/cnfs.c:1007:23: error: cast from capability type 'void *' to 
non-capability, non-address type 'size_t' (aka 'unsigned long') is most 
likely an error [-Werror,-Wcapability-to-integer-cast]
     start = (char *) ((size_t) p & ~(size_t) (pagesize - 1));
                       ^~~~~~~~~~
cnfs/cnfs.c:1007:13: error: cast from provenance-free integer type to 
pointer type will give pointer that can not be dereferenced 
[-Werror,-Wcheri-capability-misuse]
     start = (char *) ((size_t) p & ~(size_t) (pagesize - 1));
             ^
cnfs/cnfs.c:1008:21: error: cast from capability type 'char *' to 
non-capability, non-address type 'size_t' (aka 'unsigned long') is most 
likely an error [-Werror,-Wcapability-to-integer-cast]
     end = (char *) ((size_t) ((char *) p + length + pagesize)
                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cnfs/cnfs.c:1008:11: error: cast from provenance-free integer type to 
pointer type will give pointer that can not be dereferenced 
[-Werror,-Wcheri-capability-misuse]
     end = (char *) ((size_t) ((char *) p + length + pagesize)
           ^


And a few other parts of the code, like this one:


icd.c:490:16: error: cast from capability type 'char *' to 
non-capability, non-address type 'unsigned long' is most likely an error 
[-Werror,-Wcapability-to-integer-cast]
         syslog(L_FATAL, "%s msync failed %s 0x%lx %d %m", LogName, 
ICDactpath,
                (unsigned long) ICDactpointer, ICDactsize);
                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Should something really be fixed, or may I just silent these warnings 
with -Wno-* because of false positives?

-- 
Julien ÉLIE

« Rien n'est plus agaçant que de ne pas se rappeler ce dont on ne
   parvient pas à se souvenir et rien n'est plus énervant que de se
   souvenir de ce qu'on voudrait parvenir à oublier. » (Pierre Dac)


More information about the inn-workers mailing list