Send inn-workers mailing list submissions to
        [email protected]

To subscribe or unsubscribe via the World Wide Web, visit
        https://lists.isc.org/mailman/listinfo/inn-workers
or, via email, send a message with subject or body 'help' to
        [email protected]

You can reach the person managing the list at
        [email protected]

When replying, please edit your Subject line so it is more specific
than "Re: Contents of inn-workers digest..."


Today's Topics:

   1. Capability to integer casts on CheriBSD (Julien ?LIE)
   2. Re: Capability to integer casts on CheriBSD (Richard Kettlewell)


----------------------------------------------------------------------

Message: 1
Date: Sun, 29 Oct 2023 21:36:52 +0100
From: Julien ?LIE <[email protected]>
To: "[email protected]" <[email protected]>
Subject: Capability to integer casts on CheriBSD
Message-ID: <[email protected]>
Content-Type: text/plain; charset=UTF-8; format=flowed

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)


------------------------------

Message: 2
Date: Mon, 30 Oct 2023 09:49:49 +0000
From: Richard Kettlewell <[email protected]>
To: [email protected]
Subject: Re: Capability to integer casts on CheriBSD
Message-ID: <[email protected]>
Content-Type: text/plain; charset=UTF-8; format=flowed

On 29/10/2023 20:36, Julien ?LIE wrote:
> 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);
>  ??????????????????? ^

I don't know much about Cheri but AIUI pointers have extra metadata to 
enforce run-time bounds checking, so synthesizing pointers from integers 
like this does seem rather problematic - there's nowhere for the bound 
information to come from.

The idea of the code in question seems to be to convert region expressed 
by a pointer and length into the slightly wider region containing it 
consisting of whole pages.

An alternative approach that does not synthesize any pointers (but still 
relies on a pointer-to-integer conversion):

   size_t page_mask = pagesize - 1;

   // Offset of p from start of first page
   size_t start_offset = (size_t)p & page_mask;

   // Start of first page
   char *start = p - start_offset;

   // Offset of (p+length) from start of last page, or 0
   // if (p+length) is exactly on a page boundary
   size_t end_offset = (start_offset + length) & page_mask;

   // Offset _backwards_ of (p+length) from end of last page
   if(end_offset > 0)
     end_offset = page_mask - end_offset;

   // Total length of pages
   size_t total_length = start+offset + length + end_offset;

   return msync(start, total_length, flags);

Totally untested - the calculation should be out into a distinct 
function so it can be unit-tested properly.

> 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);
>  ?????????????? ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~

That one should be %p. It would already be broken on a platform with 
32-bit long but 64-bit (or longer) pointers.

ttfn/rjk


------------------------------

Subject: Digest Footer

_______________________________________________
inn-workers mailing list
[email protected]
https://lists.isc.org/mailman/listinfo/inn-workers


------------------------------

End of inn-workers Digest, Vol 154, Issue 2
*******************************************

Reply via email to