diff mbox series

[testsuite] policy,tests: add tests for netlink xperms

Message ID 20240828195755.19385-1-stephen.smalley.work@gmail.com (mailing list archive)
State Accepted
Delegated to: Ondrej Mosnáček
Headers show
Series [testsuite] policy,tests: add tests for netlink xperms | expand

Commit Message

Stephen Smalley Aug. 28, 2024, 7:57 p.m. UTC
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 <stephen.smalley.work@gmail.com>
---
 policy/Makefile        |  5 +++++
 policy/test_nlmsg.te   | 34 ++++++++++++++++++++++++++++
 tests/Makefile         |  5 +++++
 tests/nlmsg/.gitignore |  1 +
 tests/nlmsg/Makefile   |  5 +++++
 tests/nlmsg/nlmsg.c    | 50 ++++++++++++++++++++++++++++++++++++++++++
 tests/nlmsg/test       | 28 +++++++++++++++++++++++
 7 files changed, 128 insertions(+)
 create mode 100644 policy/test_nlmsg.te
 create mode 100644 tests/nlmsg/.gitignore
 create mode 100644 tests/nlmsg/Makefile
 create mode 100644 tests/nlmsg/nlmsg.c
 create mode 100755 tests/nlmsg/test

Comments

Thiébaud Weksteen Aug. 30, 2024, 6:45 a.m. UTC | #1
On Thu, Aug 29, 2024 at 6:00 AM Stephen Smalley
<stephen.smalley.work@gmail.com> wrote:
>
> 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 <stephen.smalley.work@gmail.com>

Thank you Stephen. I was able to reproduce on Fedora rawhide,
following your instructions.

Tested-by: Thiébaud Weksteen <tweek@google.com>
Stephen Smalley Sept. 16, 2024, 1:04 p.m. UTC | #2
On Wed, Aug 28, 2024 at 4:00 PM Stephen Smalley
<stephen.smalley.work@gmail.com> wrote:
>
> 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 <stephen.smalley.work@gmail.com>

Now that the kernel and userspace patches have been accepted, can we
get this testsuite patch merged please? The test will only be enabled
when the underlying policy defines the new nlmsg permission and
enables the new netlink_xperm policy capability, so it won't break
anything in the interim. We will need to separately submit a patch for
refpolicy and/or Fedora policy to add these.



> ---
>  policy/Makefile        |  5 +++++
>  policy/test_nlmsg.te   | 34 ++++++++++++++++++++++++++++
>  tests/Makefile         |  5 +++++
>  tests/nlmsg/.gitignore |  1 +
>  tests/nlmsg/Makefile   |  5 +++++
>  tests/nlmsg/nlmsg.c    | 50 ++++++++++++++++++++++++++++++++++++++++++
>  tests/nlmsg/test       | 28 +++++++++++++++++++++++
>  7 files changed, 128 insertions(+)
>  create mode 100644 policy/test_nlmsg.te
>  create mode 100644 tests/nlmsg/.gitignore
>  create mode 100644 tests/nlmsg/Makefile
>  create mode 100644 tests/nlmsg/nlmsg.c
>  create mode 100755 tests/nlmsg/test
>
> diff --git a/policy/Makefile b/policy/Makefile
> index f18e15d..32d7ede 100644
> --- a/policy/Makefile
> +++ b/policy/Makefile
> @@ -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
> diff --git a/policy/test_nlmsg.te b/policy/test_nlmsg.te
> new file mode 100644
> index 0000000..9e1e2a4
> --- /dev/null
> +++ b/policy/test_nlmsg.te
> @@ -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)
> diff --git a/tests/Makefile b/tests/Makefile
> index db4cb38..35bb358 100644
> --- a/tests/Makefile
> +++ b/tests/Makefile
> @@ -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
> diff --git a/tests/nlmsg/.gitignore b/tests/nlmsg/.gitignore
> new file mode 100644
> index 0000000..d4bea66
> --- /dev/null
> +++ b/tests/nlmsg/.gitignore
> @@ -0,0 +1 @@
> +nlmsg
> diff --git a/tests/nlmsg/Makefile b/tests/nlmsg/Makefile
> new file mode 100644
> index 0000000..1edab98
> --- /dev/null
> +++ b/tests/nlmsg/Makefile
> @@ -0,0 +1,5 @@
> +TARGETS=nlmsg
> +
> +all: $(TARGETS)
> +clean:
> +       rm -f $(TARGETS)
> diff --git a/tests/nlmsg/nlmsg.c b/tests/nlmsg/nlmsg.c
> new file mode 100644
> index 0000000..a976b95
> --- /dev/null
> +++ b/tests/nlmsg/nlmsg.c
> @@ -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);
> +}
> +
> diff --git a/tests/nlmsg/test b/tests/nlmsg/test
> new file mode 100755
> index 0000000..18bb794
> --- /dev/null
> +++ b/tests/nlmsg/test
> @@ -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;
> --
> 2.40.1
>
Stephen Smalley Oct. 8, 2024, 1:01 p.m. UTC | #3
On Mon, Sep 16, 2024 at 9:04 AM Stephen Smalley
<stephen.smalley.work@gmail.com> wrote:
>
> On Wed, Aug 28, 2024 at 4:00 PM Stephen Smalley
> <stephen.smalley.work@gmail.com> wrote:
> >
> > 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 <stephen.smalley.work@gmail.com>
>
> Now that the kernel and userspace patches have been accepted, can we
> get this testsuite patch merged please? The test will only be enabled
> when the underlying policy defines the new nlmsg permission and
> enables the new netlink_xperm policy capability, so it won't break
> anything in the interim. We will need to separately submit a patch for
> refpolicy and/or Fedora policy to add these.

Any objections to merging these tests now that the corresponding
kernel support is merged?
They will only run if the underlying base policy defines the new nlmsg
permissions and enables the new netlink_xperm policy capability so
nothing should break in the interim.
Paul Moore Oct. 8, 2024, 1:40 p.m. UTC | #4
On Tue, Oct 8, 2024 at 9:02 AM Stephen Smalley
<stephen.smalley.work@gmail.com> wrote:
> On Mon, Sep 16, 2024 at 9:04 AM Stephen Smalley
> <stephen.smalley.work@gmail.com> wrote:
> >
> > On Wed, Aug 28, 2024 at 4:00 PM Stephen Smalley
> > <stephen.smalley.work@gmail.com> wrote:
> > >
> > > 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 <stephen.smalley.work@gmail.com>
> >
> > Now that the kernel and userspace patches have been accepted, can we
> > get this testsuite patch merged please? The test will only be enabled
> > when the underlying policy defines the new nlmsg permission and
> > enables the new netlink_xperm policy capability, so it won't break
> > anything in the interim. We will need to separately submit a patch for
> > refpolicy and/or Fedora policy to add these.
>
> Any objections to merging these tests now that the corresponding
> kernel support is merged?

Not from me, although since the kernel support was merged less than 24
hours ago I might give Ondrej another day or two just in case he was
waiting on that.  If we still haven't heard from Ondrej towards the
end of the week I think it's fair game to merge, I would have thought
if he had any concerns he would have voiced them by now.

> They will only run if the underlying base policy defines the new nlmsg
> permissions and enables the new netlink_xperm policy capability so
> nothing should break in the interim.
Ondrej Mosnacek Oct. 9, 2024, 8:25 a.m. UTC | #5
On Tue, Oct 8, 2024 at 3:41 PM Paul Moore <paul@paul-moore.com> wrote:
>
> On Tue, Oct 8, 2024 at 9:02 AM Stephen Smalley
> <stephen.smalley.work@gmail.com> wrote:
> > On Mon, Sep 16, 2024 at 9:04 AM Stephen Smalley
> > <stephen.smalley.work@gmail.com> wrote:
> > >
> > > On Wed, Aug 28, 2024 at 4:00 PM Stephen Smalley
> > > <stephen.smalley.work@gmail.com> wrote:
> > > >
> > > > 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 <stephen.smalley.work@gmail.com>
> > >
> > > Now that the kernel and userspace patches have been accepted, can we
> > > get this testsuite patch merged please? The test will only be enabled
> > > when the underlying policy defines the new nlmsg permission and
> > > enables the new netlink_xperm policy capability, so it won't break
> > > anything in the interim. We will need to separately submit a patch for
> > > refpolicy and/or Fedora policy to add these.
> >
> > Any objections to merging these tests now that the corresponding
> > kernel support is merged?
>
> Not from me, although since the kernel support was merged less than 24
> hours ago I might give Ondrej another day or two just in case he was
> waiting on that.  If we still haven't heard from Ondrej towards the
> end of the week I think it's fair game to merge, I would have thought
> if he had any concerns he would have voiced them by now.

It is now applied:
https://github.com/SELinuxProject/selinux-testsuite/commit/023b79b8319e5fe222fb5af892c579593e1cbc50
diff mbox series

Patch

diff --git a/policy/Makefile b/policy/Makefile
index f18e15d..32d7ede 100644
--- a/policy/Makefile
+++ b/policy/Makefile
@@ -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
diff --git a/policy/test_nlmsg.te b/policy/test_nlmsg.te
new file mode 100644
index 0000000..9e1e2a4
--- /dev/null
+++ b/policy/test_nlmsg.te
@@ -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)
diff --git a/tests/Makefile b/tests/Makefile
index db4cb38..35bb358 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -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
diff --git a/tests/nlmsg/.gitignore b/tests/nlmsg/.gitignore
new file mode 100644
index 0000000..d4bea66
--- /dev/null
+++ b/tests/nlmsg/.gitignore
@@ -0,0 +1 @@ 
+nlmsg
diff --git a/tests/nlmsg/Makefile b/tests/nlmsg/Makefile
new file mode 100644
index 0000000..1edab98
--- /dev/null
+++ b/tests/nlmsg/Makefile
@@ -0,0 +1,5 @@ 
+TARGETS=nlmsg
+
+all: $(TARGETS)
+clean:
+	rm -f $(TARGETS)
diff --git a/tests/nlmsg/nlmsg.c b/tests/nlmsg/nlmsg.c
new file mode 100644
index 0000000..a976b95
--- /dev/null
+++ b/tests/nlmsg/nlmsg.c
@@ -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);
+}
+
diff --git a/tests/nlmsg/test b/tests/nlmsg/test
new file mode 100755
index 0000000..18bb794
--- /dev/null
+++ b/tests/nlmsg/test
@@ -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;