jvoisin/fortify-headers

Fix missing includes

Closed this issue · 10 comments

As reported by @q66 on irc:

/usr/include/fortify/poll.h:39:2: error: use of undeclared identifier 'size_t'; did you mean 'sizeof'?
   39 |         size_t __b = __bos(__f, 0);
      |         ^
/usr/include/fortify/poll.h:39:13: error: expression is not assignable
   39 |         size_t __b = __bos(__f, 0);
      |         ~~~~~~~~~~ ^
/usr/include/fortify/poll.h:39:9: error: use of undeclared identifier '__b'
   39 |         size_t __b = __bos(__f, 0);
      |                ^
/usr/include/fortify/poll.h:41:12: error: use of undeclared identifier '__b'
   41 |         if (__n > __b / sizeof(struct pollfd))
      |                   ^
/usr/include/fortify/poll.h:54:2: error: use of undeclared identifier 'size_t'; did you mean 'sizeof'?
   54 |         size_t __b = __bos(__f, 0);
      |         ^
/usr/include/fortify/poll.h:54:13: error: expression is not assignable
   54 |         size_t __b = __bos(__f, 0);
      |         ~~~~~~~~~~ ^
/usr/include/fortify/poll.h:54:9: error: use of undeclared identifier '__b'
   54 |         size_t __b = __bos(__f, 0);
      |                ^
/usr/include/fortify/poll.h:56:12: error: use of undeclared identifier '__b'; did you mean '__n'?
   56 |         if (__n > __b / sizeof(struct pollfd))
      |                   ^
/usr/include/fortify/poll.h:51:72: note: '__n' declared here
   51 | _FORTIFY_FN(ppoll) int ppoll(struct pollfd * _FORTIFY_POS0 __f, nfds_t __n,
q66 commented

this is not a missing include, this is using types you're not allowed to use

please do not add random extra includes, fortify is not supposed to mess with that

q66 commented

that said you do have a missing include in select.h:

/usr/include/fortify/sys/select.h:34:60: error: expected ')'
   34 | _STI void __fortify_FD_CLR(int __f, fd_set * _FORTIFY_POS0 __s)
      |                                                            ^
/usr/include/fortify/sys/select.h:34:27: note: to match this '('
   34 | _STI void __fortify_FD_CLR(int __f, fd_set * _FORTIFY_POS0 __s)
      |                           ^
/usr/include/fortify/sys/select.h:36:21: error: use of undeclared identifier '__s'; did you mean '__f'?
   36 |         size_t __b = __bos(__s, 0);
      |                            ^
/usr/include/fortify/sys/select.h:34:32: note: '__f' declared here
   34 | _STI void __fortify_FD_CLR(int __f, fd_set * _FORTIFY_POS0 __s)
      |                                ^
/usr/include/fortify/sys/select.h:40:14: error: use of undeclared identifier '__s'
   40 |         FD_CLR(__f, __s);
      |                     ^
/usr/include/fortify/sys/select.h:43:60: error: expected ')'
   43 | _STI void __fortify_FD_SET(int __f, fd_set * _FORTIFY_POS0 __s)
      |                                                            ^
/usr/include/fortify/sys/select.h:43:27: note: to match this '('
   43 | _STI void __fortify_FD_SET(int __f, fd_set * _FORTIFY_POS0 __s)
      |                           ^
/usr/include/fortify/sys/select.h:45:21: error: use of undeclared identifier '__s'; did you mean '__f'?
   45 |         size_t __b = __bos(__s, 0);
      |                            ^
/usr/include/fortify/sys/select.h:43:32: note: '__f' declared here
   43 | _STI void __fortify_FD_SET(int __f, fd_set * _FORTIFY_POS0 __s)
      |                                ^
/usr/include/fortify/sys/select.h:49:14: error: use of undeclared identifier '__s'
   49 |         FD_SET(__f, __s);
      |                     ^
/usr/include/fortify/sys/select.h:52:61: error: expected ')'
   52 | _STI int __fortify_FD_ISSET(int __f, fd_set * _FORTIFY_POS0 __s)
      |                                                             ^
/usr/include/fortify/sys/select.h:52:28: note: to match this '('
   52 | _STI int __fortify_FD_ISSET(int __f, fd_set * _FORTIFY_POS0 __s)
      |                            ^
/usr/include/fortify/sys/select.h:54:21: error: use of undeclared identifier '__s'; did you mean '__f'?
   54 |         size_t __b = __bos(__s, 0);
      |                            ^
/usr/include/fortify/sys/select.h:52:33: note: '__f' declared here
   52 | _STI int __fortify_FD_ISSET(int __f, fd_set * _FORTIFY_POS0 __s)
      |                                 ^
/usr/include/fortify/sys/select.h:58:23: error: use of undeclared identifier '__s'
   58 |         return FD_ISSET(__f, __s);
      |                              ^
9 errors generated.

additionally, feature test macros are not being respected:

/usr/include/fortify/stdio.h:46:13: error: use of undeclared identifier 'fdopen'; did you mean 'fopen'?
   46 | _FORTIFY_FN(fdopen) FILE *fdopen(int __f, const char* _FORTIFY_POS0 __m)
      |             ^
/usr/include/stdio.h:70:7: note: 'fopen' declared here
   70 | FILE *fopen(const char *__restrict, const char *__restrict);
      |       ^
In file included from ../src.freebsd/sh/mknodes.c:52:
/usr/include/fortify/stdio.h:68:13: error: use of undeclared identifier 'fmemopen'; did you mean 'freopen'?
   68 | _FORTIFY_FN(fmemopen) FILE *fmemopen(void* _FORTIFY_POS0 __b, size_t __s, const char* _FORTIFY_POS0 __m)
      |             ^
/usr/include/stdio.h:71:7: note: 'freopen' declared here
   71 | FILE *freopen(const char *__restrict, const char *__restrict, FILE *__restrict);
      |       ^
In file included from ../src.freebsd/sh/mknodes.c:52:
/usr/include/fortify/stdio.h:122:13: error: use of undeclared identifier 'popen'; did you mean 'fopen'?
  122 | _FORTIFY_FN(popen) FILE *popen(const char* _FORTIFY_POS0 __c, const char* _FORTIFY_POS0 __t)
      |             ^
/usr/include/fortify/stdio.h:79:26: note: 'fopen' declared here
   79 | _FORTIFY_FN(fopen) FILE *fopen(const char* _FORTIFY_POS0 __p, const char* _FORTIFY_POS0 __m)
      |                          ^
3 errors generated.
ninja: build stopped: subcommand failed.

this is not a missing include, this is using types you're not allowed to use

please do not add random extra includes, fortify is not supposed to mess with that

Yet I do need size_t, which isn't available without an include.

There are already some includes in fortify-header:

$ grep include ./include/wchar.h 
#include_next <limits.h>
#include_next <stdlib.h>
#include_next <string.h>
#include_next <wchar.h>
#include "fortify-headers.h"
$
q66 commented

then those are also wrong and should be fixed

q66 commented

having additional includes imposed by fortify means that programs that don't correctly include everything they should will compile without errors, even though they should error

I'm not sure I follow: headers are allowed to include others, eg.

$ grep '^#include' /usr/include/stdio.h | grep -v bits
#include <stddef.h>
#include <stdarg.h>
$
q66 commented

that's not the point (musl does not do this by the way), the point is that fortify should not relax include file strictness over unfortified code

$ cd musl/
$ git gr '^#include' ./include/*.h | grep -v bits -c
84
$

musl does this.

Anyway, the problem here is that I do need size_t, and I really don't want to define it manually in a portable way. Do you have a better idea/recommendations?

q66 commented

pretty much all of these are includes like features.h or internal includes from bits/, in general musl does not include other stdlib headers when it can help it

q66 commented

what about using an extension such as __typeof__ in place of the types? the way fortify is implemented pretty much already assumes gcc/clang