While performing a backport of apparmor 3 to kernel 3.4, I received the following error:
security/apparmor/lsm.c:1146:2: warning: initialization from incompatible pointer type
error, forbidden warning: lsm.c:1146
There was no more information. gcc didn't even print the erroneous line. The line in question was:
1136 static struct security_operations apparmor_ops = {
[...]
1146 .sb_mount = apparmor_sb_mount,
Which seemed fine.
To investigate this, check the definition of struct security_operations
(in this kernel, it was in include/linux/security.h
). Specifically, find the sb_mount
member definition:
int (*sb_mount) (const char *dev_name, struct path *path,
const char *type, unsigned long flags, void *data);
I compared that against the apparmor_sb_mount
function signature:
static int apparmor_sb_mount(char *dev_name, struct path *path,
char *type, unsigned long flags, void *data)
The char *
arguments aren't const
! This means the function has a different signature, and is not compatible with the security_operations
struct definition. The Linux kernel has a light OO programming model where functions are assigned as members of structs. These structs serve as interfaces: a struct security_operations apparmor_ops
and a struct security_operations selinux_ops
can be used interchangeably, of course enabling the respective functionality. This can lead to some interesting compile errors. Changing the function signature as such fixed the issue:
static int apparmor_sb_mount(const char *dev_name, struct path *path,
const char *type, unsigned long flags, void *data)