zcryptctl: Add control domain handling

Support control domain handling for custom zcrypt device nodes.

Signed-off-by: Juergen Christ <jchrist@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
Juergen Christ
2022-03-11 14:19:50 +01:00
committed by Jan Höppner
parent 071522f7d2
commit c22d282e67
2 changed files with 152 additions and 9 deletions

View File

@@ -1,6 +1,6 @@
.\" zcryptctl.8
.\"
.\" Copyright 2018 IBM Corp.
.\" Copyright 2018, 2022 IBM Corp.
.\" s390-tools is free software; you can redistribute it and/or modify
.\" it under the terms of the MIT license. See LICENSE for details.
.\"
@@ -10,7 +10,7 @@
.\" nroff -man zcryptctl.8
.\" to process this source
.\"
.TH ZCRYPTCTL 8 "AUG 2018" "s390-tools"
.TH ZCRYPTCTL 8 "JAN 2022" "s390-tools"
.SH NAME
zcryptctl \- display information and administrate zcrypt multiple device nodes
.SH SYNOPSIS
@@ -35,6 +35,11 @@ zcryptctl \- display information and administrate zcrypt multiple device nodes
.B deldom
.I node-name domain-nr
.TP
.B zcryptctl addctrl
.R |
.B delctrl
.I node-name domain-nr
.TP
.B zcryptctl addioctl
.R |
.B delioctl
@@ -57,6 +62,7 @@ driver. Each zcrypt device node can be restricted in terms of crypto
cards, domains, and available ioctls. Such a device node can be used
as a base for container solutions like Docker to control and restrict
the access to crypto resources.
See the NOTES section below for information on control domains.
.SH COMMANDS
.TP 8
.B zcryptctl list
@@ -96,6 +102,14 @@ Update the filter for the specified zcrypt device node and add or
delete a domain to be accessible through this node. The symbol
\fBALL\fP can be used to enable or disable all domains.
.TP
.B zcryptctl addctrl
.R |
.B delctrl
.I node-name domain-nr
Update the filter for the specified zcrypt device node and add or
delete a control domain to be accessible through this node. The symbol
\fBALL\fP can be used to enable or disable all domains.
.TP
.B zcryptctl addioctl
.R |
.B delioctl
@@ -116,19 +130,20 @@ line and the settings are applied. Syntax is simple:
.IP "node=<node-name>"
.IP "aps=<list of ap numbers separated by space, tab or ','>"
.IP "doms=<list of domain numbers separated by space, tab or ','>"
.IP "ctrls=<list of control domain numbers separated by space, tab or ','>"
.IP "ioctls=<list of ioctl as numeric or symbolic number separated by space, tab or ','>"
.LP
Empty lines are ignored and the '#' marks the rest of the
line as comment.
.LP
The \fBnode=\fP line creates a new zcrypt device node, the \fBaps=\fP,
\fBdoms=\fP and \fBioctls=\fP lines customize the previously created
node. The symbol \fBALL\fP is also recognized for aps, doms, and
ioctls.
\fBdoms=\fP, \fBctrls=\fP and \fBioctls=\fP lines customize the
previously created node. The symbol \fBALL\fP is also recognized for
aps, doms, and ioctls.
.LP
Each action must fit into one line, spreading over multiple lines is
not supported. But you can use more than one \fBaps=\fP, \fBdoms=\fP
and \fBioctls=\fP lines to customize the very same node.
not supported. But you can use more than one \fBaps=\fP, \fBdoms=\fP,
\fBctrls=\fP and \fBioctls=\fP lines to customize the very same node.
.LP
Processing stops when a line cannot be parsed or the current action
fails. In this case the exit status is non zero but the successful
@@ -139,6 +154,17 @@ actions until the failure occurs are not rolled back.
List the current configuration in a form suitable for input to the
\fBzcryptctl config\fP command.
.LP
.SH NOTES
Control domain filtering is only supported for custom device
<nodename> if the \fBadmask\fP file in sysfs under
/sys/class/zcrypt/<nodename>/admask exists. If this file does not
exist, the kernel is too old and does not support control command
filtering. This is the same effect as setting the control domain mask
to ALL. Note that, even though you can allow more than available to
the system, you can only send control commands to control domains
available to the system.
.SH EXIT STATUS
On successful completion of the command the exit status is 0. A non
zero return code (and some kind of failure message) is emitted if the

View File

@@ -2,7 +2,7 @@
* zcryptctl - Maintain zcrypt multi device nodes.
*
* by Harald Freudenberger <freude@linux.ibm.com>
* Copyright IBM Corp. 2018
* Copyright IBM Corp. 2018, 2022
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
@@ -58,6 +58,8 @@
#define CMD_DEL_IOCTL 0x0009
#define CMD_CONFIG 0x000A
#define CMD_LISTCONFIG 0x000B
#define CMD_ADD_CTRL 0x000C
#define CMD_DEL_CTRL 0x000D
/*
* Program configuration
@@ -70,7 +72,7 @@ static const struct util_prg prg = {
{
.owner = "IBM Corp.",
.pub_first = 2018,
.pub_last = 2018,
.pub_last = 2022,
},
UTIL_PRG_COPYRIGHT_END
}
@@ -345,6 +347,18 @@ static int cmd_list(int cmd,
if (test_bit(i, buf))
printf("%c%d", n++ == 0 ? tab : ',', i);
putchar('\n');
if (cmd == CMD_LISTCONFIG)
printf(" ctrls =");
else
printf(" control domains:");
if (read_dn_attr(de->d_name, "admask", buf, sizeof(buf)) != 0)
errx(EXIT_FAILURE,
"Could not fetch admask attribute from sysfs for zcrypt node '%s'",
de->d_name);
for (i = n = 0; i < MAX_ZDEV_DOMAINS_EXT; i++)
if (test_bit(i, buf))
printf("%c%d", n++ == 0 ? tab : ',', i);
putchar('\n');
if (cmd == CMD_LISTCONFIG)
printf(" ioctls =");
else
@@ -526,6 +540,52 @@ static int cmd_add_del_dom(int cmd, const char *node, const char *arg)
return 0;
}
static void add_del_ctrl(int cmd, const char *node, int dom)
{
int rc;
char buf[PATH_MAX];
if (cmd == CMD_ADD_CTRL)
sprintf(buf, "+%d", dom);
else
sprintf(buf, "-%d", dom);
rc = write_dn_attr(node, "admask", buf);
if (rc != 0)
errx(EXIT_FAILURE,
"Could not write into sysfs entry to %s domain %d for zdev node '%s'",
cmd == CMD_ADD_CTRL ? "add" : "remove", dom, node);
}
static int cmd_add_del_ctrl(int cmd, const char *node, const char *arg)
{
int dom, all = 0;
if (strcasecmp(arg, "ALL") == 0) {
all = 1;
} else {
if (sscanf(arg, "%i", &dom) != 1)
errx(EXIT_FAILURE,
"Invalid domain argument '%s'", arg);
if (dom < 0 || dom >= MAX_ZDEV_DOMAINS_EXT)
errx(EXIT_FAILURE,
"Domain argument '%s' out of range [0..%d]",
arg, MAX_ZDEV_DOMAINS_EXT - 1);
}
if (!all) {
add_del_ctrl(cmd, node, dom);
printf("Control domain %d %s\n", dom,
(cmd == CMD_ADD_CTRL ? "added" : "removed"));
} else {
for (dom = 0; dom < MAX_ZDEV_DOMAINS_EXT; dom++)
add_del_ctrl(cmd, node, dom);
printf("All control domains %s\n",
(cmd == CMD_ADD_CTRL ? "added" : "removed"));
}
return 0;
}
static void add_del_ioctl(int cmd, const char *node, int ioctlnr)
{
int rc;
@@ -700,6 +760,28 @@ static int cmd_config(int cmd _UNUSED_,
while (isblank(*p) || *p == ',')
p++;
}
} else if (_match_keyword(&p, "ctrls")) {
if (!havenode)
errx(EXIT_FAILURE,
"Missing node=... before processing any ctrls=... statements in line %d '%s'",
nr, line);
if (!_match_character(&p, '='))
errx(EXIT_FAILURE,
"Missing '=' at '%-8.8s...' in line %d '%s'",
p, nr, line);
while (1) {
while (isspace(*p))
p++;
if (*p == '\0' || *p == '#')
break;
if (!_match_string(&p, buf))
errx(EXIT_FAILURE,
"Missing argument(s) for ctrls=... at '%-8.8s...' in line %d '%s'",
p, nr, line);
cmd_add_del_ctrl(CMD_ADD_CTRL, node, buf);
while (isblank(*p) || *p == ',')
p++;
}
} else if (_match_keyword(&p, "ioctls")) {
if (!havenode)
errx(EXIT_FAILURE,
@@ -817,6 +899,28 @@ static struct zcryptctl_cmds_s {
"domain argument may be a number in the range 0-255 or the\n"
"symbol ALL.",
},
{
.cmd = CMD_ADD_CTRL,
.command = "addctrl",
.function = cmd_add_del_ctrl,
.usage = "zcryptctl addctrl <domain>",
.description =
"Update the filter for the specified zcrypt device node and\n"
"add a crypto control domain to be accessible via this node.\n"
"The domain argument may be a number in the range 0-255 or\n"
"the symbol ALL.",
},
{
.cmd = CMD_DEL_CTRL,
.command = "delctrl",
.function = cmd_add_del_ctrl,
.usage = "zcryptctl delctrl <domain>",
.description =
"Update the filter for the specified zcrypt device node and\n"
"remove a crypto control domain from the allowed domains list.\n"
"The domain argument may be a number in the range 0-255 or\n"
"the symbol ALL.",
},
{
.cmd = CMD_ADD_IOCTL,
.command = "addioctl",
@@ -1003,6 +1107,19 @@ int main(int argc, char *argv[])
argv[optind + 1],
argv[optind + 2]);
break;
case CMD_ADD_CTRL:
case CMD_DEL_CTRL:
if (optind + 1 >= argc)
errx(EXIT_FAILURE, "Missing node name argument");
if (optind + 2 >= argc)
errx(EXIT_FAILURE, "Missing domain argument");
if (check_nodename(argv[optind + 1]) != 0)
errx(EXIT_FAILURE, "Invalid or unknown nodename '%s'",
argv[optind + 1]);
rc = zcryptctl_cmds[cmdindex].function(c,
argv[optind + 1],
argv[optind + 2]);
break;
case CMD_ADD_IOCTL:
case CMD_DEL_IOCTL:
if (optind + 1 >= argc)