@@ -20,7 +20,7 @@ TARGETS = \
test_task_create.te test_task_getpgid.te test_task_getsched.te \
test_task_getsid.te test_task_setpgid.te test_task_setsched.te \
test_transition.te test_inet_socket.te test_unix_socket.te \
- test_wait.te test_mmap.te test_overlayfs.te
+ test_alg_socket.te test_wait.te test_mmap.te test_overlayfs.te
ifeq ($(shell [ $(POL_VERS) -ge 24 ] && echo true),true)
TARGETS += test_bounds.te
@@ -0,0 +1,25 @@
+#################################
+#
+# Policy for testing sockets in
+# the AF_ALG namespace (Crypto
+# API).
+#
+
+attribute algsocketdomain;
+
+# Domain for client process.
+type test_alg_socket_client_t;
+domain_type(test_alg_socket_client_t)
+unconfined_runs_test(test_alg_socket_client_t)
+typeattribute test_alg_socket_client_t testdomain;
+typeattribute test_alg_socket_client_t algsocketdomain;
+
+# client can bind socket.
+allow test_alg_socket_client_t self:alg_socket bind;
+
+# client can request to load a kernel module
+kernel_request_load_module(algsocketdomain)
+
+# Allow all of these domains to be entered from the sysadm domain.
+miscfiles_domain_entry_test_files(algsocketdomain)
+userdom_sysadm_entry_spec_domtrans_to(algsocketdomain)
@@ -0,0 +1,94 @@
+/*
+ * The alg_socket is representative of the new set of
+ * socket families that the kernel is able to classify
+ * when it supports the new extended_socket_class policy
+ * capability.
+ *
+ * This test simply checks the result of bind() using
+ * the Kernel Crypto API.
+ */
+
+#include <sys/socket.h>
+#include <linux/if_alg.h>
+#include <linux/version.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+/*
+ * First kernel version that supports the new
+ * extended_socket_class policy capability.
+ */
+
+#define KER_VERSION 4
+#define KER_PATCHLEVEL 99
+#define KER_SUBLEVEL 99
+
+void usage(char *progname)
+{
+ fprintf(stderr,
+ "usage: %s [succeed|fail]\n",
+ progname);
+ exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+ int succeed;
+ int sock;
+
+ if (argc != 2)
+ usage(argv[0]);
+
+ if (!strcmp(argv[1], "succeed"))
+ succeed = 1;
+ else if (!strcmp(argv[1], "fail"))
+ succeed = 0;
+ else
+ usage(argv[0]);
+
+ sock = socket(AF_ALG, SOCK_SEQPACKET, 0);
+ if (sock < 0) {
+ perror("socket");
+ exit(1);
+ }
+
+ if (succeed == 1) {
+ struct sockaddr_alg sa_good = {
+ .salg_family = AF_ALG,
+ .salg_type = "hash",
+ .salg_name = "sha256",
+ };
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(KER_VERSION,KER_PATCHLEVEL,KER_SUBLEVEL)
+ if (bind(sock, (struct sockaddr *) &sa_good, sizeof(sa_good)) < 0) {
+ perror("bind (algorithm available)");
+ close(sock);
+ exit(1);
+ }
+#else /* kernel does not support the new policy capability */
+ exit(0);
+#endif
+ } else {
+ struct sockaddr_alg sa_bad = {
+ .salg_family = AF_ALG,
+ .salg_type = "hash",
+ .salg_name = "NOTAVAILABLE",
+ };
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(KER_VERSION,KER_PATCHLEVEL,KER_SUBLEVEL)
+ if (bind(sock, (struct sockaddr *) &sa_bad, sizeof(sa_bad)) < 0) {
+ perror("bind (algorithm not available)");
+ close(sock);
+ exit(1);
+ }
+#else /* kernel does not support the new policy capability */
+ exit(1);
+#endif
+ }
+
+ close(sock);
+ exit(0);
+}
@@ -0,0 +1,5 @@
+TARGETS=client
+
+all: $(TARGETS)
+clean:
+ rm -f $(TARGETS)
@@ -0,0 +1,26 @@
+#!/usr/bin/perl
+
+use Test;
+BEGIN { plan tests => 2}
+
+$basedir = $0; $basedir =~ s|(.*)/[^/]*|$1|;
+
+#
+# Tests for sockets in the AF_ALG namespace (Crypto API).
+#
+# The AF_ALG socket is representative of the new set of
+# socket families that the kernel can classify when it
+# supports the new extended_socket_class policy capability.
+#
+
+# Verify that the client can initialize the server with an
+# available algorithm.
+$result = system "runcon -t test_alg_socket_client_t $basedir/client succeed";
+ok($result, 0);
+
+# Verify that the client cannot initialize the server with an
+# unavailable algorithm.
+$result = system "runcon -t test_alg_socket_client_t $basedir/client fail";
+ok($result);
+
+exit;