Skip to content

Commit

Permalink
policy,tests: add tests for netlink xperms
Browse files Browse the repository at this point in the history
Add tests for netlink xperms. Test program is based on an earlier test
program for netlink_send checking by Paul Moore. Exercising these
tests depends on the corresponding kernel patch, userspace patches,
and updating the base policy to define the new nlmsg permissions
and to enable the new netlink_xperm policy capability.

For testing purposes, you can update the base policy by manually
modifying your base module and tweaking /usr/share/selinux/devel
(latter only required due to writing the test policy as a .te file
rather than as .cil in order to use the test macros) as follows:
    sudo semodule -c -E base
    sudo sed -i.orig "s/nlmsg_read/nlmsg nlmsg_read/" base.cil
    sudo semodule -i base.cil
    echo "(policycap netlink_xperm)" > netlink_xperm.cil
    sudo semodule -i netlink_xperm.cil
    sudo sed -i.orig "s/nlmsg_read/nlmsg nlmsg_read/" \
        /usr/share/selinux/devel/include/support/all_perms.spt

When finished testing, you can semodule -r base netlink_xperm to
undo the two module changes and restore your all_perms.spt file
from the saved .orig file.

NB The above may lead to unexpected denials of the new nlmsg permission
for existing domains on your system and prevent new ssh sessions from
being created. Recommend only inserting the netlink_xperm.cil module
just prior to running the testsuite and removing immediately thereafter.

Signed-off-by: Stephen Smalley <[email protected]>
Tested-by: Thiébaud Weksteen <[email protected]>
Signed-off-by: Ondrej Mosnacek <[email protected]>
  • Loading branch information
stephensmalley authored and WOnder93 committed Oct 9, 2024
1 parent f71a462 commit 023b79b
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 0 deletions.
5 changes: 5 additions & 0 deletions policy/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,11 @@ TARGETS += test_userfaultfd.te
endif
endif

# nlmsg test dependencies: policy >= 30, nlmsg permission, netlink_xperm capability
ifeq ($(shell [ $(MOD_POL_VERS) -ge 18 -a $(MAX_KERNEL_POLICY) -ge 30 ] && [ -f /sys/fs/selinux/class/netlink_route_socket/perms/nlmsg ] && grep -q 1 $(SELINUXFS)/policy_capabilities/netlink_xperm && echo true),true)
TARGETS += test_nlmsg.te
endif

ifeq (x$(DISTRO),$(filter x$(DISTRO),xRHEL4 xRHEL5 xRHEL6))
TARGETS:=$(filter-out test_overlayfs.te test_mqueue.te test_ibpkey.te, $(TARGETS))
endif
Expand Down
34 changes: 34 additions & 0 deletions policy/test_nlmsg.te
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
########################################
#
# Policy for testing the nlmsg extended permissions.

define(`RTM_GETLINK', `18')
define(`RTM_SETLINK', `19')
define(`RTM_GETADDR', `22')

attribute nlmsgtestdomain;

# Domain that is allowed the nlmsg extended permissions.
type test_nlmsg_xperm_t;
typeattribute test_nlmsg_xperm_t nlmsgtestdomain;
testsuite_domain_type(test_nlmsg_xperm_t)
allow test_nlmsg_xperm_t self:netlink_route_socket create_socket_perms;
# Also allow the legacy nlmsg_read/write permissions to ensure no false positives.
allow test_nlmsg_xperm_t self:netlink_route_socket { nlmsg nlmsg_read nlmsg_write };
allowxperm test_nlmsg_xperm_t self:netlink_route_socket nlmsg { RTM_GETLINK RTM_SETLINK RTM_GETADDR };

# Domain that is not allowed the nlmsg extended permissions.
type test_nlmsg_noxperm_t;
typeattribute test_nlmsg_noxperm_t nlmsgtestdomain;
testsuite_domain_type(test_nlmsg_noxperm_t)
allow test_nlmsg_noxperm_t self:netlink_route_socket create_socket_perms;
# Also allow the legacy nlmsg_read/write permissions to ensure no false positives.
allow test_nlmsg_noxperm_t self:netlink_route_socket { nlmsg nlmsg_read nlmsg_write };
allowxperm test_nlmsg_noxperm_t self:netlink_route_socket nlmsg ~{ RTM_GETLINK RTM_SETLINK RTM_GETADDR };

#
# Common rules for all nlmsg test domains.
#

# Trigger kernel module auto-loading of the protocol implementations.
kernel_request_load_module(nlmsgtestdomain)
5 changes: 5 additions & 0 deletions tests/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,11 @@ ifneq ($(shell ./kvercmp $$(uname -r) 6.5),-1)
SUBDIRS += inet_socket/mptcp
endif

# nlmsg test dependencies: policy >= 30, nlmsg permission, netlink_xperm capability
ifeq ($(shell [ $(MOD_POL_VERS) -ge 18 -a $(MAX_KERNEL_POLICY) -ge 30 ] && [ -f /sys/fs/selinux/class/netlink_route_socket/perms/nlmsg ] && grep -q 1 $(SELINUXFS)/policy_capabilities/netlink_xperm && echo true),true)
SUBDIRS += nlmsg
endif

ifeq ($(DISTRO),RHEL4)
SUBDIRS:=$(filter-out bounds dyntrace dyntrans inet_socket mmap nnp_nosuid overlay unix_socket, $(SUBDIRS))
endif
Expand Down
1 change: 1 addition & 0 deletions tests/nlmsg/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nlmsg
5 changes: 5 additions & 0 deletions tests/nlmsg/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
TARGETS=nlmsg

all: $(TARGETS)
clean:
rm -f $(TARGETS)
50 changes: 50 additions & 0 deletions tests/nlmsg/nlmsg.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <asm/types.h>
#include <sys/socket.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>

int main(int argc, char *argv[])
{
int i, rc;
int fd;
unsigned char data[512];
struct nlmsghdr *nh[3];
struct sockaddr_nl sa;
struct iovec iov;
struct msghdr msg;

memset(&sa, 0, sizeof(sa));
sa.nl_family = AF_NETLINK;

memset(data, 0, sizeof(data));
iov.iov_base = data;
iov.iov_len = 3 * NLMSG_SPACE(0);

for (i = 0; i < 3; i++) {
nh[i] = (struct nlmsghdr *)(data + (i * NLMSG_SPACE(0)));
nh[i]->nlmsg_len = NLMSG_HDRLEN;
}
nh[0]->nlmsg_type = RTM_GETLINK; // nlmsg_read
nh[1]->nlmsg_type = RTM_SETLINK; // nlmsg_write
nh[2]->nlmsg_type = RTM_GETADDR; // nlmsg_read

memset(&msg, 0, sizeof(msg));
msg.msg_name = &sa;
msg.msg_namelen = sizeof(sa);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;

fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
rc = sendmsg(fd, &msg, 0);

if (rc < 0) {
perror("sendmsg");
exit(-1);
}
exit(0);
}

28 changes: 28 additions & 0 deletions tests/nlmsg/test
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/perl
#
# This test exercises the netlink extended perms support
#

use Test;

BEGIN {
$test_count = 2;
plan tests => $test_count;
}

$basedir = $0;
$basedir =~ s|(.*)/[^/]*|$1|;

#
# Attempt to send the netlink messages from the allowed domain.
#
$result = system "runcon -t test_nlmsg_xperm_t -- $basedir/nlmsg 2>&1";
ok( $result, 0 );

#
# Attempt to send the netlink messages from the not-allowed domain.
#
$result = system "runcon -t test_nlmsg_noxperm_t -- $basedir/nlmsg 2>&1";
ok($result);

exit;

0 comments on commit 023b79b

Please sign in to comment.