Since 23 July 2023 the cn_proc.h
linux header contains the following:
#define PROC_EVENT_ALL (PROC_EVENT_FORK | PROC_EVENT_EXEC | PROC_EVENT_UID | \
PROC_EVENT_GID | PROC_EVENT_SID | PROC_EVENT_PTRACE | \
PROC_EVENT_COMM | PROC_EVENT_NONZERO_EXIT | \
PROC_EVENT_COREDUMP | PROC_EVENT_EXIT)
/*
* If you add an entry in proc_cn_event, make sure you add it in
* PROC_EVENT_ALL above as well.
*/
enum proc_cn_event {
/* Use successive bits so the enums can be used to record
* sets of events as well
*/
PROC_EVENT_NONE = 0x00000000,
PROC_EVENT_FORK = 0x00000001,
PROC_EVENT_EXEC = 0x00000002,
PROC_EVENT_UID = 0x00000004,
PROC_EVENT_GID = 0x00000040,
PROC_EVENT_SID = 0x00000080,
PROC_EVENT_PTRACE = 0x00000100,
PROC_EVENT_COMM = 0x00000200,
/* "next" should be 0x00000400 */
/* "last" is the last process event: exit,
* while "next to last" is coredumping event
* before that is report only if process dies
* with non-zero exit status
*/
PROC_EVENT_NONZERO_EXIT = 0x20000000,
PROC_EVENT_COREDUMP = 0x40000000,
PROC_EVENT_EXIT = 0x80000000
};
/* [some unrelated code removed] */
static inline enum proc_cn_event valid_event(enum proc_cn_event ev_type)
{
ev_type &= PROC_EVENT_ALL;
return ev_type;
}
This means that if you’re compiling the following minimal breaking example on kernel 6.5.6:
#include <iostream>
#include <linux/cn_proc.h>
int main()
{
std::cout << "Hello World\n";
return 0;
}
Compilation fails with the following error:
/usr/include/linux/cn_proc.h: In function ‘proc_cn_event valid_event(proc_cn_event)’:
/usr/include/linux/cn_proc.h:72:17: error: invalid conversion from ‘unsigned int’ to ‘proc_cn_event’ [-fpermissive]
72 | ev_type &= PROC_EVENT_ALL;
| ^
| |
| unsigned int
It seems the |
-aggregate of enum proc_cn_event
values that is PROC_EVENT_ALL
is considered, in C++, as an unsigned int
and not an enum proc_cn_event
, nor an int
which seems to be the underlying type for enum proc_cn_event
.
(Tested on g++ 13.1 and clang++ 17.0)
Note that:
- The header compiles fine as C code
- Wrapping the include statement in
extern "C" { … }
does not fix this issue - Prepending a forward declaration
enum proc_cn_event : unsigned int;
to the include to force the underlying type to beunsigned int
fails with:/usr/include/linux/cn_proc.h:42:6: error: enumeration previously declared with fixed underlying type 42 | enum proc_cn_event { | ^ test.cpp:3:6: note: previous declaration is here 3 | enum proc_cn_event : unsigned int; | ^
I’m not sure whether I am doing this wrong and there is a proper way to include that header in C++ code, or whether I should not be trying to include it in C++ code at all (seems a bit drastic).
So how can I make this compile, without using -fpermissive
? Can I maybe add something to my C++ code to make this compile (maybe something implicitly converting unsigned int
to enum proc_cn_event
values?)