Compare commits

...

430 Commits

Author SHA1 Message Date
Jan Höppner
ab35d92028 New release s390-tools-2.13.0
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-07 02:16:43 +02:00
Viktor Mihajlovski
39ceb02404 genprotimg: Add sample script to verify host keys
The genprotimg tool doesn't yet contain code to verify IBM Secure Execution
host key documents. The sample script check_hostkeydoc outlines the steps
that need to be followed by users to verify a host key before it should
be used with genprotimg to build secure Linux images.

Signed-off-by: Viktor Mihajlovski <mihajlov@linux.ibm.com>
Reviewed-by: Patrick Steuer <patrick.steuer@de.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-06 17:57:19 +02:00
Philipp Rudo
454f1427d3 zipl/libc: Fix printing zeros in vsnprintf
Printing the number zero (e.g. printf("%u", 0)) currently only gives you
an empty string. This is because the while-do loop to map the number to a
string is only entered when the value is 'true', i.e. non-zero. Fix this
by using do-while instead.

Fixes: 6fe9e6c ("zipl/libc: Introduce vsnprintf")
Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
Reported-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-06 17:36:39 +02:00
Jason J. Herne
1b65b23b43 zipl: Support nvme devices
nvme devices use the same on-disk bootmap as scsi devices. When the target
device is nvme (using the blkext driver) we simply treat it as scsi.

Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-06 17:36:39 +02:00
Marc Hartmayer
0c583ec1a6 zipl: set NULL-termination for the new command line
Let's assume the original `command_line` is 'aaaaaaaaaaaaaaaaaa' and
`cextra` is ' =blub'. With the old code this would result in the
following new command line:

'blubaaaaaaaaaaaaa' instead of the expected result 'blub\0aaaaaaaaaaaa'

Let's fix this by setting the NULL-termination for the new command
line. While at it, use the `command_line` variable instead of casting
an address.

Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-06 17:36:39 +02:00
Marc Hartmayer
0ac7ce964e zipl/stage3: skip the equal sign when replacing
Skip the equal sign when replacing the original command line.

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-06 17:36:39 +02:00
Marc Hartmayer
4eea67cd6f zipl/stage3: fix buffer overflow
The inserted blank must also be taken into account for the calculation
of `cmdline_len`. In general it's only possible to insert a blank if
the command line length is not already the maximum.

Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-06 17:36:39 +02:00
Marc Hartmayer
9a68a25ab6 zipl/stage3: fix two out-of-bounds reads
`src` parameter for `memcpy` is set to `cextra + begin` but the offset
begin is not taken into account for the calculation of the length that
should be copied.

Fix this by increment the cextra pointer for each skipped whitespace
of the extra parameter.

While at it, rename `end` variable to `cmdline_len`, `command_line`
variable to `cmdline`, remove useless void pointer cast, and use
strlen instead of a while loop to determine the cmdline string length.

Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-06 17:36:39 +02:00
Marc Hartmayer
1a150b2fe0 zipl/stage3: fix "off-by-two" errors
1. `begin` is used as array index and should therefore never be greater
    than COMMAND_LINE_SIZE - 1. Therefore let's fix the while condition.

2. `length` describes the string length and should therefore also never
    be greater than COMMAND_LINE_SIZE - 1.

The 1. off-by-two error can lead to a out-of-bounds read and the 2.
to a buffer overflow.

Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-06 17:36:39 +02:00
Marc Hartmayer
0843b7db36 zipl/stage3: use command_line variable whenever possible
Use `command_line` variable whenever possible, this makes the code
easier to read.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-06 17:36:39 +02:00
Marc Hartmayer
cc069af26d zipl/libc: use stddef.h instead of self defined macros and types
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-06 17:36:39 +02:00
Marc Hartmayer
d978fc6141 boot/ipl.h: remove aligned attribute from struct ipl_parameter_block
This fixes an error when genprotimg is compiled with clang and the
sanitizers address and undefined behaviour enabled.

pv/pv_ipib.c:47:33: runtime error: member access within misaligned address 0x62100000a100 for type 'IplParameterBlock' (aka 'struct ipl_parameter_block'), which requires 4096 byte alignment
0x62100000a100: note: pointer points here
 01 00 00 45  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00
              ^
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior pv/pv_ipib.c:47:33 in

This change should be no problem as genprotimg is the only user.

Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-06 17:36:39 +02:00
Marc Hartmayer
2fe5f27975 zipl/boot: reuse STAGE2_ENTRY and PSW_LOAD
Use STAGE2_ENTRY and PSW_LOAD instead of hard-coded values. While at
it, also move the libc.h to the top in tape2dump.c.

Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-06 17:36:39 +02:00
Marc Hartmayer
93a0cb254e Consolidate PSW masks
While at it, rename PSW_SHORT_ADDR_MASK and PSW_ADDRESS_MASK to
PSW32_ADDR_MASK. As a side effect this removes the zipl.h dependency
of the boot loaders. While at it,

Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-06 17:36:39 +02:00
Marc Hartmayer
eb4e806cdc zipl/sclp: remove PSW_* macros
They were never used and can therefore be removed.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-06 17:36:39 +02:00
Marc Hartmayer
19f747847f zipl/boot: use C pre-processor for linker script generation
Use C pre-processor for linker script generation and refactor some
constants. This allows the usage of the constants in our "linker
scripts" `*.lds.S` (actually, these are assembler files, so we can
make us of the C pre-processor and its capabilities).

While at it, enforce the described memory layout in the generated
linker script.

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-06 17:36:39 +02:00
Marc Hartmayer
ce65c39e18 zipl: consolidate COMMAND_LINE_EXTRA and COMMAND_LINE_SIZE
Move COMMAND_LINE_EXTRA to `boot/loaders_layout.h` so it can be reused
by `menu.c`and `stage3.c`. Additionally, reuse COMMAND_LINE_SIZE from
`linux_layout.h` in `menu.c`.

Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-06 17:36:39 +02:00
Marc Hartmayer
6c04f97773 zipl: consolidate stage3_params structs and stage3 flags
Introduce a struct definition for the stage3 parameters used by
stage3.c. This makes it easier to maintain the stage3 linker script
and it allows us to consolidate the stage3_params structs defined in
`stage3.h` and `include/boot.h` as well as the stage3 flag macros.

Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-06 17:36:39 +02:00
Marc Hartmayer
cb11d6baec stage3.h: remove superfluous libc.h include
This allows the usage of stage3.h in files where other libc
implementations than our minimal libc is used, e.g. glibc.

Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-06 17:36:39 +02:00
Marc Hartmayer
c673bacd7e Replace UTIL_ARRAY_SIZE with ARRAY_SIZE
Replace `UTIL_ARRAY_SIZE` with `ARRAY_SIZE` and remove it from
`util_base.h`.

Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-06 17:36:39 +02:00
Marc Hartmayer
6cf7f31746 cpuplugd: Remove redundant declaration of ‘debug’
This fixes cpuplugd.h:157:12: warning: redundant redeclaration of ‘debug’ [-Wredundant-decls]
  157 | extern int debug;        /* is verbose specified? */
      |            ^~~~~
cpuplugd.h:155:12: note: previous declaration of ‘debug’ was here
  155 | extern int debug;
      |            ^~~~~

Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-06 17:36:39 +02:00
Stefan Haberland
c4a0933165 zipl: prevent endless loop during IPL
In case secure boot is enabled but no components in the IPL report
are found it ends up in an endless loop in the component verification.
To prevent this check if components are found and exit if not.

Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-06 17:36:39 +02:00
Stefan Haberland
e67f630086 zipl: check for valid ipl parmblock lowcore pointer
The lowcore parmblock pointer is not valid in every case. For example
it is invalid for CCW type IPL.
To have an indication if the pointer is valid do a diag308 to store the
parmblock and check if secure boot is enabled.
If it is enabled the lowcore pointer is valid and the ipl report that is
needed for secure boot can be found right behind the ipl parmblock.

Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-06 17:36:39 +02:00
Marc Hartmayer
465348ced9 Add build and runtime dependencies for genprotimg to README.md
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-06 17:36:39 +02:00
Marc Hartmayer
f148df4cc3 genprotimg: fix table in README.md
Fix the table used in README.md.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-06 17:36:39 +02:00
Marc Hartmayer
4d61a21811 genprotimg: fix dependency tracking for .lds generation
Variable names are case sensitive in Makefiles, therefore fix the typo
in the variable reference.

Fixes: 2d600570df ("genprotimg: boot: use C pre-processor for linker script generation")
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-06 17:36:39 +02:00
Marc Hartmayer
e0ffb3c584 zipl/boot: make stage2.h assembler compatible
In preparation for the linker script generation make the stage2.h
assembler compatible.

Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-06 17:36:39 +02:00
Marc Hartmayer
f4f2220693 zipl/stage3: include loaders_layout.h
stage3.c uses `IMAGE_LOAD_ADDRESS`, which is defined in
`loaders_layout.h`. Therefore let's include it explicitly.

Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-06 17:36:39 +02:00
Marc Hartmayer
fb62cc9e14 zipl/boot: fix dependencies of stage2 loaders
If the stage2.lds linker script changes we must rebuild all stage2
loaders so let's add stage2.lds as a target dependency.

Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-06 17:36:39 +02:00
Marc Hartmayer
c91d8bd5f9 zipl: use unsigned int for the iteration variable
This fixes the false positive

CC      zipl/src/misc.o
misc.c: In function ‘misc_temp_dev’:
misc.c:313:27: warning: ‘%04d’ directive writing between 4 and 11 bytes into a region of size 5 [-Wformat-overflow=]
    sprintf(filename, "zipl%04d", retry);
                           ^~~~
misc.c:313:22: note: directive argument in the range [-2147483648, 999]
    sprintf(filename, "zipl%04d", retry);
                      ^~~~~~~~~~
misc.c:313:4: note: ‘sprintf’ output between 9 and 16 bytes into a destination of size 9
    sprintf(filename, "zipl%04d", retry);
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

While at it, add an assertion that protects against a format-overflow,
e.g. if TEMP_DEV_MAX_RETRIES changes.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-06 17:36:39 +02:00
Gerald Schaefer
4753340e79 ipl_tools: support clear attribute for FCP and CCW re-IPL
This patch adds support for the "clear" sysfs attribute for re-IPL, if
available. This attribute allows to control whether the memory should
be cleared on re-IPL.

Signed-off-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Acked-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-05-06 17:36:39 +02:00
Julian Wiedmann
f742ed73e1 dbginfo: gather ethtool output for per-queue coalescing
Some drivers provide per-queue IRQ coalescing information, collect it.

Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-03-16 13:41:43 +01:00
Marc Hartmayer
65b9fc442c genprotimg: introduce new tool for the creation of PV images
Protected VMs (PVM) are KVM VMs, where KVM can't access the VM's state
like guest memory and guest registers anymore. Instead the PVMs are
mostly managed by a new entity called Ultravisor (UV), which provides
an API, so KVM and the PV can request management actions.

PVMs are encrypted at rest and protected from hypervisor access while
running. They switch from a normal operation into protected mode, so
we can still use the standard boot process to load an encrypted image
and then move it into protected mode.

This commit adds the tool 'genprotimg'. It takes a kernel, key files,
optionally an initrd, optionally a file with the kernel command line,
and it generates a single, loadable image file. The image consists of
a concatenation of a plain text boot loader, the encrypted components
for kernel, initrd, and cmdline, and the integrity-protected PV
header, containing metadata necessary for running the guest in PV
mode.

It's possible to use this image file as a kernel for zipl or for a
direct kernel boot using QEMU.

Reviewed-by: Bjoern Walk <bwalk@linux.ibm.com>
Acked-by: Patrick Steuer <patrick.steuer@de.ibm.com>
Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-03-16 13:41:35 +01:00
Thomas Richter
2c106425e8 cpumf_helper: Avoid perl warning from pod2usage function
The pod2usage function from module Pod::Usage always emits this warning
when the module is loaded, even if the funtion is not invoked at all:

The script_run feature is experimental in regex;
            marked by <-- HERE in m/(*script_run: <-- HERE  ^ .* $ )/
            at (eval 14) line 2.

To avoid this warning every time the cpumf_helper script is invoked,
do not use function pod2usage. The use of this function has no
benefit. cpumf_helper is invoked under the covers from lscpumf and
chcpumf, so it is sufficient to print the help text in case a wrong
parameter has been supplied.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-03-16 13:39:10 +01:00
Marc Hartmayer
11bdab2629 include/boot/s390.h: add guard for struct __vector128
`linux/asm/types.h` also defines the struct `__vector128` so in order
to avoid definition conflicts add the macro guard _S390_TYPES_H, which
is defined in `linux/asm/types`. `linux/asm/types.h` is included by
glib2, which is used by the PV tooling.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-03-16 13:39:10 +01:00
Marc Hartmayer
b06af6026f README.md: remove useless empty line
Remove useless empty line.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-03-16 13:39:10 +01:00
Thomas Richter
1086548607 cpumf: Add IBM z15 extended counter defintion file
Add IBM Z15 extended counter definition file to Makefile
DATA_FILES list.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-03-16 13:39:10 +01:00
Jens Remus
fbf8513d43 zfcpdbf: print HBA FC Endpoint Security trace records
Format and print HBA FC Endpoint Security trace records with a record ID
of ZFCP_DBF_HBA_FCES (5). Align output to the one of FSF response trace
records for readability. Note that the FSF protocol status is most likely
FSF_PROT_GOOD (0x00000001).

Signed-off-by: Jens Remus <jremus@linux.ibm.com>
Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-03-16 13:39:10 +01:00
Jens Remus
67496afe57 zdev: Report FC Endpoint Security of zfcp devices
Add support to report Fibre Channel (FC) Endpoint Security
related information for zfcp-host and zfcp-lun devices.

Allow to query (lszdev) and provide help for (chzdev) the FC Endpoint
Security capability of a FCP device (zfcp-host). Provide this
information by defining the FCP device attribute fc_security in zdev
zfcp-host.

Allow to query (lszdev) and provide help for (chzdev) the FC Endpoint
Security in use on a connection between a FCP device and a FC remote
port. Provide this information by introducing a virtual zdev zfcp-lun
attribute fc_security. It returns the fc_security attribute value of
the zfcp port object representing the FC remote port used to access the
LUN.
This approach allows users of lszdev to easily query the FC Endpoint
Security in use on the connections to one or more FCP LUNs. It also
does not require the effort to introduce a zfcp-port device type in
zdev.

The fc_security attribute help for both zfcp-host and zfcp-lun can be
queried for example as follows:

    chzdev zfcp --help-attribute

The fc_security attribute values and path of all active zfcp devices
can be queried for example as follows:

    lszdev zfcp -a -c TYPE,ID,ATTR:fc_security,ATTRPATH:fc_security

Signed-off-by: Jens Remus <jremus@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Fedor Loshakov <loshakov@linux.ibm.com>
Reviewed-by: Benjamin Block <bblock@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-03-16 13:39:10 +01:00
Jens Remus
16b2799150 zdev: Handle special case in if-case
As preparation for a following commit reorder the path logic in function
zfcp_lun_st_get_active_attrib_path(). This then allows to handle
subsequent special cases more easily. Additionally it also enhances the
readability of the expression.

Signed-off-by: Jens Remus <jremus@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Reviewed-by: Fedor Loshakov <loshakov@linux.ibm.com>
Reviewed-by: Benjamin Block <bblock@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-03-16 13:39:10 +01:00
Peter Oberparleiter
c063273b14 zdev: Introduce read-only attributes
Add support for defining read-only attributes in the chzdev/lszdev
tools. These attributes can be used to provide online documentation
for specific attributes via the --help-attribute and --list-attributes
tool functions.

Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Reviewed-by: Fedor Loshakov <loshakov@linux.ibm.com>
Reviewed-by: Benjamin Block <bblock@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-03-16 13:39:10 +01:00
Marc Hartmayer
d2f8f972cf genprotimg: add relocator for stage3b
Add support for the placement of the stage3b loader at other addresses
than 0xa000. For this add a position independent relocator that first
copies the original stage3b code to the memory location 0xa000 and
then starts it.

Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-03-16 13:39:10 +01:00
Marc Hartmayer
2d600570df genprotimg: boot: use C pre-processor for linker script generation
Use C pre-processor for linker script generation. This allows the
usage of constants in our "linker scripts" `*.lds.S` (actually, these
are assembler files, so we can make us of the C pre-processor and its
capabilities).

Suggested-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-03-16 13:39:10 +01:00
Marc Hartmayer
3356d6f4fa genprotimg: boot: initial bootloader support
Add a boot loader for protected virtualization (PV) that can be
combined with a kernel/initrd/parmfile to form a single bootable file.
This file must be constructed in a way that it can be used (1) for a
QEMU direct kernel boot and (2) it can be zipl'ed by the normal,
unmodified zipl program.

This new boot loader consists of two parts:

1. stage3a boot loader (cleartext), this loader is responsible for
   the transition into the protected mode by doing diag308 subcode 8
   and 10 calls.

2. stage3b boot loader (encrypted), this loader is very similar to the
   normal zipl stage3 boot loader. It will be loaded by the Ultravisor
   after the successful transition into protected mode. Like the zipl
   stage3 boot loader it moves the kernel and patches in the values
   for initrd and parmline.

The requirements for (1) and (2) result in the following constraints:

1. It must be possible to place stage3a and stage3b at a location >=
   0x10000 because the zipl stage3 loader zeroes out everything at
   addresses lower than 0x10000 of the image.

2. As the stage3 loader of zipl assumes that the passed kernel image
   looks like a normal kernel image, the zipl stage3 loader modifies the
   content at the memory area 0x10400 - 0x10800, therefore we leave this
   area unused in our stage3a loader.

3. The default entry address used by the zipl stage3 loader is 0x10000
   so we add a simple branch to 0x11000 at 0x10000 so the zipl stage3
   loader can modify the area 0x10400 - 0x10800 without affecting the
   stage3a loader.

The stage3b loader is linked at address 0x9000, therefore it will not
work at another address. The relocation support for the stage3b
loader, so that it can be placed at addresses != 0x9000, is added in
the next patch. This loader with relocation support has the name
'stage3b_reloc'.

The memory layout of the single bootable file looks like:

+-----------------------+-----------+------------------------+
|Start                  |End        |Use                     |
+=======================+===========+========================+
|0                      |0x7        |Short PSW, starting     |
|                       |           |instruction at 0x11000  |
+-----------------------+-----------+------------------------+
|0x10000                |0x10012    |Branch to 0x11000       |
+-----------------------+-----------+------------------------+
|0x10013                |0x10fff    |Left intentionally      |
|                       |           |unused                  |
+-----------------------+-----------+------------------------+
|0x11000                |0x12fff    |Stage3a                 |
+-----------------------+-----------+------------------------+
|0x13000                |0x13fff    |IPIB used as argument   |
|                       |           |for the diag308 call    |
+-----------------------+-----------+------------------------+
|0x14000                |0x1[45]fff |UV header used for the  |
|                       |           |diag308 call (size can  |
|                       |           |be either 1 or 2 pages) |
+-----------------------+-----------+------------------------+
|NEXT_PAGE_ALIGNED_ADDR |           |Encrypted Kernel        |
+-----------------------+-----------+------------------------+
|NEXT_PAGE_ALIGNED_ADDR |           |Encrypted Cmdline       |
+-----------------------+-----------+------------------------+
|NEXT_PAGE_ALIGNED_ADDR |           |Encrypted Initrd        |
+-----------------------+-----------+------------------------+
|NEXT_PAGE_ALIGNED_ADDR |           |Encrypted Stage3b_reloc |
+-----------------------+-----------+------------------------+

Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-03-16 13:39:10 +01:00
Marc Hartmayer
67aef9bbf3 Consolidate ALIGN, __ALIGN_MASK, ARRAY_SIZE macros
Consolidate `ALIGN, __ALIGN_MASK, ARRAY_SIZE` macros and add them to
lib/zt_common.h. While at it, adapt coding style.

Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-03-16 13:39:10 +01:00
Thomas Richter
5d2871d626 cpumf/data: Add new deflate counters for IBM z15
Add support for new deflate counters:
- Counter 247: cycles CPU spent obtaining access to Deflate unit
- Counter 252: cycles CPU is using Deflate unit
- Counter 264: Increments by one for every DEFLATE CONVERSION CALL
    instruction executed.
- Counter 265: Increments by one for every DEFLATE CONVERSION CALL
    instruction executed that ended in Condition Codes
    0, 1 or 2.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-03-16 13:39:10 +01:00
Marc Hartmayer
6fcf64ebe0 lib/util_file.h: fix typo in the macro guard
Fix typo in the macro guard.

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-03-16 13:39:10 +01:00
Marc Hartmayer
e51663bbca zipl/libc: printf: print on linemode and ASCII console
... if the `ENABLE_SCLP_ASCII` macro is defined.

Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-03-16 13:39:10 +01:00
Marc Hartmayer
f99560f734 zipl/sclp: add sclp_print_ascii
Add `sclp_print_ascii` function that can be used to print output on
the SCLP ASCII console. This would increase the size of the
loaders (e.g. eckd2.bin and fba2.bin) and therefore might break the
compilation. In order to avoid that add a macro 'ENABLE_SCLP_ASCII'
which must be defined by the users of the `sclp_print_ascii` function.

Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-03-16 13:39:10 +01:00
Marc Hartmayer
303a3707e2 zipl/sclp: add macros for the control-program masks
Add macros for the control-program masks and use them.

Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-03-16 13:39:10 +01:00
Marc Hartmayer
a37170b8be zipl: refactor all EBCDIC code into separate files
This allows the reuse of the code later in sclp.c. While at it, also
declare @source parameter of `ebcdic_to_ascii` function as `const` and
rename all `ebc_` function name prefixes into `ebcdic_`. Move
conversion tables to separate file so it only gets linked into loaders
that need it.

Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-03-16 13:39:10 +01:00
Marc Hartmayer
305235a7bc include/boot/s390.h: fixes for -Werror=sign-conversion
Errors fixed:

../../include/boot/s390.h: In function '__stfle_asm':
../../include/boot/s390.h:424:41: error: conversion to 'long unsigned int' from 'int' may change the sign of the result [-Werror=sign-conversion]
  register unsigned long reg0 asm("0") = size - 1;

../../include/boot/s390.h: In function 'stfle':
../../include/boot/s390.h:453:31: error: conversion to 'long unsigned int' from 'int' may change the sign of the result [-Werror=sign-conversion]
   nr = MIN((nr + 1) * 8, size * 8UL);

../../include/boot/s390.h: In function 'diag308':
../../include/boot/s390.h:296:9: error: conversion from 'long unsigned int' to 'int' may change value [-Werror=conversion]
  return _rc;

Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-03-02 14:26:30 +01:00
Marc Hartmayer
2568863f58 include/boot/s390.h: move panic and panic_notify to libc.h
... as this code is not s390 specific and not every user of s390.h
wants to implement `panic_notify`.

Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-03-02 14:26:30 +01:00
Marc Hartmayer
b0f82d22f9 zipl/libc: include 's390.h'
Include 'boot/s390.h' in 'libc.c' as `PAGE_SIZE` is used there and
move the 'libc.h' include directive to the top.

Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-03-02 14:26:30 +01:00
Marc Hartmayer
b83c8944f1 zipl: move s390.h to include/boot/s390.h
Now that we made sure that s390.h can be used with our minimal libc
implementation and glibc move s390.h to `include/boot/s390.h`. While
at it, make sure that s390.h is assembler compatible as it will be
used later in the PV boot loader and include s390.h in ipl.h as
PAGE_SIZE is used there.

Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-03-02 14:26:30 +01:00
Marc Hartmayer
f454c6825f zipl: remove libc.h include in s390.h
This allows the use of s390.h in combination with other libc
implementations than our minimal libc, e.g. with glibc.

Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-03-02 14:26:30 +01:00
Marc Hartmayer
c55ceabc67 Consolidate MIN and MAX macros
Consolidate MIN and MAX macros and make sure it can be used in
combination with glib.

Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-03-02 14:26:30 +01:00
Marc Hartmayer
2e28291c75 zipl: make BLK_PWRT unsigned int
Otherwise there might be a compiler warning when using 'MIN(bl_count,
BLK_PWRT)'.

Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-03-02 14:26:30 +01:00
Marc Hartmayer
24fe8c1d1b zipl: move __always_inline/barrier/__pa32/pa to zt_common.h
Move `__always_inline/barrier/__pa32/pa` to `lib/zt_common.h` as this
is non-architecture dependent code.

Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-03-02 14:26:30 +01:00
Marc Hartmayer
67e76b8ebd zipl/s390.h: rename inline macro into __always_inline
Rename `inline` macro into `__always_inline` so one can differentiate
between the macro and the C keyword. While at it, undefine the
previous `__always_inline` macro so s390.h can be used in combination
with glibc.

Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-03-02 14:26:30 +01:00
Marc Hartmayer
97ab8fb4e9 zipl: move loaders layout definitions into separate header
Move the loaders (stage2/stage3) layout values to
`include/boot/loaders_layout.h` and use the `_AC` macro for the
constants. This allows the reuse of the definitions, e.g. in assembler
files, and later for the creation of linker scripts.

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-03-02 14:26:30 +01:00
Marc Hartmayer
c07104dbc7 zipl: use STAGE3_ENTRY for STAGE3_LOAD_ADDRESS
Use STAGE3_ENTRY for STAGE3_LOAD_ADDRESS as they have the same value
and this makes it more clear that the load address of stage3 is also
its entry point.

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-03-02 14:26:30 +01:00
Marc Hartmayer
c871050097 zipl: tape0: use constants defined in linux_layout.h
Use the constants defined in `linux_layout.h`. Therefore move the
`PARMAREA` address offset to `linux_layout.h` and include the header.

Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-03-02 14:26:30 +01:00
Marc Hartmayer
7e37a1d4e0 zipl: move Linux layout definitions into separate header
Move the Linux layout values to `include/boot/linux_layout.h`. This
allows the reuse of the definitions, e.g. in assembler files, and
later for the creation of linker scripts.

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-03-02 14:26:30 +01:00
Marc Hartmayer
d884fb8db4 zipl/stage3: make IPL_DEVICE definition consistent with tape0.S
Make `IPL_DEVICE` definition consistent with the kernel definition and
the definition in tape0.S. This allows us to refactor the code later.

Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-03-02 14:26:30 +01:00
Marc Hartmayer
0e385a81ca zipl: add SIGP_SET_ARCHITECTURE to sigp.h and use it
This makes the code easier to read.

Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-03-02 14:26:30 +01:00
Marc Hartmayer
675c854fa3 zipl: move SIGP related functions and definitions into separate header
Move SIGP related functions and definitions to
`include/boot/sigp.h`. This allows the reuse of the definitions in
assembler files.

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Acked-by: Janosch Frank <frankja@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-03-02 14:26:30 +01:00
Marc Hartmayer
9d39a4bd47 zipl: move IPL related definitions into separate header
Move the IPL related definitions into `include/boot/ipl.h`. This
allows the reuse of the definitions, e.g. in the boot loader for
protected guests.

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-03-02 14:26:30 +01:00
Marc Hartmayer
400167f512 Support lib/zt_common.h to be used in assembler and add _AC macro
Support `lib/zt_common.h` to be used in assembler files. In addition,
add the macro `_AC` that can be used to make constant macros usable in
both assembler and C code.

Suggested-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-03-02 14:26:30 +01:00
Julian Wiedmann
4fa9656613 dbginfo: collect softnet_stat
This can be helpful when diagnosing network performance issues.

Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-03-02 14:26:30 +01:00
Michael Holzheu
87b54fc884 CHANGELOG: Fix formatting
Since release v2.4.0 the indentation of the release headings is wrong.
So fix the indentation for all releases since then.

Closes: https://github.com/ibm-s390-tools/s390-tools/pull/81
Signed-off-by: Michael Holzheu <michael@holzheu.de>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-02-27 13:44:46 +01:00
Stefan Haberland
299fd2b772 zipl: fix zipl.conf man page example for secure boot
The secure= option is not supported in the defaultboot section when a
menu is used. It should be placed in the menu section in this case.

Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-02-27 13:44:46 +01:00
Philipp Rudo
36fed0e6c6 zipl/libc: Indicate truncated lines in printf with '...'
Append '...' to lines exceeding the maximum line length instead of
silently truncating them.

Suggested-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-02-27 13:44:46 +01:00
Philipp Rudo
f7430027b4 zipl/libc: Replace sprintf with snprintf
The use of sprintf can easily result in buffer overflows as it assumes
that the buffer it writes to is large enough to contain the formatted
string. Thus replace sprintf by snprintf and update its users.

This removes the last user of vsprintf. Thus also remove vsprintf and
its dependencies.

Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-02-27 13:44:46 +01:00
Philipp Rudo
8874b90825 zipl/libc: Fix potential buffer overflow in printf
Per definition vsprint assumes that the provided buffer it writes to is
large enough to contain the formatted string. As printf uses a fixed
sized buffer (81 bytes) and has no size checks the use of vsprintf can
easily cause buffer overflows. Protect against these buffer overflows by
using vsnprintf instead.

While at it fix a typo in the comment.

Reported-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-02-27 13:44:46 +01:00
Philipp Rudo
6fe9e6c55c zipl/libc: Introduce vsnprintf
The zipl boot loaders have their own minimalistic libc implementation.
In it printf and sprintf use vsprintf for string formatting. Per
definition vsprintf assumes that the buffer it writes to is large enough
to contain the formatted string and performs no size checks. This is
problematic for the boot loaders because the buffer they use are often
allocated on the stack. Thus even small changes to the string format can
potentially cause buffer overflows on the stack with the well known
consequences. Protect against such errors by implementing vsnprintf.
Later patches will make use of it.

This implementation of vsnprintf only supports a small subset of format
options defined in the C standard. In particular it allows the
specifiers:
	* %s (strings)
	* %o (unsigned int octal)
	* %u (unsigned int decimal)
	* %x (unsigned int hexadecimal)

Integer specifiers (o, u, and x) always use the long form, i.e. assume the
argument to be of type 'unsigned long int'. The length modified 'l' can
be given but is ignored.

Furthermore, it is possible to provide the optional field width (aligned
to the right only) and precision as decimal integer (i.e. not via '*')
as well as the flag for zero padding integers (i.e. '0').

The implementation was heavily inspired by the implementation in
lib/vsprintf.c from the Linux kernel tree.

Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-02-27 13:44:46 +01:00
Marc Hartmayer
cc16e41595 zipl: use STATIC_ASSERT macro for no padding verification
A simple comment above the struct declaration to indicate that the
structure must not have any padding is prone to error. Therefore let's
add a check for the structure size at compile time.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-02-27 13:44:46 +01:00
Marc Hartmayer
bac3f93772 lib/zt_common: add STATIC_ASSERT macro
Add `STATIC_ASSERT` macro that uses `_Static_assert` if available (was
introduced with gcc 4.6, see https://gcc.gnu.org/wiki/C11Status). For
example, this could be used for the verification of structure sizes at
compile time.

Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-02-27 13:44:46 +01:00
Marc Hartmayer
971970989b zipl/boot: fix comment in stage3.lds
See STAGE3_STACK_ADDRESS macro.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-02-27 13:44:46 +01:00
Sa Liu
d415b8efed dbginfo: Removed collection of /var/log/opencryptoki/
Signed-off-by: Sa Liu <saliu@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-02-27 13:44:46 +01:00
Ingo Franzki
33031241c3 zkey: Fix display of clear key size for EP11-AES XTS keys
Fixes: a7e47685e0 ("zkey: Add a new key type for EP11 secure keys")
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-02-12 20:02:21 +01:00
Ingo Franzki
49cbaba302 zkey: Fix display of clear key size for CCA-AESCIPHER keys
Fixes: ddde3f354f ("zkey: Introduce the CCA-AESCIPHER key type")
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-02-12 20:02:21 +01:00
Niklas Schnelle
304c3d8086 zpcitctl: Exit on error in sysfs_report_error
This also makes sure that we don't try to write to the
/sys/bus/pci/device/<dev>/recover attribute if reset failed.

Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-02-12 20:02:21 +01:00
Niklas Schnelle
d77234ddb6 zpcictl: Rename misleading sysfs_write_data
To sysfs_report_error as it only writes to the report_error attribute.

Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-02-12 20:02:21 +01:00
Niklas Schnelle
bc0d40c580 zpcictl: Initiate recover after reset
After a zpcitctl --reset the PCI function is currently left in an error
state. This seems unexpected, so follow the SCLP reset with an OS level
recovery using /sys/bus/devices/<dev>/recover.

Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-02-12 20:02:21 +01:00
Mark Post
a1697a581d zdev/dracut/95zdev/module-setup.sh: Add ctcm kernel module
The module-setup.sh script doesn't include the ctcm module
when building the initrd. This causes any CTC devices to
be bound by the LCS driver instead.

Closes: https://github.com/ibm-s390-tools/s390-tools/pull/79
Signed-off-by: Mark Post <mpost@suse.com>
Acked-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-02-12 20:02:21 +01:00
Ingo Franzki
f75f4aff8f zkey: Fix display of XTS attribute for validate command
Use after free causes the XTS attribute to be displayed wrongly.

Fixes: 298fab68fe ("zkey: Preparations for introducing a new key type")
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-02-06 12:53:27 +01:00
Ingo Franzki
729a98fcb3 zkey: Man page updates for the new EP11-AES key type
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-02-03 14:16:51 +01:00
Ingo Franzki
f52aeabca4 zkey: Generalize the key re-enciphering handling
Different crypto card types use different ways to re-encipher a secure
key with a new master key. Generalize the handling of re-enciphering,
so that the majority of the code does not have to care about the card
type when dealing with it.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-02-03 14:16:51 +01:00
Ingo Franzki
0be7efc956 zkey: Add support for re-enciphering EP11 secure keys
Re-encipher EP11 secure keys using the EP11 host library.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-02-03 14:16:51 +01:00
Ingo Franzki
88e6a18f96 zkey: Enhance APQN cross check to check for firmware version
EP11 secure keys require a certain firmware version. Enhance
the APQN cross check to not only check for a minimum card level,
but also for a minimum firmware version.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-02-03 14:16:51 +01:00
Ingo Franzki
a7e47685e0 zkey: Add a new key type for EP11 secure keys
Add key type EP11-AES to support EP11 secure keys.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-02-03 14:16:51 +01:00
Ingo Franzki
b48aa5f435 zkey: Add EP11 library helper routines
Add a new source file that contains EP11 specific helper routines.
These routines require to load the EP11 host library.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-02-03 14:16:51 +01:00
Ingo Franzki
d91e728e3c zkey: Generalize the adapter serial number handling
Different crypto card types use different serial number formats.
Generalize the handling of serial numbers so that the majority of the
code does not have to care about the card type when dealing with it.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-02-03 14:16:51 +01:00
Ingo Franzki
ce4704f365 zkey: Generalize the master key verification pattern handling
Different crypto card types use different master key verification patterns
(MKVPs). Generalize the handling of MKVPs so that the majority of the
code does not have to care about the card type when dealing with MKVPs.

Also generalize messages about the crypto card's master keys to not
mention a specific card type.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-02-03 14:16:51 +01:00
Ingo Franzki
2ca442feed zkey: Add support for reading the firmware version sysfs attribute
EP11 cards provide the firmware version and API ordinal number as
a sysfs attribute on the crypto card level. Add a helper function
that obtains the firmware version and API ordinal number from there.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-02-03 14:16:51 +01:00
Ingo Franzki
82c86fa8bd zkey: Add support for different crypto card types
As preparation for adding support for EP11 secure keys,
generalize the code to support different crypto card types.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-02-03 14:16:51 +01:00
Ingo Franzki
e7f446432b zkey: Fix display of clear key size for XTS keys
Fixes: 298fab68fe ("zkey: Preparations for introducing a new key type")
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-01-22 15:28:55 +01:00
Ingo Franzki
1a87d3a3b4 zkey: fix warn_unused_result compiler warning
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-01-22 15:28:55 +01:00
Ingo Franzki
0de533aef9 zkey: Fix listing of keys on file systems reporting DT_UNKNOWN
The zkey list function uses scandir() to look for files in the
zkey key repository directory. It checks the dirent.d_type field
to consider only regular files, but skip all others.

Unfortunately, not all file systems have full support for returning
the file type in d_type. When the zkey repository is located in a file
system that does not support d_type, such as xfs, zkey list shows no
keys, although the key repository contains keys.

Fix this by also considering directory entries with d_type = DT_UNKNOWN.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-01-08 15:00:11 +01:00
Stefan Haberland
27a6409a4a zipl: clean up temporary bootmap file in case of error
zipl creates a temp bootmap file to keep the original file in case of an
error. Delete this temp file in case of an error.

Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-01-08 15:00:11 +01:00
Stefan Haberland
6f9337d101 zipl: correct secure boot config handling
The hierarchy of the secure boot settings in the config file should be:

defaultboot > menu > section

This patch implements this hierarchy and adds a check if a valid option is
specified and prints an error message otherwise.

Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-01-08 15:00:11 +01:00
Stefan Haberland
27f6c0a167 zipl: allow stand alone secure option on command line
Allow that --secure or -S is specified on command line without the need to
allow all options on the command line.
Also ensure that the command line option overrules the config option and
correctly ensure that secure boot is only set for SCSI devices.

Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-01-08 15:00:11 +01:00
Julian Wiedmann
0652c687e3 dbginfo: collect bridge data
This can be helpful in diagnosing network-related issues.

Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-01-08 15:00:11 +01:00
Jan Höppner
16a62dff03 Prepare for next release
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-01-08 15:00:11 +01:00
Jan Höppner
094905af87 New release s390-tools-2.12.0
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-12-17 13:51:48 +01:00
Jan Höppner
dcce14923c zipl: Add missing options to help output
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-12-12 18:04:32 +01:00
Ingo Franzki
1fd78d9f5e zkey: Fix convert command to use an associated APQN of a key
The zkey convert command must select an CCA adapter out of the
list of associated APQNs (if any) to perform the key conversion.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-12-12 18:04:32 +01:00
Marc Hartmayer
9d1baaa594 zipl: stfle: use uint64_t instead of u64
As the definition of `stfle_fac_list` in the lowcore uses uint64_t, we
should also use uint64_t for the `stfle_fac_list` parameter of the
`stfle/__stfle_asm` function.

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-12-12 18:04:32 +01:00
Marc Hartmayer
efcfbce386 netboot/zipl: use '$(MAKE)' instead of 'make'
Use '$(MAKE)' to pass down the makefile flags.

This fixes the warning:

make[4]: warning: jobserver unavailable: using -j1.  Add '+' to parent make rule.

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-12-12 18:04:32 +01:00
Jan Höppner
3d74c534bf libdasd: Fix flag for opening read-only devices
dasd_is_ro() uses the O_RDWR flag when opening the file descriptor.
However, an attempt to open the file descriptor of a device that is in
read-only state will fail and the BLKROGET ioctl that is used to
actually determine the read-only state can't be issued.
Change the flag to O_RDONLY to fix this.

Fixes: a5c1923d32 ("libdasd: Add common DASD ioctl's to the lib")
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-12-12 18:04:32 +01:00
Jan Höppner
ca2ffe9e18 libdasd: Close file descriptor after use
Fixes: https://github.com/ibm-s390-tools/s390-tools/issues/77
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-12-12 18:04:32 +01:00
Ingo Franzki
52192908eb zkey: Fix typo in help output
The help output for 'zkey generate' has a typo in the description
of the '-N, --name' option mentioning a non-existing '-M' option.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-12-12 18:04:32 +01:00
Ingo Franzki
d4cee7e65a zkey: Fix APQN checking
An invalid APQN like '01.00xx' is not treated as invalid, but results
in APQN '01.0000'. Fix the checking to treat such invalid APQNs as
invalid.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-12-12 18:04:32 +01:00
Jan Höppner
bfbf456b83 dasdview: Fix exit status in error cases
In error cases, dasdview returns -1 which results in the return value
255. This is due to the fact that only the low-order 8 bits are used for
the status value. See 2.13 Status Information [1] in the POSIX standard
and the exit() POSIX man page [2] for more details.

Instead of returning -1, use the EXIT_FAILURE constant to indicate
unsuccessful termination properly. This change also makes the exit
status consistent for all error cases in dasdview, as some exit() calls
already use EXIT_FAILURE.

[1]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html
[2]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/exit.html

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-12-12 18:04:32 +01:00
Sa Liu
235e997a77 dbginfo: journalctl from the current system time with more number of lines and precise timestamp
Signed-off-by: Sa Liu <saliu@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-12-12 18:04:32 +01:00
Sa Liu
c079e48d7d dbginfo: Collect all files under /usr/lib/systemd/system/
Signed-off-by: Sa Liu <saliu@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-12-12 18:04:32 +01:00
Philipp Rudo
4762e65acb zipl: Consolidate STAGE{2,3} macros
Increase consistency with the other macros by moving and renaming
the STAGE{2,3} macros in zipl.h.

Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-12-12 18:04:32 +01:00
Philipp Rudo
cb614ed1ee zipl: Consolidate IMAGE macros
Combine the different macros for 0x10000 and use a consistent naming
schema.

Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-12-12 18:04:32 +01:00
Philipp Rudo
8face3e63e zipl/libc: Use stdint.h instead of self defined macros
Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-12-12 18:04:32 +01:00
Philipp Rudo
ea14f5471c zipl: Make address/size/mask macros UL
While at it also fix some white space damages.

Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-12-12 18:04:32 +01:00
Philipp Rudo
b2ae5a91ac zipl/sclp: Remove duplicate macros
Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-12-12 18:04:32 +01:00
Philipp Rudo
edfb6a03d8 zipl/stage3: Mark start_kernel __noreturn
Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-12-12 18:04:32 +01:00
Philipp Rudo
5eace91ee7 zipl: Define __noinline macro and make use of it
Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-12-12 18:04:32 +01:00
Philipp Rudo
86856f98db zipl: Make use of __noreturn macro
Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-12-12 18:04:32 +01:00
Philipp Rudo
154734efc7 zipl: define __section macro and make use of it
Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-12-12 18:04:32 +01:00
Philipp Rudo
c7fcb457b0 zfcpdump: Make use of __packed macro
Make use of the pre-defined __packed macro throughout zfcpdump.

Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-12-12 18:04:32 +01:00
Philipp Rudo
244bf4e550 zdump: Make use of __packed macro
Make use of the pre-defined __packed macro throughout zdump.

Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-12-12 18:04:32 +01:00
Philipp Rudo
0f7ed7d4fc zipl: Make use of __packed macro
Make use of the pre-defined __packed macro throughout zipl. This
requires adding the global include dir to ALL_CFLAGS.

Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-12-12 18:04:32 +01:00
Philipp Rudo
121d5d8013 zipl: Fix dependency generation in zipl/boot
When adding new header from zipl/include to a .c file within zipl/boot
a compiler error appears

	stage3.c:16:10: fatal error: zipl.h: No such file or directory
	 #include "zipl.h"
	          ^~~~~~~~
	compilation terminated.
	  CC      zipl/boot/stage3.o

This is because the rule to generate dependencies (*.o.d) does not use
the CFLAGS_BOOT. Thus it cannot find the header and fails. Note this
only applies to the dependency generation, the actual build succeeds.

To fix this rename the CFLAGS_BOOT to ALL_CFLAGS. Using ALL_CFLAGS
instead of e.g. ALL_CPPFLAGS is important to also overwrite flags given
on the commandline via OPT_FLAGS, e.g.

	make V=1 OPT_FLAGS="-D__FOO__"

While at it also remove the unused and wrong '-D__ASSEMBLY__'.

Fixes: 5a6605fe ("zipl: Ensure that boot loader CFLAGS are not overwritten")
Fixes: aa913b1e ("build process: Add automatic dependency generation")
Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-12-12 18:04:32 +01:00
Philipp Rudo
abe0ba7412 zipl: Fix entry point for stand-alone kdump
Currently zipl doesn't differentiate between the load address and the
entry point of an image, causing stage3 to strip away the entry point at
0x10000 for stand-alone kdump. This breaks the kdump kernel as it jumps
to 0x10000 after the special handling needed for kdump has been
performed.

Fix this by differentiating between the load address and the entry point
of an image.

Fixes: d142fbd5 ("zipl: Do not strip kernel image IPL header")
Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-12-12 18:04:32 +01:00
Marc Hartmayer
2227bb8330 zipl: remove some useless __packed___ attributes
The __packed__ attribute is not needed for these structures as they
don't need any padding to meet the size and alignment constraints
defined in the Linux for zSeries ABI.

Reported by GCC 9.2.1 when building with '-Waddress-of-packed-member'.

stage3.c: In function 'is_verified_address':
stage3.c:241:26: warning: taking address of packed member of 'struct ipl_rb_components' may result in an unaligned pointer value [-Waddress-of-packed-member]
  241 |  for_each_rb_entry(comp, comps) {
      |                          ^~~~~
stage3.c:18:15: note: in definition of macro 'for_each_rb_entry'
   18 |  for (entry = rb->entries; \
      |               ^~
  CC      zipl/boot/kdump3.o
  CC      zipl/boot/sclp_stage3.o
sclp_stage3.c: In function '__sclp_hsa_copy':
sclp_stage3.c:75:34: warning: converting a packed 'struct sdias_sccb' pointer (alignment 1) to a 'struct read_sccb' pointer (alignment 4096) may result in an unaligned pointer value [-Waddress-of-packed-member]
   75 |   if (sclp_hsa_copy_wait((struct read_sccb *)sccb))
      |                                  ^~~~~~~~~
In file included from sclp_stage3.c:13:
sclp_stage3.h:43:8: note: defined here
   43 | struct sdias_sccb {
      |        ^~~~~~~~~~
In file included from sclp_stage3.c:12:
sclp.h:149:8: note: defined here
  149 | struct read_sccb {
      |        ^~~~~~~~~
sclp_stage3.c: In function 'sclp_hsa_get_size':
sclp_stage3.c:126:34: warning: converting a packed 'struct sdias_sccb' pointer (alignment 1) to a 'struct read_sccb' pointer (alignment 4096) may result in an unaligned pointer value [-Waddress-of-packed-member]
  126 |   if (sclp_hsa_copy_wait((struct read_sccb *)sccb))
      |                                  ^~~~~~~~~
In file included from sclp_stage3.c:13:
sclp_stage3.h:43:8: note: defined here
   43 | struct sdias_sccb {
      |        ^~~~~~~~~~
In file included from sclp_stage3.c:12:
sclp.h:149:8: note: defined here
  149 | struct read_sccb {
      |        ^~~~~~~~~

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-12-12 18:04:32 +01:00
Marc Hartmayer
aa09b29248 zipl: fix -Waddress-of-packed-member
Reported by GCC 9.2.1 when building with '-Waddress-of-packed-member'.

menu.c: In function 'menu_read':
menu.c:30:22: warning: taking address of packed member of 'struct boot_stage2_params' may result in an unaligned pointer value [-Waddress-of-packed-member]
   30 |  uint16_t *configs = __stage2_params.config;
      |                      ^~~~~~~~~~~~~~~
menu.c: In function 'menu_list':
menu.c:83:22: warning: taking address of packed member of 'struct boot_stage2_params' may result in an unaligned pointer value [-Waddress-of-packed-member]
   83 |  uint16_t *configs = __stage2_params.config;
      |                      ^~~~~~~~~~~~~~~
menu.c: In function 'menu':
menu.c:139:22: warning: taking address of packed member of 'struct boot_stage2_params' may result in an unaligned pointer value [-Waddress-of-packed-member]
  139 |  uint16_t *configs = __stage2_params.config;
      |                      ^~~~~~~~~~~~~~~

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-12-12 18:04:32 +01:00
Marc Hartmayer
2790d4faaa zipl: fix -Wmaybe-uninitialized
Reported by GCC 9.2.1 when building with '-Wmaybe-uninitialized'.

job.c: In function 'job_get':
job.c:1817:14: warning: 'filename' may be used uninitialized in this function [-Wmaybe-uninitialized]
 1817 |  scan_size = scan_file(filename, &scan);
      |              ^~~~~~~~~~~~~~~~~~~~~~~~~~
job.c:1791:14: note: 'filename' was declared here
 1791 |  const char *filename;
      |              ^~~~~~~~

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-12-12 18:04:32 +01:00
Marc Hartmayer
bbc46edaf5 zipl: fix -Wdiscarded-qualifiers
Reported by GCC 9.2.1 when building with '-Wdiscarded-qualifiers'.

job.c: In function 'get_job_from_config_file':
job.c:1810:14: warning: assignment discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-12-12 18:04:32 +01:00
Jan Höppner
e5c0fb249b ziomon: Move dependency check for blktrace
When calling ziomon --version (or --help) the tool already checks
whether blktrace is present and prevents any output for those command
options when it isn't. This is unnecessary as no actual command is
issued during the parameter check and all other dependencies are checked
at a later point as well.

Move the dependency check to ensure a working --version and --help
option at any time.

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-12-12 18:04:32 +01:00
Jan Höppner
b6d8e5833c libdasd: Use DASD_BUS_ID_SIZE
Use the define instead of an hardcoded number.

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-12-12 18:04:32 +01:00
Tuan Hoang
d71628326d zipl: add value of target= as search path for BLS case
In the BLS files, the 'linux' and 'initrd' fields are relative to the
$BOOT directory. If $BOOT is a mount point of boot partition, 'linux'
and 'initrd' fields are relative to boot partition. If not, the paths
are relative to $BOOT directory of root partition.

zipl always starts searching at / regardless of partitions and mount
points.

This commit extends the semantics of target= field in zipl.conf to make
it as a second search path, besides /, for those 2 BLS fields.

See issues #69 for more details.

Fixes: https://github.com/ibm-s390-tools/s390-tools/issues/69
Closes: https://github.com/ibm-s390-tools/s390-tools/pull/74
Signed-off-by: Tuan Hoang <tmhoang@linux.ibm.com>
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-10-17 16:35:01 +02:00
Javier Martinez Canillas
8bfe18e674 zipl: fix the scanned tokens array size calculation
The zipl config file (zipl.conf) and the BootLoaderSpec (BLS) fragments
in /boot/loader/entries define a set of tokens that are parsed by zipl.

These are stored in an array of tokens whose size is calculated to make
sure that there is enough memory allocated for all the scanned tokens.

But the size calculation logic was wrong, since it was checking if the
current size was enough to store a single token per BLS fragment, while
up to 4 tokens can be defined in a BLS file: a section heading and the
image, ramdisk and parameter keywords.

This led to zipl being killed by a SIGABRT signal when trying to parse
more tokens than the ones that could fit in the scanned tokens array:

Using config file '/etc/zipl.conf'
Using BLS config file '/boot/loader/entries/vmlinuz-9.conf'
Using BLS config file '/boot/loader/entries/vmlinuz-8.conf'
Using BLS config file '/boot/loader/entries/vmlinuz-7.conf'
Using BLS config file '/boot/loader/entries/vmlinuz-6.conf'
Using BLS config file '/boot/loader/entries/vmlinuz-5.conf'
Using BLS config file '/boot/loader/entries/vmlinuz-4.conf'
Using BLS config file '/boot/loader/entries/vmlinuz-3.conf'
Using BLS config file '/boot/loader/entries/vmlinuz-2.conf'
Using BLS config file '/boot/loader/entries/vmlinuz-1.conf'
Using BLS config file '/boot/loader/entries/vmlinuz-0.conf'
double free or corruption (out)
Aborted (core dumped)

Fixes: https://github.com/ibm-s390-tools/s390-tools/issues/68
Closes: https://github.com/ibm-s390-tools/s390-tools/pull/73
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-10-17 16:35:01 +02:00
Tuan Hoang
275105fe3d zipl: allow check for other locations of zipl.conf
Allow zipl to find zipl.conf in following order:
/run/zipl/zipl.conf
/etc/zipl.conf
/lib/s390-tools/zipl.conf

Whichever is found first will be used.

Fixes: https://github.com/ibm-s390-tools/s390-tools/issues/70
Closes: https://github.com/ibm-s390-tools/s390-tools/pull/71
Signed-off-by: Tuan Hoang <tmhoang@linux.ibm.com>
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-10-17 16:35:01 +02:00
Tuan Hoang
19259aeb65 zipl: ship a minimal zipl.conf
Ship a minimal zipl configuration file at /lib/s390-tools/zipl.conf by
default which would help systems using BLS files, without having to
create the traditional /etc/zipl.conf file.

GitHub-ID: https://github.com/ibm-s390-tools/s390-tools/issues/70
GitHub-ID: https://github.com/ibm-s390-tools/s390-tools/pull/71
Signed-off-by: Tuan Hoang <tmhoang@linux.ibm.com>
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-10-17 16:35:01 +02:00
Julian Wiedmann
125df52887 dbginfo: collect qdisc statistics
This can be helpful in diagnosing network-related issues.

Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-10-17 16:35:01 +02:00
Julian Wiedmann
852fb9dfb8 dbginfo: collect extended network interface statistics
The basic statistics are already collected via ifconfig. But that tool
is deprecated, and provides no way of collecting the extended stats.
So also gather data from 'ip link'.

Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-10-17 16:35:01 +02:00
Jens Remus
b0fe75b92f zipl: remove duplicate statement
The duplicate statement does not have any effect. Therefore remove it.

Signed-off-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-10-17 16:35:01 +02:00
Ingo Franzki
bc987c8d18 zkey: Allow 'zkey-cryptsetup setkey' to set different key types
When a secure key has been converted from type CCA-AESDATA to type
CCA-AESCIPHER, the secure key stored in the LUKS2 header of a volume
encrypted with that key should also changed.

Command 'zkey-cryptsetup setkey' allows to set (replace) the volume
key in the LUKS2 header. It now accepts keys to be set that have
a different size of the original volume keys. CCA-AESCIPHER keys
are larger than CCA-AESDATA keys.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-18 12:55:17 +02:00
Ingo Franzki
a86e41a518 zkey: Add 'convert' command to convert keys from one type to another
Add a new 'convert' command. It allows to convert a secure key from
one key type to another. Currently only keys of type CCA-AESDATA can be
converted to CCA-AESCIPHER.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-18 12:55:17 +02:00
Ingo Franzki
0d9e42264d zkey: Add key checks when importing a CCA-AESCIPHER key
Perform extended checks on a secure key that is imported into
the key repository. Warn the user if the imported key is by
any means insecure, e.g. has been originally created in an
insecure way. Prompt the user to continue the import if a
potential insecurity is detected.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-18 12:55:17 +02:00
Ingo Franzki
7fede7021e zkey: Add helper function to check an AES CIPHER key
The helper function performs a deep check of the AES CIPHER key
token and checks for any potentially insecure attributes.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-18 12:55:17 +02:00
Ingo Franzki
e7d79d5c5c zkey: Add helper function to restrict export of secure keys
Secure keys of type CCA-AESCIPHER can be export restricted, so that
these keys can not be exported by another key.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-18 12:55:17 +02:00
Ingo Franzki
7d4b1e18b6 zkey: Add helper function to convert secure keys between key types
Add a helper function to convert a secure key from key type
CCA-AESDATA to CCA-AESCIPHER.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-18 12:55:17 +02:00
Ingo Franzki
b0cc0e4737 zkey: Add helper function to query the CCA firmware version
Some future functions are dependent on the firmware version of the
CCA crypto adapter. This helper function allows to query the version
of the currently selected CCA adapter.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-18 12:55:17 +02:00
Ingo Franzki
b7bb90c552 zkey: Check crypto card level during APQN cross checking
Secure keys of type CCA-AESCIPHER require a CEX6C or newer crypto
card. Also check for the minimum required card level during cross
checking of APQNs. Also display the card level in the APQN report.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-18 12:55:17 +02:00
Ingo Franzki
560b672bfa zkey: Add support for re-enciphering AES CIPHER keys
For secure keys of type CCA-AESCIPHER the CCA verb CSNBKTC2
(Key Token Change2) is used. CCA-AESDATA keys will continue
to use CCA verb CSNBKTC (Key Token Change).

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-18 12:55:17 +02:00
Ingo Franzki
0fab6bdf2a zkey: Add support for validating AES CIPHER keys
Add support for validating secure keys using the new pkey
IOCTLs. This allows to validate secure keys of type CCA-AESDATA
as well as CCA-AESCIPHER.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-18 12:55:17 +02:00
Ingo Franzki
b56c74fe7b zkey: Add support for generating AES CIPHER keys
Add support for generating secure keys using the new pkey
IOCTLs. This allows to generate secure keys of type CCA-AESDATA
as well as CCA-AESCIPHER, either by random inside the crypto
card, or from a given clear key.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-18 12:55:17 +02:00
Ingo Franzki
663d362ff3 zkey: Add helper functions to build lists of APQNs
The new IOCTLs are based on list of APQNs that they try to send
the request to. Add some helper functions to build such lists
of APQNs based on the key type, and optionally a given mkvp.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-18 12:55:17 +02:00
Ingo Franzki
d4027e6506 zkey: Add wrappers for the new IOCTLs with fallback to the old once
By default the new pkey IOCTL are used. In case the pkey device does not
support the new IOCTLs (i.e. errno ENOTTY is returned), then the wrapper
falls back to the old IOCTLs. The old IOCTLs only support secure keys of
type CCA-AESDATA.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-18 12:55:17 +02:00
Ingo Franzki
ddde3f354f zkey: Introduce the CCA-AESCIPHER key type
Add definitions and helper functions to support the new
CCA-AESCIPHER key type. Also enhance existing helper functions
to support CCA-AESCIPHER keys.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-18 12:55:17 +02:00
Ingo Franzki
298fab68fe zkey: Preparations for introducing a new key type
Introduce helper functions and definitions to allow key type
independent code in the keystore implementation

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-18 12:55:17 +02:00
Ingo Franzki
b47007b8ac zkey: Allow to specify the key type with the generate command
The zkey generate command allows to specify the --key-type|-K
option to specify the key type. If not specified, then the
default is CCA-AESDATA.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-18 12:55:17 +02:00
Ingo Franzki
91c35543ca zkey: Allow to filter list output by key type
The zkey list command now accepts option --key-type|-K type
to filter the displayed keys by key type. If not specified,
then all key types are displayed.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-18 12:55:17 +02:00
Ingo Franzki
9de85f4295 zkey: Display key type with list and validate commands
For the 'zkey list', 'zkey validate' and 'zkey-cryptsetup validate'
commands, display the key type.

As of today there is only one possible key type (CCA-AESDATA),
but in the future there might be additional key types.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-18 12:55:17 +02:00
Ingo Franzki
e15e8a1bfa zcryptstats: Add support for CEX7
Add the CEX7 crypto card to the list of known crypto cards.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-18 12:55:17 +02:00
Harald Freudenberger
4fc0c3cfef zcrypt: CEX7S exploitation support
This patch adds CEX7S exploitation support to lszcrypt and chzcrypt.

Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-18 12:55:17 +02:00
Ingo Franzki
a0ed6709cf zkey-cryptsetup: Add --to-new and --from-old options
To allow better control about the secure AES volume key re-enciphering
with 'zkey-cryptsetup reencipher', add options '--to-new' and '--from-old'
to specify if a re-enciphering from CURRENT to NEW, or OLD to CURRENT master
key registers is to be performed. If these options are not specified, then
it is auto-detected, based on the master key that the secure key is currently
re-enciphered with.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-18 12:55:17 +02:00
Ingo Franzki
552a915465 zkey: Select CCA adapter when re-enciphering
When re-enciphering secure AES keys, select the correct APQN for used
with the CCA host library. Re-enciphering a secure key requires the use
of the CCA host library. The APQN is selected based on the master key
verification pattern obtained from the secure key to re-encipher.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-18 12:55:17 +02:00
Ingo Franzki
1091b0bf65 zkey: Add function to select a CCA adapter by mkvp
Add a utility function to select an APQN that is set up with
a specific master key for use with the CCA host library. The
selection is based on the master key verification pattern, which
is typically obtained from an existing secure AES key.

The function iterates over a set of APQNs to find one that is setup
with the desired master key in the CURRENT or OLD master key register,
and optionally has a new master key loaded. It then selects the found
APQN for use with the CCA host library.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-18 12:55:17 +02:00
Ingo Franzki
016a0a56fc zkey: Add function to select a specific CCA adapter
Some operations require the CCA host library to be used, such as
re-enciphering a secure key. The CCA host library uses a different
approach to select the APQN it operates with. To ensure that the
desired APQN is used for an operation, a utility function is added
to select a specific APQN for usage with the CCA host library.

The CCA host library allows to set environment variables to override
the default CCA APQN selection. The environment variables are inspected
during CCA host library initialization only. To select a specific
domain for CCA, the CSU_DEFAULT_DOMAIN environment variable is set,
and then the CCA host library is un-loaded and re-loaded again.
Furthermore, the 'Cryptographic Resource Allocate' verb of the CCA
host library is used together with the 'Cryptographic Facility Query
function' verb to iterate over the crypto cards known by the CCA host
library, and to identify the desired crypto card based on its serial
number. That way, a specific APQN can be selected for use with
subsequent CCA verbs.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-18 12:55:17 +02:00
Ingo Franzki
0b4cbf0041 zkey: Cross check APQNs when changing APQN associations
Perform a cross check of the APQNs when the APQN association of a
secure AES key in the key repository is changed. When adding new APQNs,
or associating a new set of APQNs to a secure key, then the APQNs are
cross checked. If all associated APQNs are removed, then all currently
available APQNs are cross checked. If a master key mismatch is detected,
then the change is rejected.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-18 12:55:17 +02:00
Ingo Franzki
d854aed4b8 zkey: Cross check APQNs when importing secure keys
Perform a cross check of the APQNs when an existing secure AES key is
imported into the key repository. When a set of APQNs are associated to
the imported secure key, these APQNs are cross checked. If no APQNs are
associated to imported secure key, then all currently available
APQNs are cross checked. If a master key mismatch is detected, then
the key import is rejected.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-18 12:55:17 +02:00
Ingo Franzki
7f8e31e861 zkey: Cross check APQNs when validating secure keys
Perform a cross check of the APQNs when a secure AES key is validated.
When a set of APQNs are associated to a secure key, these APQNs are
cross checked. If a secure key is validated outside of the key repository,
or no APQNs are associated to a secure key inside the key repository,
then all currently available APQNs are cross checked. If a master key
mismatch is detected, then an error message is issued.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-18 12:55:17 +02:00
Ingo Franzki
a5b58038a0 zkey: Cross check APQNs when generating secure keys
Perform a cross check of the APQNs when a new secure AES key is
generated. When a set of APQNs are associated to a new secure key,
these APQNs are cross checked. If a new secure key is generated
outside of the key repository, or no APQNs are associated to a secure
key generated inside the key repository, then all currently available
APQNs are cross checked. If a master key mismatch is detected, then
the key generation is rejected.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-18 12:55:17 +02:00
Ingo Franzki
c2244a5795 zkey: Display MKVP when validating a secure key
Display the master key verification pattern of a secure key while
'zkey validate' and 'zkey-cryptsetup validate'

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-18 12:55:17 +02:00
Ingo Franzki
ea7cc9ea60 zkey: Add function to obtain the mkvp of a secure key
A secure AES key token contains the master key verification pattern
of the master key it is encrypted with. Add a function to obtain the
master key verification pattern of a secure key token.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-18 12:55:17 +02:00
Ingo Franzki
b32c031474 zkey: Add function to cross check APQNs for valid master keys
Add a utility function to cross check the master keys of a set of
APQNs. It checks for valid master keys in the CURRENT and OLD
master key registers, as well as newly loaded master keys in the NEW
register. It issues information and warning messages for various
findings and also indicates improper master key setup to the caller.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-18 12:55:17 +02:00
Ingo Franzki
bfc3dd018c zkey: Add function to print the MKVPs of APQNs
Add a utility function to print the master key verification patterns
of a set of APQNs. This allows the user to visually check which
master keys are set on which APQNs.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-18 12:55:17 +02:00
Ingo Franzki
625b81130a zkey: add function to iterate over all available CCA APQNs
Add a utility function to iterate over all available APQNs of
type CCA-Coprocessor. This function is required for various
future enhancements.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-18 12:55:17 +02:00
Ingo Franzki
bf8872e94a zkey: Add utility function to get the mkvp of a crypto card
With recent changes in the zcrypt device driver, the master key verifi-
cation patterns of the AES master key of am APQN can be obtained by
reading the sysfs attribute 'mkvps' of an APQN device of type CCA-
Coprocessor. The sysfs attribute can be found under
'/sys/devices/ap/cardnn/nn.mmmm/', where nn specifies the card number
in hex, and mmmm specifies the domain number on hex.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-18 12:55:17 +02:00
Ingo Franzki
a84d1c5d58 zkey: Add utility function to get the serial number of a crypto card
With recent changes in the zcrypt device driver, the serial number of
a crypto card can be obtained by reading the sysfs attribute 'serialnr'
of a crypto card device of type CCA-Coprocessor. The sysfs attribute
can be found under '/sys/devices/ap/cardnn/', where nn specifies the
card number in hex.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-18 12:55:17 +02:00
Ingo Franzki
696e8458f0 zkey: Move utility functions into separate source file
As preparation for future changes, move a sysfs specific functions
into a separate source file (utils.c).

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-18 12:55:17 +02:00
Ingo Franzki
95c7258ea7 zkey: Separate and rework CCA host library loading
As preparation for future changes, rework the loading of the
CCA host library so that the exported symbols are not passed
individually to the functions that use it. Pass a structure
that contains all entry points of all loaded CCA functions
instead. This will make it easier to add further CCA functions
at a later time.

Also add a version query for the CCA host library since some
future functions might be dependent on the library version.

While at it, separate the CCA related functions and definitions,
and move them into a separate source file (cca.h/cca.h).

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-18 12:55:17 +02:00
Thomas Richter
21de913a5e cpumf/bin/cpumf_helper.in: Add IBM z15 machine name
Add IBM z15 as official machine name to lscpumf command
output.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Reviewed-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-18 12:55:17 +02:00
Sa Liu
7a2a96e8a3 dbginfo: add hyptop output for z/VM and LPAR.
Signed-off-by: Sa Liu <saliu@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-18 12:55:17 +02:00
Jan Höppner
7a569c7e33 Prepare for next release
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-06 14:13:49 +02:00
Jan Höppner
dc2ac0c916 New release s390-tools-2.11.0
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-06 14:13:09 +02:00
Stefan Haberland
367598b187 zipl: set correct secure IPL default value
Set secure IPL to auto as default value to match documented behavior.

Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-06 12:44:34 +02:00
Marc Hartmayer
c01bcfa73a Use TOOLS_SYSCONFDIR for the default zipl.conf path
Use the configurable sysconf path instead of a hard-coded path for the
default zipl location.

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-06 12:44:34 +02:00
Marc Hartmayer
fe457e2082 zipl: don't leak @script_file
...
==9448== 32 bytes in 1 blocks are definitely lost in loss record 1 of 3
==9448==    at 0x4831010: malloc (vg_replace_malloc.c:309)
==9448==    by 0x48E2205: __vasprintf_internal (vasprintf.c:71)
==9448==    by 0x1005061: misc_asprintf (misc.c:48)
==9448==    by 0x10131F3: disk_get_info (disk.c:239)
==9448==    by 0x1013C41: disk_get_info_from_file (disk.c:517)
==9448==    by 0x1011C87: bootmap_create (bootmap.c:1127)
==9448==    by 0x1004C73: main (zipl.c:192)
...

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-06 12:44:34 +02:00
Philipp Rudo
1d25112589 zipl: Fix error message printed with --dumptofs
The option --dump does not exist. Adjust it to --dumpto.

Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-06 12:44:34 +02:00
Marc Hartmayer
27a8c4434c zipl: fix freeing of uninitialized pointer
Not in every case ppn_cmd is initialized. Therefore, set it explicitly
to NULL.

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-06 12:44:34 +02:00
Ursula Braun
e6a3b18104 dbginfo.sh: add ethtool output
This patch adds ethtool commands for network interfaces.
Especially the offload settings are important.

Signed-off-by: Ursula Braun <ubraun@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-06 12:44:34 +02:00
Ursula Braun
36292cb166 dbginfo.sh: add lspci and smc output
This patch adds the base lspci command to list pci devices
and the smc_dbg command from the smc-tools package to show
SMC socket related information.

Signed-off-by: Ursula Braun <ubraun@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-06 12:44:34 +02:00
Peter Oberparleiter
49da03e2e7 zdev: Fix broken zfcp-lun udev rule check
zdev incorrectly reports an invalid udev rule for zfcp-lun type rules.
This is caused by a faulty check for an empty udev rule file. This
commit fixes the check to only report invalid rules when there was no
valid configuration directive found in a zfcp-lun type udev rule.

Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Reported-by: Steffen Maier <maier@linux.ibm.com>
Reported-by: Benjamin Block <bblock@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-06 12:44:34 +02:00
Ingo Franzki
139dff3525 zkey: Make confirmation prompts more user friendly
Show '[y/N]' on all user confirmation prompts to give the user a
hint what to reply. Also indicate that the operation was aborted
on a negative confirmation.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-06 12:44:34 +02:00
Ingo Franzki
94227b44d5 zkey: Store volume type property all uppercase
The volume type of a secure key is not really case sensitive,
but for better usability store and display it in uppercase always,
regardless in whatever case it was specified.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-09-06 12:44:34 +02:00
Stefan Haberland
a9f4ae2db3 zipl: fix zfcp dump image location
The zfcp dumper fails with the following error:

MLOPDM003I: Machine loader finished, moving data to final storage
	    location.

	    uncompression error
--- System halted

HCPGIR450W CP entered; disabled wait
PSW 00020001 80000000 00000000 DEADBEEF

The zipl command shows overlapping components when installing the dumper
to a zfcp disk:

zipl -d /dev/sda1
Building bootmap directly on partition '/dev/sda1'
Adding dump section
  kernel image......: /lib/s390-tools/zfcpdump/zfcpdump-image
  kernel parmline...: 'root=/dev/ram0 dump_mem=1 possible_cpus=1
  	 	      cgroup_disable=memory '
  component address:
    heap area.......: 0x00002000-0x00005fff
    stack area......: 0x0000f000-0x0000ffff
    internal loader.: 0x0000a000-0x0000dfff
    parameters......: 0x00009000-0x000091ff
    kernel image....: 0x00010000-0x005761ff
				     ^^^^^^
    parmline........: 0x00567000-0x005671ff
			  ^^^^^^
Preparing boot device: sda.
Done.

With the secure IPL patchset the offset of the kernel image has been
removed for the normal IPL case but it has not been removed for the dump
image which leads to the overlap of 0x10000.

Fix by removing the offset for the dump case.

Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Reviewd-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Tested-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-08-08 15:27:27 +02:00
Jan Höppner
15b7f9d83f lsdasd: Add support for thin-provisioned volumes
Make lsdasd aware of thinly provisioned (Extent Space Efficient (ESE))
DASD volumes.

The ESE information is added to the discipline output and the extended
output additionally lists information about logical capacity, allocated
space, and the extent size.

Output before:

Bus-ID     Status      Name      Device  Type  BlkSz  Size      Blocks
==============================================================================
0.0.95e0   alias                         ECKD
0.0.7eb4   active      dasda     94:0    ECKD  4096   7043MB    1803060
0.0.7eb7   active      dasdb     94:4    ECKD  4096   7043MB    1803060
0.0.95d0   active      dasdc     94:8    ECKD  4096   42259MB   10818360
0.0.95d1   n/f         dasdd     94:12   ECKD
0.0.95d4   n/f         dasde     94:16   ECKD
0.0.95d5   active      dasdh     94:28   ECKD  4096   831097MB  212761080

Output after:

Bus-ID    Status    Name      Device  Type         BlkSz  Size      Blocks
================================================================================
0.0.95e0  alias                       ECKD
0.0.7eb4  active    dasda     94:0    ECKD         4096   7043MB    1803060
0.0.7eb7  active    dasdb     94:4    ECKD         4096   7043MB    1803060
0.0.95d0  active    dasdc     94:8    ECKD (ESE)   4096   42259MB   10818360
0.0.95d1  n/f       dasdd     94:12   ECKD (ESE)
0.0.95d4  n/f       dasde     94:16   ECKD (ESE)
0.0.95d5  active    dasdh     94:28   ECKD (ESE)   4096   831097MB  212761080

Extended output before:

0.0.95d0/dasdc/94:8
  status:                               active
  type:                                 ECKD
  blksz:                                4096
  size:                                 42259MB
  blocks:                               10818360
  use_diag:                             0
  readonly:                             0
  eer_enabled:                          0
  erplog:                               0
  hpf:                                  1
  uid:                                  IBM.750000000ABT31.9500.d0
  paths_installed:                      38 39 3a 3b
  paths_in_use:                         38 39 3a 3b
  paths_non_preferred:
  paths_invalid_cabling:
  paths_cuir_quiesced:
  paths_invalid_hpf_characteristics:
  paths_error_threshold_exceeded:

Extended output after:

0.0.95d0/dasdc/94:8
  status:                               active
  type:                                 ECKD (ESE)
  blksz:                                4096
  size:                                 42259MB
  blocks:                               10818360
  extent_size:                          1113
  logical_capacity:                     60102
  space_allocated:                      18921
  use_diag:                             0
  readonly:                             0
  eer_enabled:                          0
  erplog:                               0
  hpf:                                  1
  uid:                                  IBM.750000000ABT31.9500.d0
  paths_installed:                      38 39 3a 3b
  paths_in_use:                         38 39 3a 3b
  paths_non_preferred:
  paths_invalid_cabling:
  paths_cuir_quiesced:
  paths_invalid_hpf_characteristics:
  paths_error_threshold_exceeded:

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-08-08 15:27:21 +02:00
Jan Höppner
214580a704 dasdfmt: Add support for thin-provisioned volumes
Make dasdfmt aware of thinly provisioned (Extent Space Efficient (ESE))
DASD volumes.
If an ESE volume is recognised a QUICK format is performed, formatting
only the first two tracks. The mode can always be overwritten by --mode.

Previously allocated space is always released before formatting, if not
specified otherwise. The option --no-discard (-D) is provided to omit
the space release.

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-08-08 15:27:16 +02:00
Jan Höppner
96f13ead2b libdasd: Provide function to utilise release space ioctl
The BIODASDRAS (Release Allocated Space) ioctl allows to release
track-wise or full space of an Extent Space Efficient DASD volume.

Provide a library function to utilise this functionality.

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-08-08 15:27:09 +02:00
Jan Höppner
8023a72b11 libdasd: Provide function to read ese sysfs attribute
Provide a function to determine whether a DASD is an Extent Space
Efficient (ESE) volume.

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-08-08 15:27:03 +02:00
Jan Höppner
abc1875300 libdasd/dasdfmt: Move definitions to libdasd
Move definitions mostly used by IOCTLs to libdasd. Clean up unused and
old definitions while at it as well.

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-08-08 15:26:56 +02:00
Ingo Franzki
7d4c8c2781 zkey: Missing blank in command description
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-08-08 15:25:25 +02:00
Jan Höppner
f0afc6c89a Prepare for next release
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-08-08 15:25:25 +02:00
Jan Höppner
8565e591bd New release s390-tools-2.10.0
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-07-31 16:26:57 +02:00
Jan Höppner
80443ab629 fdasd: Fix exit status in error cases
In error cases, fdasd returns -1 which results in the return value 255.
This is due to the fact that only the low-order 8 bits are used for the
status value. See 2.13 Status Information [1] in the POSIX standard and
the exit() POSIX man page [2] for more details.

Instead of returning -1, use the EXIT_FAILURE constant to indicate
unsuccessful termination properly.

[1]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html
[2]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/exit.html

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-07-31 16:00:40 +02:00
Peter Oberparleiter
8b3cc6e4c1 zdev: Improve handling of invalid udev rules
Add basic checking when reading udev rules and print a warning when an
invalid udev rule file is found. This addresses the current inconsistent
behavior:

  - CCW devices: invalid udev rules are considered valid
  - CCW group devices: invalid udev rules are silently ignored
  - zFCP LUNs: invalid rules cause chzdev/lszdev to silently terminate
    with non-zero exit code

Checks include a test for empty or truncated rule files that might be
the result of an interrupted chzdev operation, or a file system or I/O
error.

Note: The recommended way to correct invalid udev rules is to either
remove the offending rules file, or to repeat the associated persistent
configuration step.

Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Reported-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-07-31 16:00:40 +02:00
Peter Oberparleiter
5693c16894 zdev: Add helper to report warnings only once
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-07-31 16:00:40 +02:00
Stefan Haberland
8bf5f8d0e2 zipl: do not overwrite BOOT_IMAGE entry
The zipl internal loader adds a variable BOOT_IMAGE= to the commandline
so that it is visible in the operating system which menu entry has been
chosen.

This entry was overwritten by the stage3 parameter page.

Fix by re-arranging the internal memory layout and putting the command
line extra param, which contains the BOOT_IMAGE entry, at 0xe000.
This location is available because less than  one page is used for the
stack.

Fixes: https://github.com/ibm-s390-tools/s390-tools/issues/67
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-07-31 15:59:50 +02:00
Ingo Franzki
99ab2db6ad zkey: Fix auto-detection of clear key bitsize for XTS keys
When 'zkey generate' is used with options '--clearkey <file>' and
'--xts', but without the '--keybits <bitsize>' option, then the
auto-detection of the bitsize of the specified clear key fails.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-07-31 15:59:50 +02:00
Ingo Franzki
784ac7d190 zcryptstats: Add note about loading kernel module chsc_sch
Dependent on kernel config option CHSC_SCH the device node /dev/chsc may
exist per default or not. In case the kernel is built with CHSC_SCH=M,
then the device driver is built as separate kernel module, and must
therefore be loaded using modprobe chsc_sch to make device node /dev/chsc
available.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-07-31 15:59:50 +02:00
Javier Martinez Canillas
53f166673d zipl: remove trailing spaces from the fields defined in BLS files
Currently the zipl tool doesn't remove trailing spaces from the BLS field
values. So for example if a 'title' field has trailing spaces and is used
as the default, zipl will complain that there's no section with that name:

Using config file '/etc/zipl.conf'
Using BLS config file '/boot/loader/entries/f871a0cf218348c5ba921f61c92b7eac-4.18.0-80.20.el8.s390x.conf'
Using BLS config file '/boot/loader/entries/f871a0cf218348c5ba921f61c92b7eac-0-rescue.conf'
Error: Config file '/etc/zipl.conf': Line 6: no such section 'Red Hat Enterprise Linux (4.18.0-80.20.el8.s390x) 8.1 (Ootpa)'

Since the trailing spaces are also removed from the fields defined in the
zipl.conf file, do the same for the ones that are defined in the BLS file.

Closes: https://github.com/ibm-s390-tools/s390-tools/pull/62
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Acked-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-07-18 16:21:17 +02:00
Dimitri John Ledkov
d4ea321a97 zipl/boot/Makefile: fix failure to build, do not specify .lds twice.
Whilst stage3.lds is a dependency, it is specified via SFLAGS and must
not be repeated again along all the .o files. Filter anything but .o
files.

Fixes failure to build from source on Ubuntu 19.10.

Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/s390-tools/+bug/1833238
Closes: https://github.com/ibm-s390-tools/s390-tools/pull/63
Signed-off-by: Dimitri John Ledkov <xnox@ubuntu.com>
Acked-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-07-18 15:02:06 +02:00
Dimitri John Ledkov
1a63894487 zipl/boot/Makefile: do not suppress echo in verbose builds.
By default, non-verbose builds don't echo the full command anyway. And
supressed echos in verbose builds make it harder to debug the build
failure.

GitHub-ID: https://github.com/ibm-s390-tools/s390-tools/pull/63
Signed-off-by: Dimitri John Ledkov <xnox@ubuntu.com>
Acked-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-07-18 15:02:06 +02:00
Stefan Haberland
e3fc9478bf zipl: secure IPL man page update
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-07-15 16:06:53 +02:00
Thomas Richter
f110a77b68 cpumf: Add support for CPU-Measurement Facility counters SVN 6
Add support for CPU-Measurement facility counter second version
number 6. This adds some more counters to the crypto counter set.
Extended counter set is the same as for z14.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-07-15 16:06:53 +02:00
Ingo Franzki
712433d7f9 util_opt: Correct util_opt_example to handle all possible options
The util_opt_example allows to specify '-l' and '-m, --manual' options,
but does not handle them. This leads to error message 'PANIC: The
application terminated due to an unrecoverable error' with 'Option 'l'
should not be handled here' and the program is aborted.

Add the required case statements in the switch to handle those options.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-07-15 16:06:53 +02:00
Fedor Loshakov
2c4c210ca8 zdev: add zfcp dix parameter handling
The zfcp kernel module was changed to introduce separate parameters for
selecting DIF and DIF&DIX. This commit implements the corresponding
changes in chzdev and lszdev.

Signed-off-by: Fedor Loshakov <loshakov@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-07-09 16:24:17 +02:00
Karsten Graul
58e2135d87 znetconf: show help and version without ccwgroup driver loaded
When directory $SYSFSDIR/bus/ccwgroup does not exist znetconf issues an
error message and terminates. Its not even possible to get the output of
--help or --version. Fix that by moving the responsible check behind the
parameter evaluation.

Signed-off-by: Karsten Graul <kgraul@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-07-09 16:24:17 +02:00
Ingo Franzki
5dbe73403f zkey: Fix option check for validate command
The validate command should allow to specify the --no-apqn-check
option even when --apqns is not specified.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-07-09 16:24:17 +02:00
Ingo Franzki
819513ab38 zkey: Fix misspelled option name in error messages
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-07-09 16:24:17 +02:00
Ingo Franzki
7e6d782699 zkey: Fix typo in function name
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-07-09 16:24:17 +02:00
Heiko Carstens
cc82be3135 zipl: add missing inline
please merge with previous commit.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-07-09 16:24:17 +02:00
Heiko Carstens
1b318fe114 zipl: fix stfle zero padding
The stfle inline assembly returns the number of double words written
(condition code 0) or the double words it would have written
(condition code 3), if the memory array it got as parameter would have
been large enough.

The current stfle implementation assumes that the array is always
large enough and clears those parts of the array that have not been
written to with a subsequent memset call.

If however the array is not large enough memset will get a negative
length parameter, which means that memset clears memory until it gets
an exception and the system crashes.

To fix this simply limit the maximum length. Move also the inline
assembly to an extra function to avoid clobbering of register 0, which
might happen because of the added MIN invocation together with code
instrumentation.

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-07-09 16:24:17 +02:00
Jens Remus
87f47f60e4 zdev: Add comment that zfcp LUNs do not support ranges
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-07-09 16:24:17 +02:00
Jens Remus
0f55dab2de zdev: Add missing includes
The header exit_code.h is required for the exit_code_t type and
the header misc.h for the err_t type.

Signed-off-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-07-09 16:24:17 +02:00
Jens Remus
b58adc26f4 zdev: Cleanup zfcp attribute help
Add missing punctuation, remove duplicate newline, and add missing
spacing.

Signed-off-by: Jens Remus <jremus@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-07-09 16:24:17 +02:00
Jens Remus
91509973fe zdev: Do not pass user input as format string
The function util_path_exists() consumes its first parameter as format
string. Passing the user input specified to the chzdev option --export
as-is to the function opens up the possibility for a format string
injection.

Fixes: d542138868 ("zdev: use libutil provided path functions")
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-07-09 16:24:17 +02:00
Jens Remus
39520546c5 chcp: Use macro S_ISDIR() to test type of file
Testing whether a file is a directory by comparing the struct stat
field st_mode against S_IFDIR is wrong. If st_mode has any access
permission bits set along with the file type code the test will always
fail.

The file type encoded in the struct stat field st_mode is actually an
enumeration. To test whether a file is a directory either extract the
file type from st_mode using the mask S_IFMT and compare it against
S_IFDIR or simply use the macro S_ISDIR().

Fixes: b627b8d8e1 ("Initial s390-tools-2.0.0 import")
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-07-09 16:24:17 +02:00
Jens Remus
8d1a7fecd0 zkey: Use libutil provided path functions
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
Acked-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-07-09 16:24:17 +02:00
Jens Remus
a6507b330d zkey: Use macro S_ISDIR() to test type of file
Testing whether a file is a directory by masking the struct stat field
st_mode with S_IFDIR is wrong. Depending on the values of the macros
S_IF* block special devices might be considered as directories.

The file type encoded in the struct stat field st_mode is actually an
enumeration. To test whether a file is a directory either extract the
file type from st_mode using the mask S_IFMT and compare it against
S_IFDIR or simply use the macro S_ISDIR().

Fixes: c944f23d7e ("zkey: Add keystore implementation")
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
Acked-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-07-09 16:24:17 +02:00
Jens Remus
d37dc68693 util_path: Get rid of "? true : false"
The functions use the C99 _Bool type in form of the alias bool from
stdbool.h as return type. Scalars are implicitly converted to _Bool.
Values equal to zero to 0 (false). Nonzero values to 1 (true).
Therefore the explicit conversion using the ternary operator ?: with
true and false is not required.

Signed-off-by: Jens Remus <jremus@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-07-09 16:24:17 +02:00
Jens Remus
b0007fea98 util_path: Simplify logic and get rid of goto
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-07-09 16:24:17 +02:00
Jens Remus
1e248abd53 util_path: Use S_IS*() macros to test type of file
Testing whether a file is a directory or a regular file by masking the
struct stat field st_mode with S_IFDIR or S_IFREG is wrong. Depending
on the values of the macros S_IF* sockets and symbolic links might
erroneously be considered as regular files and block special files as
directories.

The file type encoded in the struct stat field st_mode is actually an
enumeration. To test whether a file is a directory or a regular file
either extract the file type from st_mode using the mask S_IFMT and
compare it against S_IFDIR or S_IFREG or simply use the macros S_ISDIR()
and S_ISREG().

Fixes: b627b8d8e1 ("Initial s390-tools-2.0.0 import")
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-07-09 16:24:17 +02:00
Jens Remus
61baa23e48 zdev: Fix reporting of read-only sysfs attributes
Since commit d542138868 ("zdev: use libutil provided path functions")
lszdev fails to correctly report most read-only sysfs attributes as such
in its detailed information output (options -i or -ii). This is because
the libutil function util_path_is_writable() is not equivalent to the
former function file_writable().
util_path_is_writable() always returns true (the underlying function
access() indicates the file is writable), if the path exists and the user
is root, regardless of the path's effective access permissions. This is
correct for most use cases, as root can effectively read/write any path
regardless of its effective access permissions). util_path_is_writable()
behaves exactly like Bash -w in this regard.
The former function file_writable() examined the file's access permissions
to check if one or more of user, group, and other have write permission.

For lszdev it is irrelevant whether a file is effectively writable by
the current user. Instead it needs to determine whether sysfs attributes
access permissions contain write access in any form. If not it lists
those sysfs attributes in a separate read-only section.

Use the new function util_path_is_readonly_file(), which does explicitly
check the file's effective read and write access permissions. It behaves
similar to the former function file_writable(), except that it does test
whether any of user, group, and other have read permission.

Fixes: d542138868 ("zdev: use libutil provided path functions")
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-07-09 16:24:17 +02:00
Jens Remus
261763f133 util_path_example: Add example for util_path_is_{read|write}only_file() functions
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-07-09 16:24:17 +02:00
Jens Remus
f4b2da6c9d util_path: Add functions to test path is read/write-only
For root the functions util_path_is_readable() and util_path_is_writable()
do not take the path's permissions into account. The function access()
succeeds as root is allowed to read/write any file regardless of its
permissions.

Introduce the functions util_path_is_readonly_file() and
util_path_is_writeonly_file() to test whether a path is a regular file and
is either read-only (neither user, group, nor other have write permission,
but one or more of user, group, and other have read permission) or
write-only (neither user, group, nor other have read permission, but one
or more of user, group, and other have write permission).

Signed-off-by: Jens Remus <jremus@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-07-09 16:24:17 +02:00
Jan Höppner
1f607fed3d Prepare for next release
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-07-09 16:24:17 +02:00
Jan Höppner
bf9fd47918 New release s390-tools-2.9.0
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-05-21 15:13:36 +02:00
Jan Höppner
5aec1dc2a1 cpuplugd: Always free file pointer
The file pointer in the functions is_online() and cpu_is_configured() is
only freed in the good case. Make sure it is always freed.

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-05-21 14:17:40 +02:00
Jan Höppner
cf730a9632 zipl: Fix compile warning
bootmap.c: In function ‘check_secure_boot_support’:
bootmap.c:131:2: warning: ignoring return value of ‘fscanf’, declared
with attribute warn_unused_result [-Wunused-result]
  fscanf(fp, "%d", &val);
  ^~~~~~~~~~~~~~~~~~~~~~

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-05-21 14:17:40 +02:00
Jan Höppner
73bab8e1a1 zpcictl: Fix compile warning
zpcictl.c: In function ‘sysfs_read_value’:
zpcictl.c:154:2: warning: ignoring return value of ‘fscanf’, declared with
attribute warn_unused_result [-Wunused-result]
  fscanf(fp, "%x", &val);
  ^~~~~~~~~~~~~~~~~~~~~~

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-05-21 14:17:40 +02:00
Ingo Franzki
f97d048643 zkey: Allow to associate non-existing APQNs with a key
Add option --no-apqn-check to the generate, import, change, and
validate commands to disable checking of the specified APQNs.

With this option a currently non-existing APQN can be associated
with a key. This is useful to associate APQNs that exist only on
other systems, such as disaster recovery systems, but not on the
current system. When generating keys, at least one of the specified
APQNs must be available to generate the key.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-05-21 14:16:53 +02:00
Steffen Maier
d8c630e5f4 zfcpdbf: warn about ambiguous payload records with dup reqid & payarea
Function get_payload_records() reading from disk, blindly adds payload
record (junks) to a list in a 2-stage hierarchical hash keyed with
request ID and PAY area.

On adapter offline/online, zfcp resets the request ID to re-start with 1.
Hence it's not a unique foreign key in the lifetime of the PAY area.

The last payload record (junks) read for the same request ID and PAY area
is the one printed as named PAY field in the tool output.
This is not necessarily the chronologically last record due to PAY area
wrapping.

With this workaround, we:
* warn on reading PAY records if ambiguous entries occurred,
* print additional PAY timestamps which the user can compare
  with the actual trace record timestamps to determine if they are close
  enough to indicate a match.

We only found this by accident because we kept "short" "payload" being a
built-in part of some actual trace record types in areas HBA, SAN, SCSI.
For above cases, the full PAYload did not match the
built-in "short" "payload".

While at it, also add a comment that PAY output can also be wrong
in another case when junks of multi-part PAY records are missing due
to PAY area wrapping.

Below is an abbreviated example output with this workaround:

Loading trace records ...(this might take a while)
Warning: Ambiguous PAYload records. reqid:0000000000000037 area:san_res

...

Timestamp      : 2017-07-07-18:01:34:574827
Area           : SAN
...
Tag            : fssct_1
Request ID     : 0x0000000000000037
Destination ID : 0x00fffffc
SAN req short  : 01000000 fc020000 01720ffc 00000000
                 00000008
SAN req length : 20

Timestamp      : 2017-07-07-18:01:34:619310         ------------------+
Area           : SAN                                                  |
...                                                                   |
Tag            : fsscth2                                              |
Request ID     : 0x0000000000000037                                   |
Destination ID : 0x00fffffc                                           |
SAN resp short : 01000000 fc020000 80020000 00000000                  |
                 00671a07 00000000 c05076ff d6801850                  |
                 00671a7e 00000000 c05076ff d6801968                  |
SAN resp length: 16384                                                |
Payload time   : 2017-07-07-18:16:17:165708          <== does not match
San resp info  : 01000000 fc020000 80020000 00000000 <== wrong
                 4a49424d 20202020 20323936 34202020 <== wrong
                 20202020 20202020 20303230 30303030 <== wrong
                 30303745 43383720 20504348 49443a20 <== wrong
                 30313938 204e5049 5620556c 7049643a <== wrong
                 20303536 30303330 30202020 00000000 <== wrong
                 00000000 00000000 00000000 00000000 <== wrong
                 ...                                 <== wrong

...

Timestamp      : 2017-07-07-18:16:17:165713
Area           : SAN
...
Tag            : fsscth2
Request ID     : 0x0000000000000037             <== same reqid & pay "area"
Destination ID : 0x00fffffc
SAN resp short : 01000000 fc020000 80020000 00000000
                 4a49424d 20202020 20323936 34202020
                 20202020 20202020 20303230 30303030
SAN resp length: 273
Payload time   : 2017-07-07-18:16:17:165708          <== 2nd & last, match
                                                         close to Timestamp
San resp info  : 01000000 fc020000 80020000 00000000
                 4a49424d 20202020 20323936 34202020
                 20202020 20202020 20303230 30303030
                 30303745 43383720 20504348 49443a20
                 30313938 204e5049 5620556c 7049643a
                 20303536 30303330 30202020 00000000
                 00000000 00000000 00000000 00000000
                 ...

Signed-off-by: Steffen Maier <maier@linux.vnet.ibm.com>
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-05-21 14:16:53 +02:00
Heiko Carstens
45132ce1ee libutil: fix build breakage
/usr/bin/ld: ../..//libutil/libutil.a(util_sys.o): in function `util_sys_get_dev_addr':
/home/builder/s390-tools/libutil/util_sys.c:52: undefined reference to `major'
/usr/bin/ld: /home/builder/s390-tools/libutil/util_sys.c:53: undefined reference to `minor'
collect2: error: ld returned 1 exit status
make[2]: *** [../../common.mak:243: zipl] Error 1
make[1]: *** [Makefile:8: all] Error 2
make: *** [Makefile:52: zipl] Error 2

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-05-21 14:16:53 +02:00
Jan Höppner
57a797350c libu2s: Remove the library
There are no users of libu2s anymore. Remove it.

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-05-21 14:16:53 +02:00
Jan Höppner
75e3afb6a0 libdasd: Move get_host_access_count() to libdasd
Reading DASD specific sysfs attributes should be collected in one
library. Move get_host_access_count() to libdasd/dasd_sys.

Remove the old implementation and update any user accordingly.
Also, fix the build order for zdsfs.

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-05-21 14:16:53 +02:00
Jan Höppner
7915c9257b zpcictl: Use libutil to identify the slot id of a device
Rather than using an own implementation, use util_sys_get_dev_addr()
provided by libutil instead.

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-05-21 14:16:53 +02:00
Jan Höppner
6014d07cb1 dasdview/libdasd/zipl: Use util_sys_get_dev_addr() instead of u2s_getbusid()
Use the newer and more robust libutil provided function
util_sys_get_dev_addr() to identify a device address for any former user
of u2s_getbusid().

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-05-21 14:16:53 +02:00
Jan Höppner
5d2ebe5301 libutil: Introduce util_sys and util_sys_get_dev_addr()
Many tools need to identify the device address of a given device. So
far, either the tool had its own implementation, or u2s_getbusid() was
used. Though, u2s_getbusid() was mainly designed for and used by the
DASD tools.

Introduce util_sys with a first function util_sys_get_dev_addr() which
provides a more universal way to identify the device address which is
not limited to one particular device type. The device address represents
either a busid (e.g. DASD), slot address (NVMe), H:C:T:L tuple (SCSI),
or other id types associated with a device.

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-05-21 14:16:53 +02:00
Jan Höppner
ab510cff39 libdasd: Provide definition for bus id size
dasdview and libdasd deal with DASD bus ids and should use a definition
for the size. libu2s already provides a definition, which is used by
dasdview. However, the size of 32 is a bit much and the definition
should be part of libdasd.

Including the terminating null byte ('\0') and considering a DASD bus id
length of 8 characters (e.g. 0.0.4711), this leads to a size of 9.

Provide such a definition via libdasd and update any user.

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-05-21 14:16:53 +02:00
Jan Höppner
8c06dea4e5 libdasd: Use util_path_sysfs() to construct sysfs paths
Don't rely on rather arbitrary values for the string buffer size of
different sysfs paths. Instead use util_path_sysfs(), which allocates
the exact amount of memory necessary for a certain path string.

As these path strings are dynamically constructed, potential buffer
overflows can hereby be avoided and make the library functions more
robust.

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-05-21 14:16:53 +02:00
Dan Horák
0efacac5b8 zipl: update stage3 objcopy command for gcc9
The objcopy command for stage3.bin needs to take the new rodata section
into account.
See also PR https://github.com/ibm-s390-tools/s390-tools/pull/60.

Closes: https://github.com/ibm-s390-tools/s390-tools/pull/61
Signed-off-by: Dan Horák <dan@danny.cz>
Acked-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-05-21 14:16:53 +02:00
Stefan Haberland
6ea645b345 zipl: add secure boot man page updates
Add zipl and zipl.conf man page updates.

The zipl man page will look like:

       -S <SWITCH> or --secure <SWITCH>
               Control the zIPL secure boot support.  <SWITCH> can take one of three values:

                 auto (default)
                   Write signatures if available and supported by the system.
                 1
                   Signatures are written independent of support indicated by the local
                   system. Also missing signatures for stage 3 and kernel IPL files
                   will result in an error.
                 0
                   No signatures will be written.

The zipl.conf man page will look like:

       secure = auto/1/0 (configuration only)

              Configuration section:
              Control the zIPL secure boot support.  Set this option to one of the following:

                -  auto: Write signatures if available and supported by the system.

                -  1: Signatures are written independent of support indicated by the local system.
		   Also missing signatures for stage 3 and kernel IPL files will result in an error.

                -  0: No signatures will be written.

                   The default value for 'secure' is auto.

Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Acked-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-04-29 17:17:48 +02:00
Stefan Haberland
331b54d573 zipl: secure boot - verify load address
To ensure that only verified code is executed the stage 3 loader has
to check if the load psw points to an address that has previously been
verified by the machine loader.

If secure boot is enabled the IPL process will only continue if the
verification was successful.

Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Acked-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-04-29 17:17:45 +02:00
Stefan Haberland
7e7a77675d zipl: re-order variable declaration
For better readbility re-arrange the variable declaration.

Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Acked-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-04-29 17:17:42 +02:00
Stefan Haberland
dc2e439550 zipl: add dummy section for stage3 heap and stack
The firmware needs to know which memory locations are used by
the stage 3 loader so that it can allocate its own memory.
To indicate the usage of the heap and stack area of the stage 3 loader
add a dummy component to block this memory area for the firmware.

Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Acked-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-04-29 17:17:40 +02:00
Stefan Haberland
75d4317f20 zipl: pad stage3 binary
The stage 3 loader size has to be a multiple of the filesystem
blocksize so that the signature maps with the later in memory
stage 3 loader. The lowest common blocksize is 4k so the image
is padded to a 4k boundary.

Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Acked-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-04-29 17:17:37 +02:00
Stefan Haberland
58a7462f65 zipl: add secure boot switch
Add a command line option and configuration section keyword to control
the zIPL secure boot support. This option is named "secure" and can take
one of three values:

  auto (default)
    Write signatures if available and supported by the system.
  1
    Signatures are written independent of support indicated by the local
    system. Also missing signatures for stage 3 and kernel IPL files
    will result in an error.
  0
    No signatures will be written.

Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-04-29 17:17:33 +02:00
Stefan Haberland
7c7e10ed8f zipl: detect signed files and create bootmap components
Add support for parsing IPL file signatures as produced by the Linux
kernel's sign-file tool. When preparing a disk for IPL, the signatures
will be added as separate data components that can be used by the Secure
Boot firmware feature to validate the integrity of the IPL files.

Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-04-29 17:17:30 +02:00
Stefan Haberland
0c1a63ce5e zipl: dynamically build component name array
Change the fixed component entry text array to a more dynamic approach
to allow easier extension and make the order changeable.

Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-04-29 17:17:25 +02:00
Stefan Haberland
6825645a21 zipl: Move stage 3 loader to external file
The first component that gets control after IPL is the zIPL-provided
stage 3 boot loader. This boot loader is based on a binary image linked
into the zIPL executable. When preparing a disk for IPL, zIPL updates
runtime parameters in the boot loader image and writes the resulting
data to disk.

To support the Secure Boot firmware feature, the stage 3 code must be
signed, and can therefore no longer contain variable parameter portions.
Also the boot loader image should be accessible as a separate file to
enable the use of external programs for creating the signature.

This patch moves the stage 3 boot loader code to an external file
location and splits out the parameter portion into a separate, unsigned
on-disk component.

The new memory layout of the stage 3 loader during its execution looks
as follows:

 * 0x0000-0x1fff        Lowcore
 * 0x2000-0x5fff        Memory allocation (heap)
 * 0x7000-0x8fff        free
 * 0x9000-0x9fff        Stage3 parameter
 * 0xa000-0xcfff        Stage3 code
 * 0xd000-0xefff        Section: bss, rodata, data
 * 0xf000-0xffff        Stack

Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-04-29 17:17:21 +02:00
Stefan Haberland
e764f460c4 zipl: Do not strip kernel image IPL header
The binary Linux kernel image is built to be loaded to memory address
0x0 but the first 64 kbyte contain an IPL header that is not used for
disk IPL. zIPL strips away this IPL header when writing IPL records to
disk, loads the remaining data to memory address 0x10000 and uses the
memory area below that for its own boot loader code.

The Secure Boot firmware feature checks the integrity of an installed
image during IPL using a checksum that was generated for the full image.
Since the checksum becomes invalid if the IPL header is removed, zIPL
must be changed to write the full image to disk.

This patch modifies the zIPL logic to no longer strip away the IPL
header. Instead the full image is loaded to a higher memory address and
relocated by the stage 3 boot loader code to its final location.

Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-04-29 17:17:16 +02:00
Jan Höppner
63089835b0 README.md: Add runtime requirement for dbginfo.sh
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-04-29 17:17:16 +02:00
Ingo Franzki
e4cd42900f zkey: Fix a problem with changing a volume association of a key
When a 'zkey change' command is used to change (i.e. set) the volume
association of a key, and the new volume association contains a volume
that is already assigned to the key to be changed, the command fails
with an error that the volume is already associated to the key.

This commit fixes the problems and allows to set such a volume
association. When setting a new association the current association of
the key to be changed is of no relevance, since the set operation
replaces the current association with the new association.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-04-15 15:17:55 +02:00
Stefan Raspl
7f033938b8 lschp: add support for specifying a CHPID
We keep things simple and allow for only a single CHPID to be specified.

Signed-off-by: Stefan Raspl <raspl@linux.ibm.com>
Reviewed-by: Sebastian Ott <sebott@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-04-15 15:16:25 +02:00
Fedor Loshakov
f2dee9f542 ziomon: fix utilization data recording with multi-digit scsi hosts
s390-tools-1.9.0 introduced a new way of recognizing of multipath
device paths with using of sed command invocation in ziomon script.
With this new way of recognizing, if there are paths, related to
multipath device, with SCSI host ID longer, than one digit,
ziomon incorrectly parses the multipath -l command output. It
erroneously cuts off all but the least significant digit of the
SCSI host ID (H) of paths in H:B:T:L format (Host:Bus:Target:Lun).
This leads to passing of hosts (-a) and paths (-l) with
non-existing SCSI host ID to ziomon_util. In turn ziomon_util
cannot recognize hosts with non-existing SCSI host ID and issues
an error.

Also, wrong sed command invocation could lead to receiving of
duplicate LUNs by ziomon after parsing of multipath -l command
output. Then ziomon excludes duplicates from WRP_LUNS, which
leads to mismatch between number of LUNs and number of detected
block devices and issues ziomon script error, without starting
ziomon_util and without writing to specified log file.

The regular expression to match a path in H:B:T:L format started
with a greedy ".*", which erroneously consumed parts of the SCSI
host ID (H). This patch replaces the greedy ".*" by "[^0-9]*",
so that sed command does not consume parts of the SCSI host ID
any more.

Test example with unique SCSI host IDs:
$ multipath -l
...
mpathc (36005076307ffc5e300000000000083f5) dm-2 IBM     ,2107900
size=20G features='1 queue_if_no_path' hwhandler='0' wp=rw
`-+- policy='service-time 0' prio=0 status=active
  |- 10:0:0:1089814659 sdb 8:16  active undef running
  `- 11:0:0:1089814659 sdf 8:80  active undef running
...

Behavior without fix applied:
$ ziomon -d 5 -o log /dev/mapper/mpathc
Check devices...done
NOTE: No size limit specified, run without a limit.
Estimated maximum disk space required for log data: approx. <1 MBytes
Collecting configuration data...done
Start data collection processes...ziomon_util: Path does not exist: /sys/class/scsi_host/host0/utilization - correct kernel version?
ziomon_util: Path does not exist: /sys/class/scsi_host/host0/utilization - correct kernel version?
ziomon_util: Path does not exist: /sys/class/scsi_host/host0/queue_full - correct kernel version?
ziomon_util: Path does not exist: /sys/class/scsi_host/host1/utilization - correct kernel version?
ziomon_util: Path does not exist: /sys/class/scsi_host/host1/queue_full - correct kernel version?
failed
ziomon: Failed to determine ziomon_util pid
Shutting down
Shutting down blktrace process
Shutting down blkiomon process
Shutting down ziomon_zfcpdd process
blkiomon: terminated by signal
Shutting down data manager

User can see more information, when using ziomon with -V option:
...
=== WRP_LUNS         : 0:0:0:1089814659 1:0:0:1089814659
=== WRP_HOST_ADAPTERS: host0 host1
...
=== starting ziomon_util: ziomon_util -V  -a 0 -a 1  -l 0:0:0:1089814659 -l 1:0:0:1089814659 ...
...

User can also see this type of errors, while using
ziorep_traffic or ziorep_utilization tools:
$ ziorep_traffic -t1 log.log
Extracting config data...done
ziorep_traffic: Could not retrieve initial data - data files corrupted or broken, or the .agg file is missing.

Behavior with fix applied:
$ ziomon -d 5 -o log /dev/mapper/mpathc
Check devices...done
NOTE: No size limit specified, run without a limit.
Estimated maximum disk space required for log data: approx. <1 MBytes
Collecting configuration data...done
Start data collection processes...done
Collecting data...done
Shutting down
Shutting down data manager

User can see more information, when using ziomon with -V option:
...
=== WRP_LUNS         : 10:0:0:1089814659 11:0:0:1089814659
=== WRP_HOST_ADAPTERS: host10 host11
...
=== starting ziomon_util: ziomon_util -V  -a 10 -a 11  -l 10:0:0:1089814659 -l 11:0:0:1089814659 ...
...

Test example with duplicate SCSI host IDs:
$ multipath -l
...
mpathc (36005076307ffc5e300000000000083f5) dm-1 IBM     ,2107900
size=20G features='1 queue_if_no_path' hwhandler='0' wp=rw
`-+- policy='service-time 0' prio=0 status=active
  |- 0:0:0:1089814659  sdb 8:16  active undef running
  `- 10:0:0:1089814659 sdf 8:80  active undef running
...

Behavior without fix applied:
$ ziomon -d 5 -o log /dev/mapper/mpathc
Check devices...done
ziomon: Number of LUNs does not match number of devices: 2 devices and 1 LUNs

User can see more information, when using ziomon with -V option:
...
    === #Devices total   : 2
    === WRP_DEVICES      : /dev/sdb /dev/sdf
    === WRP_LUNS         : 0:0:0:1089814659
    === WRP_HOST_ADAPTERS: host0
...

Behavior with fix applied:
$ ziomon -d 5 -o log /dev/mapper/mpathc
Check devices...done
NOTE: No size limit specified, run without a limit.
Estimated maximum disk space required for log data: approx. <1 MBytes
Collecting configuration data...done
Start data collection processes...done
Collecting data...done
Shutting down
Shutting down data manager

User can see more information, when using ziomon with -V option:
...
=== #Devices total   : 2
=== WRP_DEVICES      : /dev/sdb /dev/sdf
=== WRP_LUNS         : 0:0:0:1089814659 10:0:0:1089814659
=== WRP_HOST_ADAPTERS: host0 host10
...
=== starting ziomon_util: ziomon_util -V  -a 0 -a 10  -l 0:0:0:1089814659 -l 10:0:0:1089814659 ...
...

Signed-off-by: Fedor Loshakov <loshakov@linux.ibm.com>
Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-04-11 13:19:36 +02:00
Jan Höppner
c7a255fcd9 zpcictl: Check for regular directory
In case a regular directory was specified, rather than a device node,
the check if the device exists will pass. The following code paths then
assume a slot id was specified. This in turn may lead to a buffer
overflow when the device data is copied to to the zpci_device struct.

Check if the specified path is a regular directory and prevent a
possible later buffer overflow and copying wrong data respectively.

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-04-01 12:41:17 +02:00
Steffen Maier
be7b854969 lszfcp: also mark FCP devices (hosts) that are not available
Also mark FCP devices with CHPID that is logically varied off,
e.g. after running "chchp -v 0 60".
Such FCP devices can be online, not failed, and are not defunct,
so the other existing markers do not appear.

Shows potential issues with FCP devices at one glance.

Examples:

$ lszfcp -He
0.0.1900 host0 NotAvailable

$ lszfcp -HeV
/sys/devices/css0/0.0.010d/0.0.1900 NotAvailable
/sys/class/fc_host/host0
/sys/class/scsi_host/host0

Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Complements: 4036e80b26 ("lszfcp: add new output marker for non-good FCP devices (hosts)")
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-03-27 14:57:40 +01:00
Jan Höppner
05a0f8e0eb gitignore: Add zcryptstats
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-03-26 17:14:46 +01:00
Ingo Franzki
43fcb694bf zcryptstats: add new tool to readme
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-03-26 17:14:46 +01:00
Ingo Franzki
8be43a1f16 zcryptstats: Add man page
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-03-26 17:14:46 +01:00
Ingo Franzki
7b4a05e5a3 zcryptstats: Add new zcryptstats tool
The zcryptstats tool displays usage statistics of IBM Crypto Express
adapters. It obtains cryptographic performance measurement data
periodically and displays the data for each cryptographic device for
each interval. A cryptographic device can be either a card device or
a queue device (APQN).

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-03-26 17:14:46 +01:00
Steffen Maier
9911a95144 CHANGELOG: lszfcp: fix regressions
Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-03-26 17:14:46 +01:00
Steffen Maier
9c56255a70 lszfcp: new command line option to show module parameters
I often use "systool -v -m zfcp" but that's a bit longish to type
and contains more output than just the parameters I'm interested in.
"tail /sys/module/zfcp/parameters/*" is also not so nice.
"lszfcp -Z" makes it very easy and can be combined with the other
existing output options of lszfcp.

Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-03-26 17:14:46 +01:00
Steffen Maier
a20cabccc4 lszfcp: sdev attributes for scsi_disk, block, integrity, queue, iosched
Show if command line option for more attribute details specified twice
and depending on existence in sysfs (i.e. not for non-disk such as tape).

Abbreviated examples:

$ lszfcp -DVeamm
/sys/devices/css0/0.0.0019/0.0.1880/0x50050763031bd327/0x4045400300000000
/sys/bus/ccw/drivers/zfcp/0.0.1880/host2/rport-2:0-0/target2:0:0/2:0:0:1073954885
/sys/block/sdd /sys/class/scsi_generic/sg3
Class = "zfcp_unit"
    access_denied       = "0"
    access_readonly     = "0"
    access_shared       = "0"
    failed              = "0"
    in_recovery         = "0"
    status              = "0x54000000"
Class = "scsi_device"
    ...
    modalias            = "scsi:t-0x00"
    model               = "2107900"
    scsi_level          = "6"
    state               = "running"
    type                = "0"
    ...
    zfcp_access_denied  = "0"
    zfcp_failed         = "0"
    zfcp_in_recovery    = "0"
    zfcp_status         = "0x54000000"
Class = "scsi_disk"
    allow_restart       = "0"
    app_tag_own         = "1"
    cache_type          = "write back"
    FUA                 = "0"
    manage_start_stop   = "0"
    max_medium_access_timeouts = "2"
    max_write_same_blocks = "65535"
    protection_mode     = "dix1"
    protection_type     = "1"
    provisioning_mode   = "unmap"
    thin_provisioning   = "1"
    zeroing_mode        = "writesame"
Class = "block"
    alignment_offset    = "0"
    capability          = "50"
    dev                 = "8:48"
    discard_alignment   = "0"
    size                = "2097152"
    ...
    uevent              = "MAJOR=8"
Class = "block_integrity"
    device_is_integrity_capable = "1"
    format              = "T10-DIF-TYPE1-IP"
    protection_interval_bytes = "512"
    read_verify         = "1"
    tag_size            = "2"
    write_generate      = "1"
Class = "block_queue"
    add_random          = "1"
    chunk_sectors       = "0"
    dax                 = "0"
    discard_granularity = "1073741824"
    discard_max_bytes   = "4294966784"
    discard_max_hw_bytes = "4294966784"
    discard_zeroes_data = "0"
    hw_sector_size      = "512"
    io_poll             = "0"
    io_poll_delay       = "0"
    iostats             = "1"
    logical_block_size  = "512"
    max_discard_segments = "1"
    max_hw_sectors_kb   = "1076"
    max_integrity_segments = "269"
    max_sectors_kb      = "1076"
    max_segments        = "269"
    max_segment_size    = "4096"
    minimum_io_size     = "512"
    nomerges            = "0"
    nr_requests         = "128"
    optimal_io_size     = "0"
    physical_block_size = "512"
    read_ahead_kb       = "512"
    rotational          = "1"
    rq_affinity         = "1"
    scheduler           = "noop [deadline] cfq"
    write_cache         = "write back"
    write_same_max_bytes = "33553920"
    write_zeroes_max_bytes = "33553920"
    zoned               = "none"
Class = "block_queue_iosched"
    fifo_batch          = "16"
    front_merges        = "1"
    read_expire         = "500"
    write_expire        = "5000"
    writes_starved      = "2"

/sys/devices/css0/0.0.0222/0.0.3c80/0x2002000e1115c62f/0x0000000000000000
/sys/bus/ccw/drivers/zfcp/0.0.3c80/host4/rport-4:0-2/target4:0:2/4:0:2:0
Class = "zfcp_unit"
    access_denied       = "0"
    access_readonly     = "0"
    access_shared       = "0"
    failed              = "0"
    in_recovery         = "0"
    status              = "0x54000000"
Class = "scsi_device"
    ...
    modalias            = "scsi:t-0x01"
    model               = "ULT3580-TD6"
    scsi_level          = "7"
    state               = "running"
    type                = "1"
    ...
    zfcp_access_denied  = "0"
    zfcp_failed         = "0"
    zfcp_in_recovery    = "0"
    zfcp_status         = "0x54000000"

/sys/devices/css0/0.0.0222/0.0.3c80/0x2002000e1115c62f/0x0001000000000000
/sys/bus/ccw/drivers/zfcp/0.0.3c80/host4/rport-4:0-2/target4:0:2/4:0:2:1
Class = "zfcp_unit"
    access_denied       = "0"
    access_readonly     = "0"
    access_shared       = "0"
    failed              = "0"
    in_recovery         = "0"
    status              = "0x54000000"
Class = "scsi_device"
    ...
    modalias            = "scsi:t-0x08"
    model               = "3573-TL"
    scsi_level          = "6"
    state               = "running"
    type                = "8"
    ...
    zfcp_access_denied  = "0"
    zfcp_failed         = "0"
    zfcp_in_recovery    = "0"
    zfcp_status         = "0x54000000"

/sys/devices/css0/0.0.0222/0.0.3c80/0x500507630313d327/0xffffffffffffffff failed
-
Class = "zfcp_unit"
    access_denied       = "0"
    access_readonly     = "0"
    access_shared       = "0"
    failed              = "1"
    in_recovery         = "0"
    status              = "0x00000000"

Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-03-26 17:14:46 +01:00
Steffen Maier
f67758160e lszfcp: allow to show zfcp_units without associated SCSI device
Useful to detect configuration errors and FCP LUN typos.

Example:

$ lszfcp -De
0.0.3c80/0x500507630313d327/0xffffffffffffffff - failed

$ lszfcp -DeV
/sys/devices/css0/0.0.0222/0.0.3c80/0x500507630313d327/0xffffffffffffffff failed
-

$ lszfcp -Deam
0.0.3c80/0x500507630313d327/0xffffffffffffffff - failed
Class = "zfcp_unit"
    access_denied       = "0"
    access_readonly     = "0"
    access_shared       = "0"
    failed              = "1"
    in_recovery         = "0"
    status              = "0x00000000"

Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-03-26 17:14:46 +01:00
Steffen Maier
e84287e76e lszfcp: attribute details for: css, zfcp_port, zfcp_unit
Consistency with "lszfcp -Ha" which includes zfcp_adapter as class=ccw.
Attribute details are especially useful to show the driver-internal status.

For FCP devices (hosts), "css" shows subchannel details including CHPID.

Abbreviated examples:

$ lszfcp -PVeam -b 0.0.50c0 -p 0x500507680b2481fa
- (NoMoreZfcpPort:0.0.50c0/0x500507680b2481fa)
/sys/class/fc_remote_ports/rport-6:0-2 NotOnline
Class = "fc_remote_ports"
    dev_loss_tmo        = "60"
    fast_io_fail_tmo    = "off"
    maxframe_size       = "2048 bytes"
    node_name           = "0x500507680b0081fa"
    port_id             = "0x242200"
    port_name           = "0x500507680b2481fa"
    port_state          = "Blocked"
    roles               = "FCP Target"
    scsi_target_id      = "2"
    supported_classes   = "Class 2, Class 3"

$ lszfcp -HPDeam
0.0.1900 host0
Bus = "css"
    chpids              = "60 00 00 00 00 00 00 00"
    modalias            = "css:t0"
    pimpampom           = "80 80 ff"
    type                = "0"
    uevent              = "DRIVER=io_subchannel"
    vpm                 = "80"
Bus = "ccw"
    availability        = "good"
    ...
    failed              = "0"
    in_recovery         = "0"
    online              = "1"
    status              = "0x5400040b"
    ...
Class = "fc_host"
    ...
    port_state          = "Online"
    port_type           = "NPIV VPORT"
    ...
Class = "scsi_host"
    ...
    state               = "running"
    ...

0.0.1940 host8 offline
Bus = "css"
    chpids              = "61 00 00 00 00 00 00 00"
    modalias            = "css:t0"
    pimpampom           = "80 80 ff"
    type                = "0"
    uevent              = "DRIVER=io_subchannel"
    vpm                 = "80"
Bus = "ccw"
    availability        = "good"
    ...
    failed              = "0"
    in_recovery         = "0"
    online              = "0"
    status              = "0x00000401"
    ...
Class = "fc_host"
    ...
    port_state          = "Unknown"
    port_type           = "NPIV VPORT"
    ...
Class = "scsi_host"
    ...
    state               = "running"
    ...

0.0.5000 host1 offline
Bus = "css"
    chpids              = "67 00 00 00 00 00 00 00"
    modalias            = "css:t0"
    pimpampom           = "80 80 ff"
    type                = "0"
    uevent              = "DRIVER=io_subchannel"
    vpm                 = "80"
Bus = "ccw"
    availability        = "good"
    ...
    failed              = "0"
    in_recovery         = "0"
    online              = "0"
    status              = "0x00000401"
    uevent              = "DRIVER=zfcp"
    ...
Class = "fc_host"
    ...
    port_state          = "Unknown"
    port_type           = "NPort (fabric via point-to-point)"
    ...
Class = "scsi_host"
    ...
    state               = "running"
    ...

0.0.3c40 host7 defunct
Bus = "css"
    defunct
Bus = "ccw"
    availability        = "no device"
    ...
    failed              = "0"
    in_recovery         = "0"
    online              = "1"
    status              = "0x00000401"
    ...
Class = "fc_host"
    ...
    port_state          = "Unknown"
    port_type           = "NPIV VPORT"
    ...
Class = "scsi_host"
    ...
    state               = "running"
    ...

0.0.1880 - offline
Bus = "css"
    chpids              = "5a 00 00 00 00 00 00 00"
    modalias            = "css:t0"
    pimpampom           = "80 80 ff"
    type                = "0"
    uevent              = "DRIVER=io_subchannel"
    vpm                 = "00"
Bus = "ccw"
    availability        = "good"
    cmb_enable          = "0"
    cutype              = "1731/03"
    devtype             = "1732/03"
    modalias            = "ccw:t1731m03dt1732dm03"
    online              = "0"
    uevent              = "DRIVER=zfcp"

0.0.1900/0x500507630708c5e3 rport-0:0-0
Class = "zfcp_port"
    access_denied       = "0"
    failed              = "0"
    in_recovery         = "0"
    status              = "0x54000001"
Class = "fc_remote_ports"
    dev_loss_tmo        = "2147483647"
    fast_io_fail_tmo    = "5"
    maxframe_size       = "2112 bytes"
    node_name           = "0x5005076307ffc5e3"
    port_id             = "0x675c00"
    port_name           = "0x500507630708c5e3"
    port_state          = "Online"
    roles               = "FCP Target"
    scsi_target_id      = "0"
    supported_classes   = "Class 2, Class 3"

0.0.5000/0x500507680b2381fb rport-1:0-0 NotOnline
Class = "zfcp_port"
    access_denied       = "0"
    failed              = "0"
    in_recovery         = "0"
    status              = "0x00000001"
Class = "fc_remote_ports"
    dev_loss_tmo        = "2147483647"
    fast_io_fail_tmo    = "5"
    maxframe_size       = "2048 bytes"
    node_name           = "0x500507680b0081fb"
    port_id             = "0x24e200"
    port_name           = "0x500507680b2381fb"
    port_state          = "Blocked"
    roles               = "FCP Target"
    scsi_target_id      = "0"
    supported_classes   = "Class 2, Class 3"

0.0.5040/0x500507680b2281fa rport-2:0-0
Class = "zfcp_port"
    access_denied       = "0"
    failed              = "0"
    in_recovery         = "0"
    status              = "0x54000001"
Class = "fc_remote_ports"
    dev_loss_tmo        = "2147483647"
    fast_io_fail_tmo    = "5"
    maxframe_size       = "2048 bytes"
    node_name           = "0x500507680b0081fa"
    port_id             = "0x24a300"
    port_name           = "0x500507680b2281fa"
    port_state          = "Online"
    roles               = "FCP Target"
    scsi_target_id      = "0"
    supported_classes   = "Class 2, Class 3"

0.0.1940/0x500507630718c5e3 rport-8:0-0 NotOnline
Class = "zfcp_port"
    access_denied       = "0"
    failed              = "0"
    in_recovery         = "0"
    status              = "0x00000001"
Class = "fc_remote_ports"
    dev_loss_tmo        = "2147483647"
    fast_io_fail_tmo    = "5"
    maxframe_size       = "2112 bytes"
    node_name           = "0x5005076307ffc5e3"
    port_id             = "0x675e00"
    port_name           = "0x500507630718c5e3"
    port_state          = "Blocked"
    roles               = "FCP Target"
    scsi_target_id      = "0"
    supported_classes   = "Class 2, Class 3"

0.0.1900/0x500507630708c5e3/0x4000408600000000 0:0:0:1082540032 auto
Class = "scsi_device"
    ...
    state               = "running"
    ...
    zfcp_access_denied  = "0"
    zfcp_failed         = "0"
    zfcp_in_recovery    = "0"
    zfcp_status         = "0x54000000"

0.0.1940/0x500507630718c5e3/0x4000408600000000 8:0:0:1082540032 auto NotRunning
Class = "scsi_device"
    ...
    state               = "transport-offline"
    ...
    zfcp_access_denied  = "0"
    zfcp_failed         = "0"
    zfcp_in_recovery    = "0"
    zfcp_status         = "0x00000000"

0.0.5000/0x500507680b2381fb/0x0256000000000000 1:0:0:598 NotRunning
Class = "zfcp_unit"
    access_denied       = "0"
    access_readonly     = "0"
    access_shared       = "0"
    failed              = "0"
    in_recovery         = "0"
    status              = "0x00000000"
Class = "scsi_device"
    ...
    state               = "transport-offline"
    ...
    zfcp_access_denied  = "0"
    zfcp_failed         = "0"
    zfcp_in_recovery    = "0"
    zfcp_status         = "0x00000000"

0.0.5040/0x500507680b2281fa/0x0256000000000000 2:0:0:598
Class = "zfcp_unit"
    access_denied       = "0"
    access_readonly     = "0"
    access_shared       = "0"
    failed              = "0"
    in_recovery         = "0"
    status              = "0x54000000"
Class = "scsi_device"
    ...
    state               = "running"
    ...
    zfcp_access_denied  = "0"
    zfcp_failed         = "0"
    zfcp_in_recovery    = "0"
    zfcp_status         = "0x54000000"

Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-03-26 17:14:46 +01:00
Steffen Maier
0c78add815 lszfcp: add new output marker for non-good SCSI devices (luns)
Shows potential issues with zfcp-attached SCSI devices at one glance.

Example:

$ lszfcp -De
0.0.5000/0x500507680b2181fa/0x027d000000000000 1:0:1:637 NotRunning

$ lszfcp -DeV
/sys/devices/css0/0.0.0223/0.0.5000/0x500507680b2181fa/0x027d000000000000
/sys/bus/ccw/drivers/zfcp/0.0.5000/host1/rport-1:0-1/target1:0:1/1:0:1:637 NotRunning
/sys/block/sdm /sys/class/scsi_generic/sg12

Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Fedor Loshakov <loshakov@linux.ibm.com>
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-03-26 17:14:46 +01:00
Steffen Maier
94b7a8f68d lszfcp: allow to also enumerate FCP device that have never been online
Since zfcp lazily allocates Scsi_Host et al. on setting an FCP device
online for the first time since the last driver core bind to zfcp
(such as zfcp kernel module load),
lszfcp has only been showing FCP devices (vHBAs) that have been online
at least once including those that have been set offline again.
This is somewhat confusing.
Also it would be nice if lszfcp could be an easier to type replacement for
"lscss -t 17032/03" to simply show all devices bound to the zfcp device
driver.
Of course those FCP devices that have never been online, won't have any
zfcp-specific attribute details, only CIO attributes from the CCW bus.
They also do not have a Scsi_Host nor fc_host.

In order not to break any scripting or expectations around lszfcp,
make the new feature depend on the extended output command line option.

Example:

$ lszfcp -He
0.0.1880 - offline

$ lszfcp -HeV
/sys/devices/css0/0.0.010b/0.0.1880 offline
-
-

$ lszfcp -Hea
0.0.1880 - offline
Bus = "ccw"
    availability        = "good"
    cmb_enable          = "0"
    cutype              = "1731/03"
    devtype             = "1732/03"
    modalias            = "ccw:t1731m03dt1732dm03"
    online              = "0"
    uevent              = "DRIVER=zfcp"

Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Fedor Loshakov <loshakov@linux.ibm.com>
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-03-26 17:14:46 +01:00
Steffen Maier
4036e80b26 lszfcp: add new output marker for non-good FCP devices (hosts)
Shows potential issues with FCP devices at one glance.

Examples:

$ lszfcp -He
0.0.5000 host1 offline
0.0.50c0 host6 failed
0.0.3c40 host7 defunct

$ lszfcp -HeV
/sys/devices/css0/0.0.0223/0.0.5000 offline
/sys/class/fc_host/host1
/sys/class/scsi_host/host1
/sys/devices/css0/0.0.0226/0.0.50c0 failed
/sys/class/fc_host/host6
/sys/class/scsi_host/host6
/sys/devices/css0/defunct/0.0.3c40 defunct
/sys/class/fc_host/host7
/sys/class/scsi_host/host7

Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-03-26 17:14:46 +01:00
Steffen Maier
a236180ad8 lszfcp: add new output marker for non-good fc_rports
$ lszfcp -Pe
0.0.50c0/0x500507680b2481fa rport-6:0-2 NotOnline
$ lszfcp -PeV
- (NoMoreZfcpPort:0.0.50c0/0x500507680b2481fa)
/sys/class/fc_remote_ports/rport-6:0-2 NotOnline

$ lszfcp -Pe
0.0.3c40/0x500507680b2181fb rport-7:0-4 NotOnline
$ lszfcp -PeV
/sys/devices/css0/defunct/0.0.3c40/0x500507680b2181fb
/sys/class/fc_remote_ports/rport-7:0-4 NotOnline

Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-03-26 17:14:46 +01:00
Steffen Maier
a9684b9154 lszfcp: fix error message if no zfcp-attached SCSI device found
s390-tools-1.8.1 introduced a new error message.
It gave the same and thus misleading error message as if no FCP device
(vHBA) found.
In order not to break any scripting built around lszfcp output,
only print the fixed error message depending on the extended output
command line option.

Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-03-26 17:14:40 +01:00
Steffen Maier
6d31760872 lszfcp: fix to show defunct FCP devices again
s390-tools-1.8.0 introduced a regression skipping all FCP devices
that are currently "defunct".

Changing
$SYSFS/devices/css0/*/*/host*
to
$SYSFS/devices/css0/[0-9]*/[0-9]*/host*
was too strict as it won't match
$SYSFS/devices/css0/defunct/[0-9]*/host*
anymore.

Fix:
$SYSFS/devices/css0/[0-9d]*/[0-9]*/host*

Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-03-26 17:12:07 +01:00
Steffen Maier
b0dcc61ed5 lszfcp: fix to show non-good target ports again
s390-tools-1.8.1 introduced a regression skipping all fc_rports
with port_state != Online. While we need to skip some output parts
for a zfcp_port which does not exist anymore due to port_remove,
there are other cases with port_state != Online for which we should
not skip an fc_rport.

Such as port_state "Blocked" after a cable pull beyond host-adjacent switch
or port_state "Not Present" after dev_loss_tmo ran out.
This way the user can see the previously discovered ports,
even if they might currently not be usable for traffic.
Non-good ports are marked in the short output with suffix "NotOnline".
In order not to break scripting or expectations around lszfcp, make the new
feature depend on the extended output command line option.

Sysfs path globbing does not work for a removed zfcp_port
to obtain the FCP device bus-ID. Instead, properly walk the sysfs.

Examples with a removed zfcp_port:
$ lszfcp -Pe
0.0.50c0/0x500507680b2481fa rport-6:0-2
$ lszfcp -PeV
- (NoMoreZfcpPort:0.0.50c0/0x500507680b2481fa)
/sys/class/fc_remote_ports/rport-6:0-2

Examples with an existing zfcp_port but pulled fibre:
$ lszfcp -Pe
0.0.3c40/0x500507680b2181fb rport-7:0-4
$ lszfcp -PeV
/sys/devices/css0/defunct/0.0.3c40/0x500507680b2181fb
/sys/class/fc_remote_ports/rport-7:0-4

Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-03-26 17:12:07 +01:00
Steffen Maier
a3e37953fe lszfcp: fix missing block & sg device output without CONFIG_SYSFS_DEPRECATED
lszfcp -DVe was missing a 3rd SCSI device header line like:

/sys/devices/css0/0.0.0019/0.0.1880/0x50050763031bd327/0x4045400000000000
/sys/bus/ccw/drivers/zfcp/0.0.1880/host0/rport-0:0-0/target0:0:0/0:0:0:1073758277
/sys/block/sda /sys/class/scsi_generic/sg0

Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-03-26 17:12:07 +01:00
Steffen Maier
abf18cb711 lszfcp: new command line option for extended output format
Used in subsequent patches to guard their changes in order not to break
any scripting or expectations around the lszfcp output format.

Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-03-26 17:12:07 +01:00
Steffen Maier
22a4d45e3b lszfcp: clean up whitespace (mixed indentation, trailing)
Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-03-26 17:12:07 +01:00
Ingo Franzki
e693173eef zkey: Add batch-mode option to zkey-cryptsetup tool
When re-enciphering or setting LUKS2 volume keys using zkey-cryptsetup,
allow to specify the --batch-mode|-q option to suppress confirmation
questions.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-03-21 12:19:12 +01:00
Ingo Franzki
11bfa1d3c8 zkey: Add open and format options to the cryptsetup command
For LUKS2 volumes the cryptsetup command currently generates
'cryptsetup luksFormat' commands, but for plain mode volumes it
generates 'cryptsetup plainOpen' commands.

With the --open option it can now also generate 'cryptsetup luksOpen'
commands for opening LUKS2 volumes. With the --format option you can
limit the generated commands to only generate 'cryptsetup luksFormat'
commands for LUKS2 volumes, and skip plain mode volumes.
The default behavior (i.e. if none of the two options specified),
remains the same as before.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-03-21 12:19:12 +01:00
Ingo Franzki
3ed8ab4e2a zkey: Add common passphrase options for crypttab command
When generating crypttab entries for LUKS2 volumes, allow to
specify common passphrase options like --key-file, --keyfile-offset,
--keyfile-size and --tries and pass those to the generated crypttab
entries.

Note that not all distributions support the keyfile-offset and
keyfile-size options in crypttab entries.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-03-21 12:19:12 +01:00
Ingo Franzki
5a0c93443c zkey: Add batch-mode option to cryptsetup command
When generating cryptsetup commands, allow to specify the
--batch-mode|-q option and pass it to the generated commands.

Closes: https://github.com/ibm-s390-tools/s390-tools/pull/59
Fixes: https://github.com/ibm-s390-tools/s390-tools/issues/58

Suggested-by: Dimitri John Ledkov <xnox@ubuntu.com>
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-03-21 12:19:12 +01:00
Ingo Franzki
b0c7965234 zkey: Add common passphrase options for cryptsetup command
When generating 'cryptsetup luksFormat' or 'zkey-cryptsetup setvp'
commands for LUKS2 volumes, allow to specify common passphrase options
like --key-file, --keyfile-offset, --keyfile-size and --tries and
pass those to the generated commands.

Closes: https://github.com/ibm-s390-tools/s390-tools/pull/59
Fixes: https://github.com/ibm-s390-tools/s390-tools/issues/58

Suggested-by: Dimitri John Ledkov <xnox@ubuntu.com>
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-03-21 12:19:12 +01:00
Dan Horák
cdb23f8d22 zipl: copy new section introduced by GCC 9
GCC 9 is using a new section called .rodata.cst8 for some literals and
it must be included when copying the bootloaders to the bin images.

Closes: https://github.com/ibm-s390-tools/s390-tools/pull/60
Signed-off-by: Dan Horák <dan@danny.cz>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-03-21 12:19:12 +01:00
Sa Liu
60bda7ed0d dbginfo: Added commmands blockdev and lvdisplay
Signed-off-by: Sa Liu <saliu@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-03-21 12:19:12 +01:00
Peter Oberparleiter
4ff6519961 zdev: Do not export inacceptable attribute values
For some device driver SysFS attributes, values read may not be
acceptable input values for that attribute.

An example would be the group of qeth VNICC attributes that return "n/a"
when VNICC setup is not supported, but only accept "0" and "1" as valid
values that can be written to it.

This leads to errors such as the following when data for such attributes
is imported:

  # chzdev f500 --import test.conf
  Importing configuration data from test.conf
  QETH device 0.0.f500:0.0.f501:0.0.f502 configure failed
      Error: Invalid value for qeth attribute: vnicc/flooding=n/a (*)
      Acceptable values:
      - Integers in the range 0 - 1
      Use 'chzdev qeth --help-attribute vnicc/flooding' for more information
  Note: You can use --force to override safety checks (*)

To fix this, change chzdev's --export function to skip any attribute
value that is not acceptable for that attribute.

Fixes: e831269e74 ("zdev: Add support for VNIC Characteristics")
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-03-21 12:19:12 +01:00
Ingo Franzki
90dc65659f zkey: Correct crypttab entry generation
Remove 'hash=plain' option for plain type entries, add 'none luks'
for LUKS type entries.

Note that the format of a crypttab entry is distribution specific.
On some distributions only the first 2 fields are required, the
remaining are optional, on other distributions all 4 fields are
required. With this patch correct crypttab entries are generated
for all distributions.

Closes: https://github.com/ibm-s390-tools/s390-tools/pull/55
Fixes: https://github.com/ibm-s390-tools/s390-tools/issues/57
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-03-07 14:02:01 +01:00
Ingo Franzki
ec9c67189e zkey-cryptsetup: Support debug level CRYPT_DEBUG_JSON
With libcryptsetup version 2.1 a new debug level was introduced
to log the JSON structures when adding key slots, digests, etc
into the LUKS2 header.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-03-07 13:54:43 +01:00
Ingo Franzki
951bd1ae54 zkey-cryptsetup: Fix logging of libcryptsetup debug messages
Messages from libcryptsetup for logging level CRYPT_LOG_DEBUG
do not include an EOL.

Prior to libcryptsetup version 2.1 debug messages were not printed
through the log callback, but using printf directly within
libcryptsetup. Now they are also printed through the log callback,
but without an EOL terminating the text.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-03-07 13:54:43 +01:00
Ingo Franzki
ed6e3b7270 zkey-cryptsetup: Obtain PBKDF from existing key-slot
For zkey-cryptsetup commands reencipher and setkey, use the
same password-based key derivation function (PBKDF) when
creating unbound key-sots that the key slot uses, which was
unlocked through the specified passphrase. That way the
unlocked key slots created by these commands inherit the
PBKDF from the existing key slot.

This feature requires libcryptsetup version 2.1 or later.
If an older libcryptsetup version is available at compile
time, then PBKDF2 is used for newly created unbound key slots.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-03-07 13:54:43 +01:00
Ingo Franzki
79ce120553 zkey: Minor correction in man page
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-03-07 13:54:43 +01:00
Jan Höppner
b45b564681 Prepare for next release
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-03-07 13:54:43 +01:00
Jan Höppner
c8d0fca36c New release s390-tools-2.8.0
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-02-15 16:35:47 +01:00
Sa Liu
bbd88f26c9 dbginfo: Redirect output of lsof to a separate file open_files.out
The output of lsof command is sometimes too long and makes it difficult
to search in runtime.out. Move the output to a separate file.

Signed-off-by: Sa Liu <saliu@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-02-15 16:35:47 +01:00
Sa Liu
79bfa818ed dbginfo: Collect traces under /var/log/opencryptoki
Signed-off-by: Sa Liu <saliu@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-02-11 12:33:56 +01:00
Hendrik Brueckner
299144264d cpumf/cpumf_helper: always return list reference for --sfb-size
Running lscpumf -i as regular user causes a warning when trying to
disply sampling buffer sizes.  The root cause is in the cpumf_helper
that returns "0,0" instead of a list reference "[0,0]".

This happened when running as regular user because the sampling buffer
size sysfs attribute is not readable for them.

Remove the shortcut and always return a list reference.

Signed-off-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-02-11 12:33:56 +01:00
Ingo Franzki
a69470d7e0 zkey-cryptsetup: Use PBKDF2 as default PBKDF for new key slots
LUKS2 encrypted volumes use Argon2i as default password based key
derivation function (PBKDF). Argon2i is a so-called memory-hard
function. It requires a certain amount of physical memory to make
dictionary attacks more costly.

Unfortunately, when multiple encrypted volumes are unlocked
automatically during system startup via /etc/crypttab, the use of
Argon2i will most likely cause an out-of-memory error in systemd.

To avoid the out-of-memory error, use PBKDF2 instead. Because PAES
uses secure keys as volume keys, the security of the key derivation
function used to derive the key to encrypt the volume key in the LUKS
key slots is of less relevance. Thus it is safe to use a weaker key
derivation function.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-02-11 12:33:56 +01:00
Ingo Franzki
b26dbfe832 zkey: Add --pbkdf pbkdf2 to generated crptsetup luksFormat command
LUKS2 encrypted volumes use Argon2i as default password based key
derivation function (PBKDF). Argon2i is a so-called memory-hard
function. It requires a certain amount of physical memory to make
dictionary attacks more costly.

Unfortunately, when multiple encrypted volumes are unlocked
automatically during system startup via /etc/crypttab, the use of
Argon2i will most likely cause an out-of-memory error in systemd.

To avoid the out-of-memory error, use PBKDF2 instead. Because PAES
uses secure keys as volume keys, the security of the key derivation
function used to derive the key to encrypt the volume key in the LUKS
key slots is of less relevance. Thus it is safe to use a weaker key
derivation function.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-02-11 12:33:56 +01:00
Ingo Franzki
d95dc6d698 zkey: Avoid EPERM on key change if user is not owner of key file
When a user that is in the zkeyadm group, but is not the owner
of the key file changes a key in the zkey repository, then
error "Operation not permitted" occurs. This is due to a superfluous
call to chmod on the key file. When key files are changed then the
permissions of that file are retained anyway.

Also fix a typo in the error message when chmod fails.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-02-11 12:33:56 +01:00
Dan Horák
847f16f632 Switch to using /run directory instead of the legacy /var/run
Closes: https://github.com/ibm-s390-tools/s390-tools/pull/53
Signed-off-by: Dan Horák <dan@danny.cz>
Acked-by: Sa Liu <saliu@de.ibm.com>
Acked-by: Harald Freudenberger <freude@linux.ibm.com>
Acked-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-02-11 12:33:56 +01:00
Stefan Haberland
bc053a975a zdsfs: add online vtoc refresh
Enable zdsfs to access datasets that were created after zdsfs was
mounted without the need to remount zdsfs.
This is done by re-reading the VTOC with every readdir system call.
To ensure a consistent VTOC state the DASD device is reserved for
every VTOC read and released afterwards.

Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-01-30 13:35:43 +01:00
Harald Freudenberger
e9c030f202 zcrypt: refine lszcrypt man page
Added some explanations about the columns shown with the
lszcrypt verbose output.

Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-01-24 12:42:35 +01:00
Dan Horák
dffd41943e pkey: Support autoloading kernel pkey module
The module is loaded automatically based on CPU features, but it's still
too late in some use cases. Thus allow distros to use explicit loading.

See also: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=63c19be095d0f8eb8992674991e44b4228bd4179

Closes: https://github.com/ibm-s390-tools/s390-tools/pull/51
Signed-off-by: Dan Horák <dan@danny.cz>
Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-01-10 12:42:47 +01:00
Ingo Franzki
58189b8786 libutil: Add indention and separator to util_rec_example.c
Show how to use util_rec_set_indent() and util_rec_print_separator()
in util_rec_example.c

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-01-10 12:42:47 +01:00
Ingo Franzki
b165500b69 libutil: Add function to print separator line
In wide format the header is separated from the rest of the
records by a separator line. Add support to print such a
separator line also between some records.

Add function util_rec_print_separator() that prints the
separator line for wide format only. For other formats this
is a NOP.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-01-10 12:42:47 +01:00
Ingo Franzki
5f2ddad6a8 libutil: Add support for indenting records
Functions rec_print_xxx allows to print records in
different formats. Add support to optionally indent
the output by a specific number of characters.

The indention is set using a new function util_rec_set_indent().
The default indention is zero, thus existing applications
will behave the same as before.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-01-10 12:42:47 +01:00
Jan Höppner
28deb03178 Prepare for next release
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2019-01-10 12:42:47 +01:00
Jan Höppner
8f1fa2a83c New release s390-tools-2.7.1
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-12-13 15:57:25 +01:00
Martin Schwidefsky
7677d3c0b4 cmsfs-fuse: write more than a single line in linefeed mode
The cmsfs_write function only writes a single record in line mode
and returns the number of bytes it consumed from the input buffer.
This is valid behaviour as the write system call can always return
with a partial write. But there are tools that ignore the return
value of the write and just assume that a single write call is
sufficient to write many lines aka records on the cmsfs filesystem.

Enhance the cmsfs_write function to loop until all lines from the
input buffer have been consumed.

Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-12-13 15:57:25 +01:00
Gerald Schaefer
6f7cb68dcf cmsfs-fuse: Fix iconv buffer aliasing
GCC8 shows the following compile warning:

cmsfs-fuse.c: In function ‘convert_text’:
cmsfs-fuse.c:2558:19: warning: passing argument 2 to restrict-qualified
parameter aliases with argument 4 [-Wrestrict]
  rc = iconv(conv, &data_ptr, &in_count, &data_ptr, &out_count);
                   ^~~~~~~~~             ~~~~~~~~~

Fix this by using a separate buffer for iconv. The buffer size depends on
the record format: variable-length records have a maximum length of
MAX_RECORD_LEN (plus 1 byte for linefeed), while fixed-length records
could be larger in theory. This patch takes that into account for the iconv
buffer, but the rest of the code currently cannot handle fixed-length records
larger than MAX_RECORD_LEN.

Signed-off-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-12-13 15:57:25 +01:00
Jan Höppner
4d008849f7 libu2s: Remove library dependency
Commit aefc8cd3ff ("libutil/libu2s: Move strlcpy() implementation to
libutils") added a dependency to libutil. This is not necessary and
could potentially lead to parallel build errors. Remove the dependency.

Fixes: aefc8cd3ff ("libutil/libu2s: Move strlcpy() implementation to libutils")
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-12-13 15:57:25 +01:00
Jan Höppner
d921c230ab libdasd: Remove useless build dependency
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-12-13 15:57:25 +01:00
Jan Höppner
6151889dcd zpcictl: Add warning for unsupported operations
There are several reasons why an operation might fail. Either the
running kernel, the PCI function itself, or the hypervisor lacks support
for a certain operation. In such cases the kernel returns either with
EIO or EOPNOTSUPP.
The corresponding warning, however, just says the file couldn't be
closed. Display a warning for EIO and EOPNOTSUPP to tell the user about
the missing support.

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-12-13 15:57:25 +01:00
Jan Höppner
224dc2e414 Fix spelling typos and grammar mistakes.
Closes: https://github.com/ibm-s390-tools/s390-tools/pull/39
Suggested-by: Dimitri John Ledkov <xnox@ubuntu.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-12-11 15:52:07 +01:00
Ingo Franzki
5a10aa73a9 zkey: Enhance error message about missing CCA library
Make the error message when the CCA library is missing more
user friendly. Also display an URL where the CCA package
can be downloaded.

The CCA library is used for the REENCIPHER commands of
zkey and zkey-cryptsetup and must be installed separately
as part of the IBM CCA Host Libraries and Tools package.
This packages is not provided by the distributors, but must
be downloaded from an IBM web page and installed separately.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-12-11 15:52:07 +01:00
Jan Höppner
428d41034e libvmdump: Fix -Wrestrict warning
Get rid of the following GCC8 compile warning by using different buffers
for input/output:

In file included from vmdump_convert.cpp:13:
vm_dump.h: In member function ‘void VMDump::ebcAsc(char*, size_t)
const’:
vm_dump.h:145:26: warning: passing argument 2 to restrict-qualified
parameter aliases with argument 4 [-Wrestrict]
   iconv(ebcdicAsciiConv, &inout, &len, &inout, &len);
                          ^~~~~~        ~~~~~~
vm_dump.h:145:34: warning: passing argument 3 to restrict-qualified
parameter aliases with argument 5 [-Wrestrict]
   iconv(ebcdicAsciiConv, &inout, &len, &inout, &len);
                                  ^~~~          ~~~~

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-12-11 15:52:07 +01:00
Jan Höppner
cf265cc46a qethqoat: Fix -Wrestrict warning
Get rid of the following GCC8 compile warning by using different buffers
for input/output:

qethqoat.c: In function ‘ebctoasc’:
qethqoat.c:51:30: warning: passing argument 2 to restrict-qualified
parameter aliases with argument 4 [-Wrestrict]
  iconv(l_iconv_ebcdic_ascii, &inout, &len, &inout, &len);
                              ^~~~~~        ~~~~~~
qethqoat.c:51:38: warning: passing argument 3 to restrict-qualified
parameter aliases with argument 5 [-Wrestrict]
  iconv(l_iconv_ebcdic_ascii, &inout, &len, &inout, &len);
                                      ^~~~          ~~~~

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-12-11 15:52:07 +01:00
Jan Höppner
84623f39dc hyptop: Fix -Wrestrict warning
Make sure there are two different buffers passed to iconv() to get rid
of the following GCC8 compile warning:

helper.c: In function ‘ht_ebcdic_to_ascii’:
helper.c:103:30: warning: passing argument 2 to restrict-qualified
parameter aliases with argument 4 [-Wrestrict]
  iconv(l_iconv_ebcdic_ascii, &inout, &len, &inout, &len);
                              ^~~~~~        ~~~~~~
helper.c:103:38: warning: passing argument 3 to restrict-qualified
parameter aliases with argument 5 [-Wrestrict]
  iconv(l_iconv_ebcdic_ascii, &inout, &len, &inout, &len);
                                      ^~~~          ~~~~

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-12-11 15:52:07 +01:00
Michael Holzheu
8cbdfebc4f Makefile: Fix parallel build (2nd try)
Commit 851f685993 ("Makefile: Add dependency between libvmcp and
libutil to fix -j builds") introduced the following regression

  $ make clean
  CLEAN   /home2/holzheu/src/s390-tools
  ...
  CLEAN   libccw
  CC      libutil/util_base.o
  CC      libutil/util_path.o

For the "clean" target the new library dependency triggers a build
of libutil.

So remove the dependency again.

To fix the parallel build issue, no longer build the examples with
"make all" and add a new target "examples" that can now be used for building
the example programs.

Fixes: 851f685993 ("Makefile: Add dependency between libvmcp and libutil to fix -j builds")
Signed-off-by: Michael Holzheu <holzheu@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-12-11 15:52:07 +01:00
Javier Martinez Canillas
4951044213 zipl: use the BLS "title" field as the IPL section name
Most bootloaders use the BootLoaderSpec "title" field to name the entries
in their boot menu. The zipl bootloader used the "version" field instead,
since it was wrongly assumed that the zipl boot menu didn't support names
that contained spaces, which are usually present in a BLS "title" field.

But this is not the case, names with space characters are supported by the
IPL and is just a constraint of the section heading in the zipl.conf file.

So to be consistent with all the other bootloaders, use the "title" field
also on zipl when populating the boot menu entries from BLS files.

Closes: https://github.com/ibm-s390-tools/s390-tools/pull/47
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Reviewed-by: Stefan Haberland sth@linux.ibm.com
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:46:51 +01:00
Jan Höppner
667516681e zpcictl: Change service element to Support Element
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:19:48 +01:00
Jan Höppner
10ce432196 zpcictl: Replace strncpy() with util_strlcpy()
Use util_strlcpy() to copy log data correctly and get rid of the
following GCC8 compile warning:

zpcictl.c: In function ‘sclp_issue_action’:
zpcictl.c:312:3: warning: ‘strncpy’ specified bound 4054 equals
destination size [-Wstringop-truncation]
   strncpy(report.data.log_data, sdata, sizeof(report.data.log_data));
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:19:48 +01:00
Jan Höppner
320a49fc1a hmcdrvfs: Replace strncpy() with util_strlcpy()
Use util_strlcpy() to copy strings correctly and get rid of the
following GCC8 compile warning:

In function ‘hmcdrv_parse_line’,
    inlined from ‘hmcdrv_cache_dir’ at hmcdrvfs.c:981:11:
hmcdrvfs.c:862:4: warning: ‘strncpy’ specified bound 192 equals
destination size [-Wstringop-truncation]
    strncpy(symlink, arrow + 4, HMCDRV_FUSE_MAXPATH);
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:19:48 +01:00
Jan Höppner
f0d18ddf2b zdsfs: Use util_strlcpy() to copy strings
By using util_strlcpy() and correctly copying strings we can get rid of
the following GCC8 compile warnings:

In function ‘path_to_ds_name.constprop’,
    inlined from ‘zdsfs_readdir’ at zdsfs.c:282:2:
zdsfs.c:78:2: warning: ‘strncpy’ specified bound 45 equals destination
size [-Wstringop-truncation]
  strncpy(normds, path, size);
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~
In function ‘path_to_ds_name.constprop’,
    inlined from ‘zdsfs_open’ at zdsfs.c:339:2:
zdsfs.c:78:2: warning: ‘strncpy’ specified bound 45 equals destination
size [-Wstringop-truncation]
  strncpy(normds, path, size);
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~
In function ‘path_to_member_name.constprop’,
    inlined from ‘zdsfs_open’ at zdsfs.c:372:3:
zdsfs.c:94:3: warning: ‘strncpy’ specified bound 45 equals destination
size [-Wstringop-truncation]
   strncpy(normds, path, size);
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~
In function ‘path_to_ds_name.constprop’,
    inlined from ‘zdsfs_getxattr’ at zdsfs.c:527:2:
zdsfs.c:78:2: warning: ‘strncpy’ specified bound 45 equals destination
size [-Wstringop-truncation]
  strncpy(normds, path, size);
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~
In function ‘path_to_member_name.constprop’,
    inlined from ‘zdsfs_getxattr’ at zdsfs.c:547:4:
zdsfs.c:94:3: warning: ‘strncpy’ specified bound 45 equals destination
size [-Wstringop-truncation]
   strncpy(normds, path, size);
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~
In function ‘path_to_ds_name.constprop’,
    inlined from ‘zdsfs_getattr.part.1’ at zdsfs.c:134:2,
    inlined from ‘zdsfs_getattr’:
zdsfs.c:78:2: warning: ‘strncpy’ specified bound 45 equals destination
size [-Wstringop-truncation]
  strncpy(normds, path, size);
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~
In function ‘path_to_member_name.constprop’,
    inlined from ‘zdsfs_getattr.part.1’ at zdsfs.c:164:3,
    inlined from ‘zdsfs_getattr’:
zdsfs.c:94:3: warning: ‘strncpy’ specified bound 45 equals destination
size [-Wstringop-truncation]
   strncpy(normds, path, size);
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:19:48 +01:00
Jan Höppner
2962248e7b qethqoat: Use util_strlcpy() to copy strings
Use the more robust util_strlcpy() to copy strings instead of strncpy().

This fixes the following GCC8 compile warnings:

qethqoat.c: In function ‘main’:
qethqoat.c:616:2: warning: ‘strncpy’ specified bound 16 equals
destination size [-Wstringop-truncation]
  strncpy(ifr.ifr_name, opts.ifname, IFNAMSIZ);
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:19:48 +01:00
Jan Höppner
773c8672ac cmsfs-fuse: Copy strings correctly using util_strlcpy()
Use util_strlcpy() instead of strncpy() to correctly copy strings.

This fixes the following GCC8 compile warnings:

cmsfs-fuse.c: In function ‘file_open’:
cmsfs-fuse.c:604:2: warning: ‘strncpy’ specified bound 18 equals
destination size [-Wstringop-truncation]
  strncpy(uc_name, name, MAX_FNAME);
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cmsfs-fuse.c: In function ‘lookup_file’:
cmsfs-fuse.c:1570:2: warning: ‘strncpy’ specified bound 18 equals
destination size [-Wstringop-truncation]
  strncpy(uc_name, name, MAX_FNAME);
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cmsfs-fuse.c: In function ‘cmsfs_open’:
cmsfs-fuse.c:1854:3: warning: ‘strncpy’ specified bound 19 equals
destination size [-Wstringop-truncation]
   strncpy(f->path, path, MAX_FNAME + 1);
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cmsfs-fuse.c: In function ‘delete_file’:
cmsfs-fuse.c:2760:2: warning: ‘strncpy’ specified bound 18 equals
destination size [-Wstringop-truncation]
  strncpy(file, path + 1, MAX_FNAME);
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cmsfs-fuse.c: In function ‘cmsfs_rename’:
cmsfs-fuse.c:2850:2: warning: ‘strncpy’ specified bound 18 equals
destination size [-Wstringop-truncation]
  strncpy(uc_old_name, path + 1, MAX_FNAME);
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cmsfs-fuse.c:2857:3: warning: ‘strncpy’ specified bound 19 equals
destination size [-Wstringop-truncation]
   strncpy(f->path, new_path, MAX_FNAME + 1);
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cmsfs-fuse.c: In function ‘cmsfs_create’:
cmsfs-fuse.c:2111:2: warning: ‘strncpy’ specified bound 18 equals
destination size [-Wstringop-truncation]
  strncpy(uc_name, path + 1, MAX_FNAME);
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

config.c:68:2: warning: ‘strncpy’ specified bound 9 equals destination
size [-Wstringop-truncation]
  strncpy(entry->name, name, MAX_TYPE_LEN);
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:19:48 +01:00
Jan Höppner
637750f299 hyptop: Replace strncpy() with util_strlcpy()
Ensure that strings are copied correctly by using util_strlcpy() rather
than strncpy().

This fixes the following GCC8 compile warnings:

sd_core.c: In function ‘sd_cpu_new’:
sd_core.c:222:2: warning: ‘strncpy’ specified bound 9 equals destination
size [-Wstringop-truncation]
  strncpy(cpu->id, id, sizeof(cpu->id));
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sd_core.c: In function ‘sd_sys_new’:
sd_core.c:254:2: warning: ‘strncpy’ specified bound 9 equals destination
size [-Wstringop-truncation]
  strncpy(sys_new->id, id, sizeof(sys_new->id));
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

tbox.c:160:2: warning: ‘strncpy’ specified bound 121 equals destination
size [-Wstringop-truncation]
  strncpy(line_cpy, line, sizeof(line_cpy));
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

win_sys.c: In function ‘win_sys_set’:
win_sys.c:329:2: warning: ‘strncpy’ specified bound 9 equals destination
size [-Wstringop-truncation]
  strncpy(l_sys_id, sys_id, sizeof(l_sys_id));
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:19:48 +01:00
Jan Höppner
a17b52a043 hyptop: Remove unused function sd_cpu_real_type_set()
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:19:48 +01:00
Jan Höppner
d14051e309 zdev: Copy strings correctly using util_strlcpy()
Make sure strings are copied correctly by using util_strlcpy().

Also, rename the NIC_{OWNER,NAME}_LEN definitions to *_SIZE to make it
more clear that the terminating null byte ('\0') is included in this
buffer size. Using *_LEN would mean only the number of characters in the
string fit in.
Furthermore, use these definitions rather than sizeof().

This fixes the following GCC8 compile warning:

nic.c: In function ‘nic_data_get’:
nic.c:58:2: warning: ‘strncpy’ specified bound 9 equals destination size
[-Wstringop-truncation]
  strncpy(data.owner, argv[11], sizeof(data.owner));
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
nic.c:59:2: warning: ‘strncpy’ specified bound 9 equals destination size
[-Wstringop-truncation]
  strncpy(data.name, argv[12], sizeof(data.name));
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:19:48 +01:00
Jan Höppner
d85cf20981 dump2tar: Change SET_STR_FIELD to copy strings correctly
Make sure strings are properly copied in the SET_STR_FIELD
macro by using util_strlcpy().

This gets rid of the following GCC8 compile warnings:

In function ‘init_header’,
    inlined from ‘emit_header’ at tar.c:189:2:
tar.c:81:2: warning: ‘strncpy’ specified bound 100 equals destination
size [-Wstringop-truncation]
  strncpy((obj)->name, (value), sizeof((obj)->name))
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tar.c:94:2: note: in expansion of macro ‘SET_STR_FIELD’
  SET_STR_FIELD(header, name, filename);
  ^~~~~~~~~~~~~
tar.c:81:2: warning: ‘strncpy’ specified bound 100 equals destination
size [-Wstringop-truncation]
  strncpy((obj)->name, (value), sizeof((obj)->name))
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tar.c:94:2: note: in expansion of macro ‘SET_STR_FIELD’
  SET_STR_FIELD(header, name, filename);
  ^~~~~~~~~~~~~
tar.c:81:2: warning: ‘strncpy’ specified bound 100 equals destination
size [-Wstringop-truncation]
  strncpy((obj)->name, (value), sizeof((obj)->name))
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tar.c:96:3: note: in expansion of macro ‘SET_STR_FIELD’
   SET_STR_FIELD(header, linkname, link);
   ^~~~~~~~~~~~~

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:19:48 +01:00
Jan Höppner
7df8edd88a ipl_tools: Change buffer size and copy strings correctly
Change the buffer size to what we actually need and use util_strlcpy()
to correctly copy strings.

This gets rid of the following GCC8 compile warnings:

fcp.c: In function ‘fcp_wwpn_get’:
fcp.c:44:2: warning: ‘strncpy’ output may be truncated copying 20 bytes
from a string of length 4095 [-Wstringop-truncation]
  strncpy(wwpn, buf, 20);
  ^~~~~~~~~~~~~~~~~~~~~~
fcp.c: In function ‘fcp_lun_get’:
fcp.c:65:2: warning: ‘strncpy’ output may be truncated copying 20 bytes
from a string of length 4095 [-Wstringop-truncation]
  strncpy(lun, buf, 20);
  ^~~~~~~~~~~~~~~~~~~~~

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:19:48 +01:00
Jan Höppner
6d382d30d9 ipl_tools: Allocate string buffer dynamically
Use util_asprintf() to allocate memory for the string buffers
dynamically and get rid of the following GCC8 compile warnings:

system.c: In function ‘print_fw_str’:
system.c:86:46: warning: ‘%s’ directive output may be truncated writing
up to 4095 bytes into a region of size 4082 [-Wformat-truncation=]
  snprintf(path, sizeof(path), "/sys/firmware/%s", file);
                                              ^~
system.c:98:19:
  read_fw_str(str, path, sizeof(str));
                   ~~~~
system.c:86:2: note: ‘snprintf’ output between 15 and 4110 bytes into a
destination of size 4096
  snprintf(path, sizeof(path), "/sys/firmware/%s", file);
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

cmd_chreipl.c: In function ‘set_reipl_type_helper’:
cmd_chreipl.c:316:19: warning: ‘%d’ directive writing between 1 and 11
bytes into a region of size between 0 and 4095 [-Wformat-overflow=]
  sprintf(cmd, "%s %d:%d", chreipl_helper, major(dev), minor(dev));
                   ^~
cmd_chreipl.c:316:15: note: using the range [-2147483648, 2147483647]
for directive argument
  sprintf(cmd, "%s %d:%d", chreipl_helper, major(dev), minor(dev));
               ^~~~~~~~~~
cmd_chreipl.c:316:15: note: using the range [-2147483648, 2147483647]
for directive argument
cmd_chreipl.c:316:2: note: ‘sprintf’ output between 5 and 4120 bytes
into a destination of size 4096
  sprintf(cmd, "%s %d:%d", chreipl_helper, major(dev), minor(dev));
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:19:48 +01:00
Jan Höppner
9f8d245f92 ipl_tools: Copy strings correctly
Use util_strlcpy() to copy strings correctly and get rid of the
following GCC8 compile warnings:

main.c: In function ‘main’:
main.c:34:2: warning: ‘strncpy’ specified bound 256 equals destination
size [-Wstringop-truncation]
  strncpy(g.prog_name, argv[0], sizeof(g.prog_name));
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In function ‘set_bootprog’,
    inlined from ‘parse_chreipl_options’ at cmd_chreipl.c:510:4:
cmd_chreipl.c:185:2: warning: ‘strncpy’ specified bound 11 equals
destination size [-Wstringop-truncation]
  strncpy(l.bootprog, bootprog, sizeof(l.bootprog));
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

cmd_chreipl.c: In function ‘set_reipl_type’:
cmd_chreipl.c:297:2: warning: ‘strncpy’ specified bound 15 equals
destination size [-Wstringop-tr uncation]
  strncpy(l.dev, dev_name, sizeof(l.dev));
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:03:02 +01:00
Jan Höppner
cf39f26dee dasdinfo: Replace strncpy() with util_strlcpy()
Copy strings correctly by using util_strlcpy() over strncpy() and get
rid of the following GCC8 compile warning:

In function ‘dinfo_extract_dev’,
    inlined from ‘dinfo_get_dev_from_blockdev’ at dasdinfo.c:365:6:
dasdinfo.c:337:2: warning: ‘strncpy’ specified bound 80 equals
destination size [-Wstringop-trunc ation]
  strncpy(tmp, str, RD_BUFFER_SIZE);
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:01:42 +01:00
Jan Höppner
83106991ab lsqeth: Copy interface name correctly
IFNAMSIZ is the maximum buffer size for an interface name, including its
terminating zero byte. [1] strncpy() should therefore only copy a size
of 'IFNAMSIZ - 1' and the destination string should then be
null-terminated properly.

Use util_strlcpy() to correctly copy the string and get rid of the
followin GCC8 compile warning:

In function ‘ethtool_checksumming’,
    inlined from ‘process_sysfs_attribute’ at lsqeth.c:333:5,
    inlined from ‘print_device’ at lsqeth.c:468:3:
lsqeth.c:171:2: warning: ‘strncpy’ specified bound 16 equals destination
size [-Wstringop-truncat ion]
  strncpy(ifr.ifr_name, if_name, IFNAMSIZ);
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

[1]: https://www.gnu.org/software/libc/manual/html_node/Interface-Naming.html

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:01:42 +01:00
Jan Höppner
b631c74df5 lszcrypt: Replace sprintf() with util_asprintf()
Get rid of fixed buffers and avoid the following GCC8 compile warnings:

lszcrypt.c: In function ‘main’:
lszcrypt.c:642:28: warning: ‘%04x’ directive writing between 4 and 8
bytes into a region of size between 7 and 13 [-Wformat-overflow=]
     sprintf(sub_dev, "%02x.%04x", id, dom);
                            ^~~~
lszcrypt.c:642:22: note: directive argument in the range [0, 2147483647]
     sprintf(sub_dev, "%02x.%04x", id, dom);
                      ^~~~~~~~~~~
lszcrypt.c:642:5: note: ‘sprintf’ output between 8 and 18 bytes into a
destination of size 16
     sprintf(sub_dev, "%02x.%04x", id, dom);
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:01:42 +01:00
Jan Höppner
c675096899 ip_watcher: Copy device name correctly
DEV_NAME_SIZE is defined as IFNAMSIZ. IFNAMSIZ is the maximum buffer size
for an interface name, including its terminating null byte. [1] The
buffers dev_name and ifr_name are both defined with a size of
DEV_NAME_SIZE and IFNAMSIZ respectively.
Given these facts, only a size of 'IFNAMSIZ - 1' should be copied and
the destination string should then be null-terminated properly.

Use util_strlcpy() to correctly copy the strings and rid of the followin
GCC8 compile warnings:

xcec-bridge.c: In function ‘open_incoming_socket’:
xcec-bridge.c:94:2: warning: ‘strncpy’ specified bound 16 equals
destination size [-Wstringop-tru ncation]
..strncpy(if_req.ifr_name,dev_name,DEV_NAME_LEN);
..^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
xcec-bridge.c: In function ‘read_sys’:
xcec-bridge.c:284:4: warning: ‘strncpy’ output may be truncated copying
16 bytes from a string of length 255 [-Wstringop-truncation]
....strncpy(is->dev_name, if_name, DEV_NAME_LEN);
....^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

[1]: https://www.gnu.org/software/libc/manual/html_node/Interface-Naming.html

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:01:42 +01:00
Jan Höppner
5a9e93fb5b ip_watcher: Rename DEV_NAME_LEN definition
The term 'len' only represents the number of characters in a string,
as opposed to 'size' which means the number of bytes including the
terminating null byte ('\0').
DEV_NAME_LEN is defined as IFNAMSIZ, so we are clearly interested in the
size. Rename to DEV_NAME_SIZE to make this more clear.

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:01:42 +01:00
Jan Höppner
aefc8cd3ff libutil/libu2s: Move strlcpy() implementation to libutils
The strlcpy() implementation in libu2s is beneficial for other tools as
well. Move the implementation to libutils and replace misc_strlcpy() in
libu2s accordingly.

Change the link order in zipl to make it build again.

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:01:42 +01:00
Jan Höppner
a208463e49 dasdview: Replace strncpy() with memcpy()
Safely replace strncpy() with memcpy() as we don't want the terminating
null byte anyway. Get rid of the following warning:

dasdview.c: In function ‘dasdview_print_volser’:
dasdview.c:621:3: warning: ‘strncpy’ output truncated before terminating
nul copying 6 bytes from a string of the same length
[-Wstringop-truncation]
   strncpy(volser, "      ", 6);
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:01:42 +01:00
Jan Höppner
a931428908 fdasd: Replace strncpy() with memcpy()
While assembling the volume label, strncpy() is used. As we don't care
about NUL termination of the strings here, safely replace strncpy() with
memcpy() and get rid of the following compile warnings:

fdasd.c: In function ‘fdasd_write_vtoc_labels’:
fdasd.c:1324:4: warning: ‘strncpy’ output truncated before terminating
nul copying 44 bytes from a string of the same length
[-Wstringop-truncation]
    strncpy(ch, "LINUX.V               "
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     "                      ", 44);
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
fdasd.c:1332:4: warning: ‘strncpy’ output truncated before terminating
nul copying 5 bytes from a string of the same length
[-Wstringop-truncation]
    strncpy(c1, ".PART", 5);
    ^~~~~~~~~~~~~~~~~~~~~~~
In function ‘fdasd_write_vtoc_labels’,
    inlined from ‘fdasd_write_labels’ at fdasd.c:1399:3:
fdasd.c:1329:4: warning: ‘strncpy’ output may be truncated copying 6
bytes from a string of length 6 [-Wstringop-truncation]
    strncpy(c1, volser, VOLSER_LENGTH);
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
fdasd.c:1336:4: warning: ‘strncpy’ output may be truncated copying 5
bytes from a string of length 5 [-Wstringop-truncation]
    strncpy(c1, dsno, 5);
    ^~~~~~~~~~~~~~~~~~~~
fdasd.c:1340:4: warning: ‘strncpy’ output truncated before terminating
nul copying as many bytes from a string as its length
[-Wstringop-truncation]
    strncpy(c1, dsname, strlen(dsname)); /* We don't want \0 */
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
fdasd.c:1313:4: warning: ‘strncpy’ output may be truncated copying 31
bytes from a string of length 44 [-Wstringop-truncation]
    strncpy(c1, s2, 31);
    ^~~~~~~~~~~~~~~~~~~
In function ‘fdasd_change_part_type’,
    inlined from ‘main’ at fdasd.c:3000:4:
fdasd.c:1639:3: warning: ‘strncpy’ output may be truncated copying 6
bytes from a string of length 19 [-Wstringop-truncation]
   strncpy(ch, str, 6);
   ^~~~~~~~~~~~~~~~~~~

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:01:42 +01:00
Jan Höppner
c2297a0a7e zgetdump: Replace strncpy() with memcpy()
We can safely replace strncpy() with memcpy() here and get rid of the
following compile warnings:

dfi_s390mv.c: In function ‘set_magic_numbers’:
dfi_s390mv.c:570:3: warning: ‘strncpy’ output truncated before
terminating nul copying 7 bytes fr om a string of the same length
[-Wstringop-truncation]
   strncpy(l.dumper_magic, DF_S390_DUMPER_MAGIC_MV_EXT, 7);
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dfi_s390mv.c:573:3: warning: ‘strncpy’ output truncated before
terminating nul copying 7 bytes fr om a string of the same length
[-Wstringop-truncation]
   strncpy(l.dumper_magic, DF_S390_DUMPER_MAGIC_MV, 7);
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:01:42 +01:00
Jan Höppner
70a79fab3c zgetdump: Avoid using PATH_MAX
Using inappropriate sizes for snprintf() leads to the following compile
warnings:

dfi_s390mv.c: In function ‘dev_from_busid’:
dfi_s390mv.c:116:34: warning: ‘/online’ directive output may be
truncated writing 7 bytes into a region of size between 1 and 4096
[-Wformat-truncation=]
  snprintf(tmp_file, PATH_MAX, "%s/online", dev_file);
                                  ^~~~~~~
dfi_s390mv.c:116:2: note: ‘snprintf’ output between 8 and 4103 bytes
into a destination of size 4096
  snprintf(tmp_file, PATH_MAX, "%s/online", dev_file);
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dfi_s390mv.c:143:35: warning: ‘%s’ directive output may be truncated
writing up to 255 bytes into a region of size between 0 and 4095
[-Wformat-truncation=]
  snprintf(tmp_file, PATH_MAX, "%s/%s/dev", dev_file, direntp->d_name);
                                   ^~
dfi_s390mv.c:143:2: note: ‘snprintf’ output between 6 and 4356 bytes
into a destination of size 4096
  snprintf(tmp_file, PATH_MAX, "%s/%s/dev", dev_file, direntp->d_name);
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

A simple fix would be to use different suitable fixed sizes for tmp_file
and dev_file. However, the code can be improved here a little.

Use the libutil function util_path_sysfs() to build the sysfs path
string. This is more robust, as the function will figure out the correct
mount point of the sysfs. util_path_sysfs() will also terminate
execution, if no sysfs mount point could be found. That means, we can
get rid of check_sysfs().
Furthermore, the two variables (tmp_file, dev_file) can be combined to
one. Also, check the return value of open() and act accordingly.

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:01:42 +01:00
Jan Höppner
b5a7b13e71 zipl: Replace strcpy() and strcat()
Use misc_asprintf() for concatenating strings and get rid of the
following GCC8 compile warnings:

disk.c: In function ‘disk_get_info’:
disk.c:247:43: warning: ‘%d’ directive output may be truncated writing
between 1 and 11 bytes int o a region of size between 0 and 79
[-Wformat-truncation=]
    snprintf(ppn_cmd, sizeof(ppn_cmd), "%s %d:%d",
                                           ^~
disk.c:247:39: note: using the range [-2147483648, 2147483647] for
directive argument
    snprintf(ppn_cmd, sizeof(ppn_cmd), "%s %d:%d",
                                       ^~~~~~~~~~
disk.c:247:39: note: using the range [-2147483648, 2147483647] for
directive argument
disk.c:247:4: note: ‘snprintf’ output between 5 and 104 bytes into a
destination of size 80
    snprintf(ppn_cmd, sizeof(ppn_cmd), "%s %d:%d",
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      script_file, major(stats.st_rdev),
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      minor(stats.st_rdev));
      ~~~~~~~~~~~~~~~~~~~~~

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:01:42 +01:00
Jan Höppner
52b2cb8424 zipl: Replace sizeof() with DATA_SIZE() macro
Using the DATA_SIZE() macro gets rid of the following GCC8 compile
warning:

boot.c: In function ‘boot_init_fba_stage0’:
boot.c:120:2: warning: ‘memcpy’ forming offset [2, 152] is out of the
bounds [0, 1] of object ‘_binary_fba0_bin_start’ with type ‘char’
[-Warray-bounds]
  memcpy(stage0, DATA_ADDR(fba0), sizeof(*stage0));
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from boot.c:18:
../boot/data.h:24:13: note: ‘_binary_fba0_bin_start’ declared here
 extern char _binary_fba0_bin_start;
             ^~~~~~~~~~~~~~~~~~~~~~

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:01:41 +01:00
Jan Höppner
03b2bf028b zipl: Align struct lowcore to double page size
With GCC8 the following warning is displayed:

In file included from cio.h:15,
                 from stage2.h:15,
                 from menu.h:15,
                 from stage2.c:14:
s390.h:193:1: warning: alignment 1 of ‘struct _lowcore’ is less than 8
[-Wpacked-not-aligned]
 } __packed;
 ^

Fix by aligning struct _lowcore to double page size.

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:01:41 +01:00
Jan Höppner
81f9a67d6f libvmdump: Increase message buffer size
The message buffer of DumpException doesn't account for additional
strings such as strerror(), device nodes, or filenames. Make it a bit
larger to be safe.

This fixes the following GCC8 compile warnings:

In file included from vm_dump.h:62,
                 from vm_dump.cpp:17:
dump.h: In static member function ‘static Dump::DumpType
VMDump::getDumpType(const char*)’:
dump.h:46:16: warning: ‘ (’ directive writing 2 bytes into a region of size
between 1 and 200 [-W format-overflow=]
   sprintf(msg, "%s (%s)", m, strerror(errno));
                ^~~~~~~~~
dump.h:46:10: note: ‘sprintf’ output 4 or more bytes (assuming 203) into a
destination of size 200
   sprintf(msg, "%s (%s)", m, strerror(errno));
   ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dump.h:46:16: warning: ‘ (’ directive writing 2 bytes into a region of size
between 1 and 200 [-W format-overflow=]
   sprintf(msg, "%s (%s)", m, strerror(errno));
                ^~~~~~~~~
dump.h:46:10: note: ‘sprintf’ output 4 or more bytes (assuming 203) into a
destination of size 200
   sprintf(msg, "%s (%s)", m, strerror(errno));
   ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dump.h:46:16: warning: ‘ (’ directive writing 2 bytes into a region of size
between 1 and 200 [-W format-overflow=]
   sprintf(msg, "%s (%s)", m, strerror(errno));
                ^~~~~~~~~
dump.h:46:10: note: ‘sprintf’ output 4 or more bytes (assuming 203) into a
destination of size 200
   sprintf(msg, "%s (%s)", m, strerror(errno));
   ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:01:41 +01:00
Jan Höppner
c15f481181 libvtoc: Replace strncpy() with memcpy()
To assemble things like the volume id or fields of the format1 label
struct, strncpy() is used. Data copied here is later written to disk and
we don't want any terminating null byte ('\0') there. Therefore, we can
simply use memcpy() instead and get rid of the following GCC8 compile
warnings:

vtoc.c: In function ‘vtoc_init_format_1_8_label’:
vtoc.c:747:2: warning: ‘strncpy’ output truncated before terminating nul
copying 6 bytes from a s tring of the same length [-Wstringop-truncation]
  strncpy((char *) f1->DS1DSSN, "      ", 6);
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
vtoc.c:746:2: warning: ‘strncpy’ output may be truncated copying 44 bytes from
a string of length 79 [-Wstringop-truncation]
  strncpy(f1->DS1DSNAM, str, 44);
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
vtoc.c:761:2: warning: ‘strncpy’ output may be truncated copying 13 bytes from
a string of length 79 [-Wstringop-truncation]
  strncpy((char *)f1->DS1SYSCD, str, 13);
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
vtoc.c: In function ‘vtoc_volume_label_set_volser’:
vtoc.c:401:2: warning: ‘strncpy’ output may be truncated copying 6 bytes from a
string of length 6 [-Wstringop-truncation]
  strncpy(vlabel->volid, s, VOLSER_LENGTH);
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:01:41 +01:00
Jens Remus
4170cceb52 cpuplugd: close config file after use in parse_configfile()
Resolves Cppcheck error:
[cpuplugd/config.c:204]: (error) Resource leak: filp

Cc: Gerald Schaefer <gerald.schaefer@de.ibm.com>
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:01:41 +01:00
Jens Remus
a648dbb014 zkey: enhance file read/write error handling
fread()/fwrite() return the unsigned count of elements read/written or a
short count or zero in case of an error. Check if the number of elements
read/written matches the expectation. In case of fread(), if it does not
match, check if an error occurred and otherwise assume the file to be too
small. In case of fwrite(), if it does not match, assume an error.

Resolves Cppcheck style warnings:
[zkey/pkey.c:161]: (style) Checking if unsigned variable 'count' is less than zero.
[zkey/pkey.c:209]: (style) Checking if unsigned variable 'count' is less than zero.
[zkey/pkey.c:299]: (style) Checking if unsigned variable 'count' is less than zero.

Cc: Ingo Franzki <ifranzki@de.ibm.com>
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:01:41 +01:00
Jens Remus
322d51e5e4 zipl: remove redundant duplicate expression
Resolves Cppcheck style warning:
[zipl/boot/stage3.c:260]: (style) Same expression on both sides of '&&'.

Cc: Stefan Haberland <stefan.haberland@de.ibm.com>
Cc: Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:01:41 +01:00
Jens Remus
a1db08160d zipl: check array limits before indexing
Resolves Cppcheck warning:
[zipl/boot/menu.c:126]: (style) Array index 'i' is used before limits check.

Cc: Stefan Haberland <stefan.haberland@de.ibm.com>
Cc: Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:01:41 +01:00
Jens Remus
31b77e1646 zdev: fix memory leak in misc_readlink()
When realloc() fails to allocate memory it returns NULL and the original
block is left untouched. In that case return the potentially larger
original block.

Found using Cppcheck:
[zdev/src/misc.c:1106]: (error) Memory leak: name

Cc: Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:01:41 +01:00
Jens Remus
a4acf7c991 zdev: fix copying of modified flag
The modified flag was actually never copied during merge of setting lists.
Copy the modified flag if requested.

Found using Cppcheck:
[zdev/src/setting.c:553]: (warning) Redundant assignment of 'n->modified' to itself.

Cc: Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:01:41 +01:00
Jens Remus
17cade6e7f fdasd: fix resource leak in fdasd_parse_conffile()
Deallocate the file descriptor.

Found with Cppcheck:
[fdasd/fdasd.c:731]: (error) Resource leak: fd

Cc: Stefan Haberland <sth@linux.ibm.com>
Cc: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:01:41 +01:00
Jens Remus
90ea5d9e5d fdasd: check array limits before indexing
Found using Cppcheck:
[fdasd/fdasd.c:261]: (style) Array index 'from' is used before limits check.

Cc: Stefan Haberland <sth@linux.ibm.com>
Cc: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:01:41 +01:00
Jens Remus
6accffd583 fdasd: fix possible integer overflow
The computation of blk in functions fdasd_check_volume() and
fdasd_write_vtoc_labels() contained the possibility for an undetected
unsigned integer overflow. Unconditionally subtracting one from the
return value of function cchhb2blk() may cause an unsigned integer
overflow, as cchhb2blk() may return zero if cc, hh, and b are all zero.

Resolves Cppcheck style warning:
[fdasd/fdasd.c:1260]: (style) Checking if unsigned variable 'blk' is less than zero.

Cc: Stefan Haberland <sth@linux.ibm.com>
Cc: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:01:41 +01:00
Jens Remus
4e5afb9b71 cmsfs-fuse: do not check if unsigned is less than zero
Only check if size is zero and not if equal or less than zero. This is
safe, as size is only decremented by rlen, which is either less than or
equal to size. So size may never overflow.

Resolves Cppcheck style warning:
[cmsfs-fuse/cmsfs-fuse.c:3746]: (style) Checking if unsigned variable 'size' is less than zero.

Cc: Gerald Schaefer <gerald.schaefer@de.ibm.com>
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:01:41 +01:00
Jens Remus
9f247795f3 cmsfs-fuse: remove unused variable in add_record_ext()
Resolves Cppcheck style warning:
[cmsfs-fuse/cmsfs-fuse.c:936]: (style) Variable 'i' is modified but its new value is never used.

Cc: Gerald Schaefer <gerald.schaefer@de.ibm.com>
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:01:41 +01:00
Jens Remus
71976f8e4b cmsfs-fuse: fix memory leak in cmsfs_rename()
Free the string uc_new_name that gets allocated using strdup().

Found with Cppcheck:
[cmsfs-fuse/cmsfs-fuse.c:2865]: (error) Memory leak: uc_new_name

Cc: Gerald Schaefer <gerald.schaefer@de.ibm.com>
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:01:41 +01:00
Michael Holzheu
851f685993 Makefile: Add dependency between libvmcp and libutil to fix -j builds
For linking the "libvmcp" example program the "libutil" is required.
Therefore when the "libvmcp" directory is entered in a parallel build
and the "libutil.a" file has not yet been created, a second "libutil"
build is triggered which can then lead to build errors like the following:

 ar: libutil.a: File format not recognized
 ar: libutil.a: No such file or directory
 make[2]: Leaving directory '/builddir/build/BUILD/s390-tools-2.6.0/libutil'
 make[2]: *** [../common.mak:246: libutil.a] Error 1
 make[1]: *** [../common.mak:246: libutil.a] Error 1
 make[1]: *** Waiting for unfinished jobs....
 make[1]: *** [../common.mak:315: ..//libutil/libutil.a] Error 2
 make[1]: Leaving directory '/builddir/build/BUILD/s390-tools-2.6.0/libvmcp'
 make: *** [Makefile:57: libvmcp] Error 2
 make: *** Waiting for unfinished jobs....
ving directory '/builddir/build/BUILD/s390-tools-2.6.0/libutil'
 make: *** [Makefile:57: libutil] Error 2
 error: Bad exit status from /var/tmp/rpm-tmp.wCulxB (%build)

So fix this and add a dependency between libvmcp and libutil.

Signed-off-by: Michael Holzheu <holzheu@linux.ibm.com>
Reviewed-by: Thomas Richter <tmricht@linux.vnet.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:01:41 +01:00
Ingo Franzki
9100327092 zkey: Include /sbin into PATH when executing commands
When using 'zkey cryptsetup' with the '--run' option,
it might not find the executable to execute when those
are in /sbin.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:01:41 +01:00
Jan Höppner
e2d433bb10 dasdinfo: Display error messages on stderr output
Change all error messages from printf() to warnx().

While at it, remove the punctuation mark for some of the error messages.

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-11-16 15:01:41 +01:00
Jan Höppner
d6925a30da New release s390-tools-2.7.0
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-31 11:44:17 +01:00
Ingo Franzki
fe4cc7c479 zkey: add generated files to .gitignore
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-31 11:44:17 +01:00
Ingo Franzki
fa3cabc8af zkey: Makefile: Don't rebuild .o.d files on 'make install'
The .o.d make targets in common.mak do not expect that
header files are generated by a make target. When a new header
file is generated, the .o.d targets will be rebuilt on the
next make invocation, because that new header file is then
detected, and is then treated as a new dependency of all .o.d
targets.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-31 11:44:17 +01:00
Jan Höppner
5a9b56f814 lscss: Fix email address
The linux.vnet.ibm.com addresses will be become disfunct by eoy.

Signed-off-by: Stefan Raspl <raspl@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-31 11:44:17 +01:00
Julian Wiedmann
20145b6d06 qethqoat: add OSA-Express7S support
Add the missing identifiers to report the card name and link speed.

Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-25 13:42:12 +02:00
Ingo Franzki
9561a0b983 zkey: Enhance error message on key store open
Print a meaningful reason when the keystore can not be
accessed, e.g. because the user is not allowed to access
the keystore directory.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-25 11:00:52 +02:00
Philipp Rudo
97fa88299f zfcpdump: Remove unneeded include <zlib.h>
Dump compression was a feature of the file system dumper which was removed
several years ago. This include is a leftover. Remove it.

Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-25 11:00:52 +02:00
Jan Höppner
aaaebb2030 zpcictl: Change wording of man-page and help output
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-25 11:00:52 +02:00
Karsten Graul
ff2a403bd2 osasnmpd: remove unused code, improve readability
Remove unused code because query_OSA_EXP does actually never return -1.
So make its return value unsigned and remove all checks for negative
return values.

Signed-off-by: Karsten Graul <kgraul@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-25 11:00:52 +02:00
Karsten Graul
66ed1727f9 osasnmpd: start without real OSA devices
Osasnmpd would start without any devices, but refuses to start when all
devices are no real OSA devices.
Start osasnmpd in this case because it re-scans via update_mib_info
whenever the interface data changes.

Reviewed-by: Julian Wiedmann <jwi@linux.ibm.com>
Signed-off-by: Karsten Graul <kgraul@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-25 11:00:52 +02:00
Ingo Franzki
c33cc5a619 zkey: Makefile: Avoid relink of modules during 'make install'
Because targets check-dep-zkey and check-dep-zkey-cryptsetup
do not produce any file, any targets that have a pre-req on those
targets are rebuilt during 'make install'.

Also correct .PHONY targets.

Fixes: https://github.com/ibm-s390-tools/s390-tools/issues/46
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-22 14:02:35 +02:00
Karsten Graul
cd46297d7c s390-tools/utils: handle util_scandir errors correctly
The util_scandir_* functions may return 0 or -1, in which case no vector
is allocated in libutil/util_scandir.c. util_ptr_vec_free, called by
util_scandir_free or directly from lschp.c and lsscm.c, does always
call free for the vector which might be not initialized.

Fix this by always initializing the vector with NULL in __scandir and
add some api hardening by checking the vector and count in
util_ptr_vec_free before iterating over the vector.
And update the comment for util_scandir to indicate that -1 may be
returned in error cases plus that the vector is initialized with NULL.

Fixes: https://github.com/ibm-s390-tools/s390-tools/issues/43
Reported-by: Cornelia Huck <cohuck@redhat.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Karsten Graul <kgraul@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-19 15:32:53 +02:00
Dimitri John Ledkov
07b11982e3 zdev: Trigger generic_ccw devices on any kernel module loads.
Generic CCW device can use any driver, and the value of the driver is
not known ahead of time. To avoid the race between loading and binding
a kernel module, and devices added - retrigger generic-ccw devices on
any kernel module load.

Fixes: https://github.com/ibm-s390-tools/s390-tools/issues/37
Link: https://bugs.launchpad.net/ubuntu-z-systems/+bug/1794308
Closes: https://github.com/ibm-s390-tools/s390-tools/pull/45

Signed-off-by: Dimitri John Ledkov <xnox@ubuntu.com>
Acked-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-19 15:32:40 +02:00
Dimitri John Ledkov
35348c302b zdev/initramfs: add s390-tools- prefix to hook, due to conflicts.
Unfortunately zdev hook already exists in Ubuntu, from an unrelated
project. ZFS uses zdev/zpool names, and ships a zdev hook to do ZFS
specific initialisation. It is available on s390x and thus results in
file-conflict upon installing both. Thus renaming this zdev hook to
s390-tools-zdev.

Closes: https://github.com/ibm-s390-tools/s390-tools/pull/41
Signed-off-by: Dimitri John Ledkov <xnox@ubuntu.com>
Acked-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-19 15:31:54 +02:00
Dimitri John Ledkov
35312d0c47 cpacfstatsd.service: only run on LPARs.
Add ConditionVirtualization=no to the service file such that it is
only started on LPARs. This service cannot run on z/VM nor KVM, and
fails resulting in a degraded boot.

Closes: https://github.com/ibm-s390-tools/s390-tools/pull/38
Signed-off-by: Dimitri John Ledkov <xnox@ubuntu.com>
Acked-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-19 15:31:40 +02:00
Jan Höppner
342c6a3707 zpcictl: Make device node for NVMe optional
At the moment, if we specify the slot address of an NVMe device but
can't find the corresponding device node, the execution is terminated.

This is a bit harsh as the device node is rather optional and only
necessary to collect S.M.A.R.T. data. We should still be able to issue
the error reporting, even if we couldn't determine the device node.

Therefore, make sure the device node for NVMe devices is optional by
changing various error messages to warnings.
Change sysfs_get_slot_addr() to have a return value and work with that
accordingly.
Also make sure, that execution is terminated when a valid device node
was specified but no matching slot address was determined. The slot
address is necessary to issue the error reporting commands.

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-11 14:41:32 +02:00
Jan Höppner
e2a8d85916 zpcictl: Read device link to obtain device address
The address sysfs attribute might not be present on some older kernel
levels. Read the device link instead using readlink() to obtain the
address.

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-11 14:41:32 +02:00
Jan Höppner
8f0496b26a zpcictl: Use fopen() instead of open() for writes
Be consistent with the rest of the code and use fopen() rather than
open().

Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-11 14:41:32 +02:00
Jan Höppner
d03be73536 zpcictl: Rephrase man page entries and tool output
Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-11 14:41:32 +02:00
Michael Holzheu
a87268d62e util_path_example: Fix usage message
Document that for the "sysfs" invocation the mount point is optional.

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-11 14:41:32 +02:00
Michael Holzheu
9cc06a0529 util_proc: Fix typos in description of util_proc_mnt_get_entry()
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-11 14:41:32 +02:00
Michael Holzheu
3b1ccce515 util_proc: Fix return code handling for util_proc_mnt_get_entry()
Correctly return -1 if the requested file system is not mounted.

Reported-by: Peter Morjan <peter.morjan@de.ibm.com>
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-11 14:41:32 +02:00
Hans Wippel
ffe91d1b30 zdev: fix qeth BridgePort and VNICC conflict checking
This patch fixes false positives when attributes are checked for
conflicts between BridgePort and VNICC.

Signed-off-by: Hans Wippel <hwippel@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-11 14:41:32 +02:00
Hendrik Brueckner
f35c5d01fd zpcictl: include sys/sysmacros.h to avoid minor/major glibc warnings
The minor()/major() function definitions are moved to sys/sysmacros.h
and will be removed from sys/types.h.  To correct below warning, simply
include sys/sysmacros.h.

  zpcictl.c: In function ‘sysfs_get_slot_addr’:
  zpcictl.c:184:13: warning: In the GNU C Library, "major" is defined
   by <sys/sysmacros.h>. For historical compatibility, it is
   currently defined by <sys/types.h> as well, but we plan to
   remove this soon. To use "major", include <sys/sysmacros.h>
   directly. If you did not intend to use a system-defined macro
   "major", you should undefine it after including <sys/types.h>.
    major = major(dev_stat.st_rdev);
               ^~~~~~~~~~~~~~~~~~~~~

Signed-off-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
2018-10-02 09:55:27 +02:00
Jan Höppner
b23c35c390 zcryptctl: Add binary to .gitignore
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-29 12:41:54 +02:00
Jan Höppner
177cf8cfeb zpcictl: Introduce new tool zpcictl
zpcictl is used to manage PCI devices on z Systems. In this first
version it is mainly used to handle erroneous PCI devices by changing
their state and make those changes known to the SE. Log data, such as
S.M.A.R.T. data for NVMe devices, is sent alongside those state changes.

The state change is issued by sending data via the PCI 'report_error'
sysfs attribute. It's a binary attribute which will cause the host to
send an Adapter Notification Event.

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-29 12:41:44 +02:00
Harald Freudenberger
f05f7d656b zcryptctl: new tool zcryptctl for multiple zcrypt node management
With the latest kernel comes an extension for the zcrypt
device driver to support multiple zcrypt device nodes.

Here is the userspace part of this which adds a new
application zcryptctl for user friendly management of
this feature.

Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-29 12:41:31 +02:00
Dan Horák
0bf4f1b957 zkey: Be explicit about linking the tools
I've met cases when the make's default rule for linking was used instead
omitting the ALL_LDFLAGS variable. The linking rule from common.mak is
defined for linking *.o files only, here we have libutil.a too.

Closes: https://github.com/ibm-s390-tools/s390-tools/pull/35
Signed-off-by: Dan Horák <dan@danny.cz>
Acked-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-29 12:41:28 +02:00
Dan Horák
cd38119888 zkey: Be consistent when referring to libutil.a
Link: https://github.com/ibm-s390-tools/s390-tools/pull/35
Signed-off-by: Dan Horák <dan@danny.cz>
Acked-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-29 12:41:21 +02:00
Dan Horák
cadef5c0ff zkey: Drop redundant include
Link: https://github.com/ibm-s390-tools/s390-tools/pull/35
Signed-off-by: Dan Horák <dan@danny.cz>
Acked-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-29 12:41:15 +02:00
Dan Horák
02e1c783f6 Makefile: drop LOADLIBES variable
Remove deprecated LOADLIBES variable from the Makefile rules, LDLIBS
serves the same purpose these days.

Link: https://github.com/ibm-s390-tools/s390-tools/pull/35
Signed-off-by: Dan Horák <dan@danny.cz>
Acked-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-29 12:41:08 +02:00
Eric Sandeen
07e30951f8 zipl: use FIEMAP mapping ioctl if it exists
zipl currently uses the FIBMAP ioctl to map blocks for the bootloader;
on XFS, if FIBMAP is requested on a reflinked file, it will fail -
and FIBMAP returns 0 in this case, which is indistinguishable from a
hole.  This causes boot to fail because the file is not mapped.

We can use the FIEMAP ioctl instead, which is able to map reflinked
files.  While FIEMAP is able to map entire extents at once, here we
simply use it to obtain the mapping block-by-block so that it fits
in with the current FIBMAP calls.

Fixes: https://github.com/ibm-s390-tools/s390-tools/issues/34
Closes: https://github.com/ibm-s390-tools/s390-tools/pull/36
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Tested-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-17 14:28:18 +02:00
Harald Freudenberger
0a0b4c3826 lszcrypt: support for alternate zcrypt device drivers
With kernel 4.19 there comes an extension to the existing
AP bus which supports alternate zcrypt drivers. For details
about this see kernel patch "s390/zcrypt: AP bus support for
alternate driver(s)". So now lszcrypt displays the driver
name in verbose mode. As some of the information displayed
by lszcrypt was based on sysfs attributes, which are only
available when the default zcrypt driver is bound to the
device, this also needed some rework. If a sysfs attribute
is not available because of an alternate driver binding
(or no driver) a question mark is printed into the field.

Together with this a slight rework of the displayed information
has been done. The two columns for pending requests and pending
replies has been merged to one pending column and the column
sizes have been adjusted.

Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-17 14:26:29 +02:00
Peter Oberparleiter
eade995185 zdsfs: Direct --help and --version output to stdout
zdsfs writes output for --help and --version to stderr. This is
likely because zdsfs calls into a FUSE function for additional
usage output that also writes to stderr (prior to FUSE 3.0.0).

To be consistent with other s390-tools and GNU coding guide lines,
fix this by using stdout for zdsfs generated output, and by
redirecting stderr to stdout before calling the FUSE function.

Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-17 14:23:47 +02:00
Peter Oberparleiter
0eba8d11df tape390_display: Direct --help output to stdout
tape390_display writes output for --help to stderr. To be consistent
with other s390-tools and GNU coding guide lines, fix this by using
stdout for tool-generated usage help.

Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-17 14:23:47 +02:00
Peter Oberparleiter
257490366b util_prg_example: Add --help and --version options
Add missing long options for --help and --version in util_prg_example.

Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-17 14:23:47 +02:00
Peter Oberparleiter
5ef1320a7b iucvconn/iucvtty: Direct --help output to stdout
Both iucvconn and iucvtty write output for --help to stderr. To be
consistent with other s390-tools and GNU coding guide lines,
fix this by using stdout for tool-generated usage help.

Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-17 14:23:47 +02:00
Peter Oberparleiter
f2f572fa70 hmcdrvfs: Direct --help and --version output to stdout
hmcdrvfs writes output for --help and --version to stderr. This is
likely because hmcdrvfs calls into a FUSE function for additional
usage output that also writes to stderr (prior to FUSE 3.0.0).

To be consistent with other s390-tools and GNU coding guide lines,
fix this by using stdout for hmcdrvfs generated output, and by
redirecting stderr to stdout before calling the FUSE function.

Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-17 14:23:47 +02:00
Peter Oberparleiter
e655f0cd7b cmsfs-fuse: Direct --help and --version output to stdout
cmsfs-fuse writes output for --help and --version to stderr. This is
likely because cmsfs-fuse calls into a FUSE function for additional
usage output that also writes to stderr (prior to FUSE 3.0.0).

To be consistent with other s390-tools and GNU coding guide lines,
fix this by using stdout for cmsfs-fuse generated output, and by
redirecting stderr to stdout before calling the FUSE function.

Also remove an inactive call to add FUSE version output on --version to
be consistent with other FUSE-based s390-tools.

Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-17 14:23:47 +02:00
Peter Oberparleiter
68b46eea7a zipl: Add missing build dependency
Building zipl from outside the zipl/ sub-directory fails due to a
missing dependency:

  # cd s390-tools
  # make -C zipl/src/ zipl
  boot.c:18:10: fatal error: ../boot/data.h: No such file or directory
   #include "../boot/data.h"

This is because boot/data.h needs to be generated before src/boot.c can
be compiled. Fix this by adding the missing dependency to the zipl
Makefile.

Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-04 14:09:24 +02:00
Ingo Franzki
9894e391ef zkey: Man page correction
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-04 14:09:24 +02:00
Steffen Maier
5982fd98bf CHANGELOG: lstape, lsluns: handle non-zfcp; lin_tape multiple paths
Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-04 14:09:24 +02:00
Steffen Maier
d5291eed1c lstape: fix SCSI HBA CCW device bus-ID e.g. for virtio-scsi-ccw
Get the SCSI HBA device bus-ID in general for HBAs on the CCW bus.

Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Fedor Loshakov <loshakov@linux.ibm.com>
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-04 14:09:24 +02:00
Steffen Maier
34260f1736 lstape: fix SCSI output description in man page
Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-04 14:09:24 +02:00
Steffen Maier
b9b3d2d230 lstape: fix description of --type and <devbusid> filter for channel tapes
Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-04 14:09:24 +02:00
Steffen Maier
4cf8f5f46c lstape: fix to prevent error messages if there are non-zfcp SCSI devices
Assume "N/A" for non-zfcp SCSI devices, such as iSCSI or virtio-scsi-ccw,
to not erroneously access absent zfcp-specific sysfs attributes.

Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-04 14:09:24 +02:00
Steffen Maier
eba744a25e lsluns: fix to prevent error messages if there are non-zfcp SCSI devices
Simply skip non-zfcp SCSI devices, such as iSCSI or virtio-scsi-ccw,
to not erroneously access absent zfcp-specific sysfs attributes.

Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-04 14:09:24 +02:00
Steffen Maier
80e0c41b89 lstape: fix output without SCSI generic (sg)
The default bash setting have nullglob disabled so if
$SCSI_DEV/scsi_generic*
aka
/sys/bus/scsi/devices/*:*:*:*/scsi_generic*
does not match anything, it leaves the glob pattern unmodified and
SG_DEV=$(basename $SG_DEV/*)
results in the literal:
*
If $SG_INQ exists, it invoked sg_inq with more than the one allowed
positional argument for a SCSI generic device node:
sg_inq /dev/*
Causing error messages and the usage of sg_inq to land in $TAPE_SERIAL.

To not have to rely on the nullglob setting, explicitly check for the
existence of $SCSI_DEV/scsi_generic before evaluating
SG_DEV=$(basename $SG_DEV/*).

Also handle availability of sg_inq but absence of scsi_generic
individually to provide the user with a hint if only sg is missing.

Suggested-by: Eric Farman <farman@linux.vnet.ibm.com>
Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Cc: Eric Farman <farman@linux.vnet.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-04 14:09:24 +02:00
Steffen Maier
cdc787db1b lstape: fix to prefer sysfs to find lin_tape device name for SCSI device
This should be more stable than parsing the IBM lin_tape proc-fs output.
If sysfs is not available or provides no match, fall back to proc-fs.

An alternative to "ls -1d ... | head -n1" would have been to use
"shopt -s extglob; ls -d $SCSI_DEV/lin_tape/$DEV_NAME+([0-9])"
but I did not want to have to rely on extglob potentially influencing
other old code of lstape.

Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-04 14:09:24 +02:00
Steffen Maier
ef4dc7a45b lstape: fix output with SCSI lin_tape and multiple paths to same tape/changer
https://www.ibm.com/developerworks/linux/linux390/s390-tools-1.8.0.html
before the first upstream commit b627b8d8e1 ("Initial s390-tools-2.0.0
import") introduced SCSI tape/changer output for lstape. It used the SCSI
device serial number as lookup key to find a match in IBM lin_tape device
driver proc-fs output for a given SCSI device name. Since multiple paths
to the same tape/changer have the same serial number, multiple matches can
occur and distort the output:

% lstape
...
SCSI tape devices (found 12):
...
Generic Device        Target       Vendor   Model            Type     State
sg0     IBMtape0      3            0:0:0:0  IBM              ULT3580-TD6 tapedrv
running
sg1     IBMchanger0   1            2        3                0:0:0:1  IBM
3573-TL changer       running
...

There are unexpected additional Device suffix numbers for each additional
path of the same tape/changer (independent of actual path failover
enablement in lin_tape). The multiple matches above cause excess arguments
to printf. Explaining the resulting output, the bash man page says:
"The format is reused as necessary to consume all of the arguments."
This also causes a wrong number of found devices.

Current lin_tape (v3.0.31) uses the printf format string
"%-8d%-12s%-25s%-16s%-16s%-10s" for fixed column proc-fs output.
This causes the following example input to lstape:

==> /proc/scsi/IBMchanger <==
lin_tape version: 3.0.31
lin_tape major number: 251
Attached Changer Devices:
Number  model       SN                       HBA             SCSI            FO Path
0       3573-TL     00L4U78W6497_LL0         Virtio SCSI HBA 0:0:0:1         Primary
1       3573-TL     00L4U78W6497_LL0         Virtio SCSI HBA 0:0:1:1         Alternate
2       3573-TL     00L4U78W6497_LL0         Virtio SCSI HBA 1:0:1:1         Alternate
3       3573-TL     00L4U78W6497_LL0         Virtio SCSI HBA 1:0:0:1         Alternate

==> /proc/scsi/IBMtape <==
lin_tape version: 3.0.31
lin_tape major number: 251
Attached Tape Devices:
Number  model       SN                       HBA             SCSI            FO Path
0       ULT3580-TD6 10WT037733               Virtio SCSI HBA 0:0:0:0         Primary
1       ULT3580-TD6 10WT037701               Virtio SCSI HBA 0:0:1:0         Primary
2       ULT3580-TD6 10WT037701               Virtio SCSI HBA 1:0:1:0         Alternate
3       ULT3580-TD6 10WT037733               Virtio SCSI HBA 1:0:0:0         Alternate

If that was reliable and stable, we could use fixed column parsing:
			IBM_IDX=$(
				awk 'BEGIN {
					FIELDWIDTHS="8 12 25 16 16 10"
				}
				gensub(" ","","g",$5) == "'$SCSI_ID'"{
					print gensub(" ","","g",$1)
				}' /proc/scsi/$DEV_NAME
			)
However, we can hardly guarantee a field value always fits into the left-
adjusted columns (printf won't cap to field width!). Also, the fixed column
format changed between lin_tape v3.0.20 and v3.0.18 from
"%-8d%-12s%-18s%-16s%-16s%-10s" with less width for the 'SN' field.
The column format also changed between v2.2.0 and v1.37.0 from
"%-8d%-12s%-18s%-32s%-10s" where the 'SCSI' field did not even exist.
Likely that was the reason for the original Serial lookup in lstape.

As can be seen in the example, at least the HBA device driver string can
contain whitespace and breaks the field numbers with tokenized parsing.
We want to match column 5 (SCSI) but above we would match against the
string 'SCSI' as part of "Virtio SCSI HBA" instead of e.g. '0:0:0:0'.

The following works currently knowing that the last two columns do not
contain white space. But it can also fail if the value of field
'HBA' does not fit into the left-adjusted columns so there is no white
space between columns 'HBA' and 'SCSI' making them collapse:
awk '$(NF-1) == "'$SCSI_ID'" { print $1 }' /proc/scsi/$DEV_NAME

Grep for the SCSI device name as word (to skip names with same substring,
such as 0:0:1:1 also matching 0:0:1:10) and cut the first field 'Number'.
If there is no SCSI column at all (and no SCSI LLDD or other column with a
name accidentally matching an existing SCSI device name), we get no match
and better bail out with the initialized "N/A" for the lstape column
"Device". If the SCSI column exists, the SCSI device names are unique and
we always get at most one match.

Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-04 14:09:24 +02:00
Philipp Rudo
cb3e949772 zfcpdump: Fix incompatible cast compile warning
When zfcpdump is built you get a compile warning

zfcpdump.c: In function ‘init_sig’:
zfcpdump.c:307:24: warning: cast between incompatible function types from ‘void (* (*)(int,  siginfo_t *, void *))(int)’ {aka ‘void (* (*)(int,  struct <anonymous> *, void *))(int)’} to ‘void (*)(int)’ [-Wcast-function-type]
  g.sigact.sa_handler = (__sighandler_t)dump_sig_handler;

Furthermore the man pages for sigaction says

$man 2 sigaction
[...]
       If SA_SIGINFO is specified in sa_flags, then sa_sigaction (instead
       of sa_handler) specifies the signal-handling function for signum.
       This function receives three arguments, as described below.
[...]

Because SA_SIGINFO is set, using sa_handler at all is wrong in this case.

Fix this by giving dump_sig_handler the correct return type and assign it
to sa_sigaction.

Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-04 14:09:24 +02:00
Philipp Rudo
f02de298c1 zfcpdump: Remove module load
The zfcpdump kernel is built without module support. Furthermore the initrd
doesn't contain modprobe. So trying to load modules using modprobe in
zfcpdump userspace doesn't really make sense.

Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-04 14:09:24 +02:00
Philipp Rudo
eb0dc13c88 zfcpdump: Add install script for zfcpdump
Since version 198 (Feb 2013) systemd contains kernel-install, a script
managing kernel installs. This script allows execution of drop-in scripts
for customization. Add such a drop-in script to s390-tools to handle the
installation of zfcpdump kernels.

It's main purpose is to manage a link to the latest installed zfcpudump
kernel at ZFCPDUMP_IMAGE, where zipl expects to find the image to install
for a SCSI dumper.

The script supports two installation modes. One recommended by the
BootLoaderSpecs [1] to /boot/<machine-id>/<kernel-version> directories and
one directly to /boot. In the second case files are renamed during
installation to <original-name>-<kernel-version> to guarantee unique names.

Because the zfcpdump kernel is so special make the script stand-alone and
prevent any other script from being executed (exit 77) when a zfcpdump is
installed. Especially avoid functionality like creating an initrd (already
provided by s390-tools) or creating a boot entry (the zfcpdump kernel
should not be used for any other purpose than dumping).

The script requires systemd >= 203.

[1] https://www.freedesktop.org/wiki/Specifications/BootLoaderSpec/

Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-04 14:09:24 +02:00
Philipp Rudo
d08bd23c1e zipl: Move macro definition to Makefile
In the zipl Makefile macros are defined with the sole purpose to define
other macros in zipl.h. Remove this unnecessary indirection.

Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-04 14:09:24 +02:00
Philipp Rudo
724f1fea2c Makefile: Rename ZFCPDUMP_PART_* macros
The file system dumper no longer exists. So there is no need in keeping
'PART' to distinguish between the file system and the partition dumper.
Adjust the macro name to the usage in zipl by removing 'PART'.

While at it also adjust the file names the macros stand for.

Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-04 14:09:24 +02:00
Philipp Rudo
dcc63e6dfc zipl: Rename FSDUMP_PART_* macros
The macro names are a mixture of the original file system dumper (FSDUMP)
and its extension to cut the file system and write directly to a partition
(PART). The original dumper no longer exists and today the feature is
called zfcpdump. Prevent confusion by renaming the macros to fit todays
usage.

Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-04 14:09:24 +02:00
Philipp Rudo
576034e94a zfcpdump: Remove unused macros
There are no more users for these macros. Remove them.

Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-04 14:09:24 +02:00
Jan Höppner
3ec49ba7bd Prepare for next release
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-04 14:09:24 +02:00
328 changed files with 23323 additions and 3413 deletions

10
.gitignore vendored
View File

@@ -68,6 +68,8 @@ zconf/qeth/lsqeth
zconf/scm/lsscm
zconf/zcrypt/chzcrypt
zconf/zcrypt/lszcrypt
zconf/zcrypt/zcryptctl
zconf/zcrypt/zcryptstats
zdev/src/chzdev
zdev/src/chzdev_usage.c
zdev/src/lszdev
@@ -76,7 +78,8 @@ zdsfs/zdsfs
zdump/zgetdump
zfcpdump/cpioinit
zfcpdump/zfcpdump_part
zfcpdump/zfcpdump_part.rd
zfcpdump/zfcpdump-initrd
zfcpdump/10-zfcpdump.install
ziomon/ziomon_mgr
ziomon/ziomon_util
ziomon/ziomon_zfcpdd
@@ -89,3 +92,8 @@ zipl/src/chreipl_helper.device-mapper
zipl/src/zipl
zipl/src/zipl_helper.device-mapper
zkey/zkey
zkey/zkey-cryptsetup
zkey/check-dep-zkey
zkey/check-dep-zkey-cryptsetup
zkey/detect-libcryptsetup.dep
zpcictl/zpcictl

View File

@@ -19,6 +19,7 @@ List of all individuals having contributed content to s390-tools
- Dimitri John Ledkov
- Eberhard Pasch
- Einar Lueck
- Eric Sandeen
- Erwin Vicari
- Eugene Crosser
- Eugene Dvurechenski
@@ -46,6 +47,7 @@ List of all individuals having contributed content to s390-tools
- Jan Glauber
- Jan Hoeppner
- Jan Willeke
- Jason J. Herne
- Javier Martinez Canillas
- Jean-Baptiste Joret
- Jens Remus
@@ -55,7 +57,9 @@ List of all individuals having contributed content to s390-tools
- Kittipon Meesompop
- Klaus-Dieter Wacker
- Lakhvich Dmitriy
- Marc Hartmayer
- Mark Dettinger
- Mark Post
- Martin Kammerer
- Martin Peschke
- Martin Petermann
@@ -67,6 +71,7 @@ List of all individuals having contributed content to s390-tools
- Michael Mueller
- Mijo Safradin
- Mikhail Zaslonko
- Niklas Schnelle
- Peter Oberparleiter
- Peter Tiedemann
- Philipp Kern
@@ -96,6 +101,7 @@ List of all individuals having contributed content to s390-tools
- Thomas Richter
- Thomas Spatzier
- Thomas Weber
- Tuan Hoang
- Ursula Braun
- Utz Bacher
- Vasily Gorbik

View File

@@ -1,6 +1,193 @@
Release history for s390-tools (MIT version)
--------------------------------------------
* __v2.6.0 (2018-08-10)__
* __v2.13.0 (2020-05-06)__
For Linux kernel version: 5.5 / 5.6
Add new tool:
- genprotimg: Add genprotimg to create protected virtualization images
- genprotimg: Add sample script to verify host keys
Changes of existing tools:
- dbginfo: Gather bridge related data (using 'bridge')
- dbginfo: Removed collection of /var/log/opencryptoki/
- dbginfo: collect softnet_stat
- dbginfo: gather ethtool output for per-queue coalescing
- ipl_tools: Support clear attribute for FCP and CCW re-IPL
- zdev: Report FC Endpoint Security of zfcp devices
- zdev/dracut/95zdev/module-setup.sh: Add ctcm kernel module
- cpumf/data: Add new deflate counters for IBM z15
- zkey: Add support for EP11 secure keys
- zpcictl: Initiate recover after reset
- zipl: Add support for NVMe devices
- zipl: A multitude of code and stability improvements
Bug Fixes:
- zipl: Prevent endless loop during IPL
- zipl/libc: Fix potential buffer overflow in printf
- zkey: Fix listing of keys on file systems reporting DT_UNKNOWN
- zkey: Fix display of clear key size for XTS, CCA-AESCIPHER, and EP11-AES XTS keys
* __v2.12.0 (2019-12-17)__
For Linux kernel version: 5.4
Changes of existing tools:
- dbginfo: Gather qdisc related data (using 'tc')
- dbginfo: Gather extended network statistics (using 'ip link')
- dbginfo: Collect all files under /usr/lib/systemd/system/
- cpumf/cpumf_helper: Add IBM z15 machine name
- zkey: Display MKVP when validating a secure key
- zkey: Cross check APQNs when generating, validating, or importing secure keys,
and when changing APQN associations
- zkey: Check crypto card level during APQN cross checking
- zkey: Add support for generating, validating, and re-enciphering AES CIPHER keys
- zkey-cryptsetup: Add --to-new and --from-old options
- zkey-cryptsetup: Allow setkey to set different key types
- lszcrypt/chzcrypt: CEX7S exploitation support
- zcryptstats: Add support for CEX7 crypto card
- zipl: Ship a minimal zipl.conf
- zipl: Add value of target= as search path for BLS case
Bug Fixes:
- dasdview: Fix exit status in error cases
- zipl: Fix various compile warnings
- zipl: Fix dependency generation in zipl/boot
- zipl: Fix entry point for stand-alone kdump
- zipl: Add missing options to help output
* __v2.11.0 (2019-09-06)__
For Linux kernel version: 5.3
Changes of existing tools:
- dasdfmt: Add support for thin-provisioned volumes
- lsdasd: Add support for thin-provisioned volumes
- libdasd: Provide function to utilise release space ioctl
- libdasd: Provide function to read ese sysfs attribute
- dbginfo: Add lspci (PCI devices) and smc_dbg (SMC sockets)
- dbginfo: Gather ethtool related data
Bug Fixes:
- zipl: Fix freeing of uninitialized pointer
- zipl: Set correct secure IPL default value
* __v2.10.0 (2019-07-31)__
For Linux kernel version: 5.2
Changes of existing tools:
- zdev: Add zfcp dix parameter handling
- cpumf: Add support for CPU-Measurement Facility counters SVN 6
Bug Fixes:
- libutil: Add functions to test path is read/write-only
- zdev: Fix reporting of read-only sysfs attributes
- zdev: Improve handling of invalid udev rules
- zipl: Fix stfle zero padding
- zipl: Fix build issues
- zipl: Remove trailing spaces from the fields defined in BLS files
- zipl: Do not overwrite BOOT_IMAGE entry
- zkey: Fix auto-detection of clear key bitsize for XTS keys
* __v2.9.0 (2019-05-21)__
For Linux kernel version: 5.0 / 5.1
Add new tool:
- zcryptstats: Add zcryptstats to display usage statistics of
IBM Crypto Express adapters
Changes of existing tools:
- lszfcp: New command line option to show module parameters
- lszfcp: Sdev attributes for scsi_disk, block, integrity, queue, iosched
- lszfcp: Add new output marker for non-good SCSI devices (luns)
- lszfcp: Add new output marker for non-good fc_rports
- lszfcp: Clean up whitespace (mixed indentation, trailing)
- lschp: Add support for specifying a CHPID
- zipl: Add secure boot capabilities
- zkey: Add common passphrase options for cryptsetup and crypttab
- zkey: Add batch-mode option to cryptsetup and zkey-cryptsetup
- libu2s: Remove the entire library and provide more robust functionality
in libdasd and libutil instead
Bug Fixes:
- lszfcp: Allow to show zfcp_units without associated SCSI device
- lszfcp: Attribute details for: css, zfcp_port, zfcp_unit
- lszfcp: Allow to also enumerate FCP device that have never been online
- lszfcp: Fix error message if no zfcp-attached SCSI device found
- lszfcp: Fix to show defunct FCP devices again
- lszfcp: Fix to show non-good target ports again
- lszfcp: Fix missing block & sg device output without CONFIG_SYSFS_DEPRECATED
- lszfcp: New command line option for extended output format
- zfcpdbf: Warn about ambiguous payload records with dup reqid & payarea
- zpcictl: Check for regular directory to prevent possible buffer overflow
* __v2.8.0 (2019-02-15)__
For Linux kernel version: 4.20
Changes of existing tools:
- Switch to using /run directory instead of the legacy /var/run
- zkey: Add --pbkdf pbkdf2 to generated cryptsetup luksFormat command
- zdsfs: Add online VTOC refresh
- pkey: Support autoloading kernel pkey module
Bug Fixes:
- zkey: Avoid EPERM on key change if user is not owner of key file
- cpumf/cpumf_helper: Always return list reference for --sfb-size
* __v2.7.1 (2018-12-13)__
For Linux kernel version: 4.19
Changes of existing tools:
- zkey: Enhance file read/write error handling
- cmsfs-fuse: Write more than a single line in linefeed mode
- zpcictl: Add warning for unsupported operations
- zipl: Use the BLS "title" field as the IPL section name
Bug Fixes:
- cmsfs-fuse: Fix iconv buffer aliasing
- cmsfs-fuse: Fix memory leak in cmsfs_rename()
- fdasd: Fix possible integer overflow
- fdasd: Fix resource leak in fdasd_parse_conffile()
- zdev: Fix memory leak in misc_readlink()
- dasdinfo: Display error messages on stderr
- zkey: Include /sbin into PATH when executing commands
- Makefile: Fix parallel build
- GCC8 warning fixes across the board for:
cmsfs-fuse, dasdinfo, dasdview, dump2tar, fdasd, hmcdrvfs, hyptop,
ip_watcher, libvmdump, libvtoc, lsqeth, lszcrypt, qethqoat, zdev, zdsfs,
zgetdump, zipl, zpcictl
* __v2.7.0 (2018-10-31)__
For Linux kernel version: 4.19
Add new tool:
- zcryptctl: Add zcryptctl for multiple zcrypt node management
- zpcictl: Add zpcictl for reporting defective PCI devices
Changes of existing tools:
- qethqoat: Add OSA-Express7S support
- lszcrypt: Add support for alternative zcrypt device drivers
- zfcpdump: Add install script for zfcpdump
- zipl: Make zipl work with XFS by using the FIEMAP mapping ioctl
Bug Fixes:
- lstape: Fix output with SCSI lin_tape and multiple paths to same unit
- lstape: Fix output without SCSI generic (sg)
- lsluns: Fix to prevent error messages if there are non-zfcp SCSI devices
- lstape: Fix to prevent error messages if there are non-zfcp SCSI devices
- lstape: Fix description of --type and <devbusid> filter for channel tapes
- lstape: Fix SCSI output description in man page
- lstape: Fix SCSI HBA CCW device bus-ID e.g. for virtio-scsi-ccw
- Direct --help and --version output to stdout for several tools
- osasnmpd: Start without real OSA devices
* __v2.6.0 (2018-08-10)__
For Linux kernel version: 4.18
@@ -14,7 +201,7 @@ Release history for s390-tools (MIT version)
- netboot: Include compressed kernel modules in initramfs
- netboot: Send client architecture and handle path prefix
* __v2.5.0 (2018-06-08)__
* __v2.5.0 (2018-06-08)__
For Linux kernel version: 4.17
@@ -26,7 +213,7 @@ Release history for s390-tools (MIT version)
Bug Fixes:
- lsluns: Print a message if no adapter or port exists
* __v2.4.0 (2018-05-07)__
* __v2.4.0 (2018-05-07)__
For Linux kernel version: 4.16

View File

@@ -3,12 +3,14 @@ ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/ar
# Include common definitions
include common.mak
LIB_DIRS = libvtoc libu2s libutil libzds libdasd libvmdump libccw libvmcp
LIB_DIRS = libvtoc libutil libzds libdasd libvmdump libccw libvmcp
TOOL_DIRS = zipl zdump fdasd dasdfmt dasdview tunedasd \
tape390 osasnmpd qetharp ip_watcher qethconf scripts zconf \
vmconvert vmcp man mon_tools dasdinfo vmur cpuplugd ipl_tools \
ziomon iucvterm hyptop cmsfs-fuse qethqoat zfcpdump zdsfs cpumf \
systemd hmcdrvfs cpacfstats zdev dump2tar zkey netboot etc
systemd hmcdrvfs cpacfstats zdev dump2tar zkey netboot etc zpcictl \
genprotimg
SUB_DIRS = $(LIB_DIRS) $(TOOL_DIRS)
all: $(TOOL_DIRS)

View File

@@ -1,4 +1,3 @@
s390-tools
==========
@@ -31,6 +30,9 @@ Package contents
* dasdinfo:
Display unique DASD ID, either UID or volser.
* genprotimg:
Create a protected virtualization image.
* udev rules:
- 59-dasd.rules: rules for unique DASD device nodes created in /dev/disk/.
- 57-osasnmpd.rules: udev rules for osasnmpd.
@@ -129,6 +131,7 @@ Package contents
or show encryption state of attached LUNs.
- lszcrypt: Show Information about zcrypt devices and configuration.
- chzcrypt: Modify the zcrypt configuration.
- zcryptstats: Display usage statistics of IBM Crypto Express adapters.
- znetconf: List and configure network devices for s390 network adapters.
- cio_ignore: Query and modify the contents of the CIO device driver
blacklist.
@@ -264,9 +267,10 @@ build options:
| pfm | `HAVE_PFM` | cpacfstats |
| net-snmp | `HAVE_SNMP` | osasnmpd |
| glibc-static | `HAVE_LIBC_STATIC` | zfcpdump |
| openssl | `HAVE_OPENSSL` | zkey |
| openssl | `HAVE_OPENSSL` | genprotimg,zkey |
| cryptsetup | `HAVE_CRYPTSETUP2` | zkey-cryptsetup |
| json-c | `HAVE_JSONC` | zkey-cryptsetup |
| glib2 | `HAVE_GLIB2` | genprotimg |
This table lists additional build or install options:
@@ -284,6 +288,17 @@ Build and runtime requirements for specific tools
In the following more details on the build an runtime requirements of
the different tools are provided:
* dbginfo.sh:
The tar package is required to archive collected data.
* genprotimg:
For building genprotimg you need OpenSSL version 1.1.0 or newer
installed (openssl-devel.rpm). Also required is glib2
(glib2-devel.rpm). Tip: you may skip the genprotimg build by adding
`HAVE_OPENSSL=0` or `HAVE_GLIB2=0`.
The runtime requirements are: openssl-libs (>= 1.1.0) and glib2.
* osasnmpd:
You need at least the NET-SNMP 5.1.x package (net-snmp-devel.rpm)
installed, before building the osasnmpd subagent.

View File

@@ -165,7 +165,7 @@ cmsfs-fuse uses a configuration file for automatic translation based on the file
Upon startup, cmsfs-fuse evaluates the file .cmsfs-fuse/filetypes.conf in the user's home directory. If the file does not
exist cmsfs-fuse evaluates the file /etc/cmsfs-fuse/filetypes.conf.
The filetypes.conf file contains the CMS file types that are automaticaly translated to ASCII if cmsfs-fuse is started
The filetypes.conf file contains the CMS file types that are automatically translated to ASCII if cmsfs-fuse is started
with the -t option. The syntax of the configuration file is one file type per line. Lines that start with a # followed by a space are treated as
comments and are ignored. The file type is 8 characters long and must consist of valid CMS file name characters only.

View File

@@ -3,7 +3,7 @@
*
* Main function
*
* Copyright IBM Corp. 2010, 2017
* Copyright IBM Corp. 2010, 2018
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
@@ -17,6 +17,7 @@
#include <fuse.h>
#include <fuse_opt.h>
#include <iconv.h>
#include <limits.h>
#include <linux/fs.h>
#ifdef HAVE_SETXATTR
#include <linux/xattr.h>
@@ -36,6 +37,7 @@
#include <unistd.h>
#include "lib/util_base.h"
#include "lib/util_libc.h"
#include "lib/util_list.h"
#include "lib/zt_common.h"
@@ -76,7 +78,7 @@ static const struct fuse_opt cmsfs_opts[] = {
static void usage(const char *progname)
{
fprintf(stderr,
fprintf(stdout,
"Usage: %s DEVICE MOUNTPOINT [OPTIONS]\n"
"\n"
"Use the cmsfs-fuse command to read and write files stored on a z/VM CMS disk.\n"
@@ -232,6 +234,8 @@ struct file {
int null_records;
/* write cache for text mode */
char *wcache;
/* buffer for iconv */
char *iconv_buf;
/* used bytes in write cache */
int wcache_used;
/* committed written bytes to FUSE */
@@ -601,7 +605,7 @@ static struct file *file_open(const char *name)
char uc_name[MAX_FNAME];
struct file *f;
strncpy(uc_name, name, MAX_FNAME);
util_strlcpy(uc_name, name, MAX_FNAME);
str_toupper(uc_name);
util_list_iterate(&open_file_list, f)
@@ -923,7 +927,6 @@ static void set_record(struct file *f, int *record, off_t addr, int len,
static void add_record_ext(struct record *rec, struct record_ext *ext)
{
struct record_ext *tmp;
int i = 0;
if (rec->ext == NULL) {
rec->ext = ext;
@@ -931,9 +934,7 @@ static void add_record_ext(struct record *rec, struct record_ext *ext)
ext->next = NULL;
} else {
tmp = rec->ext;
i++;
while (tmp->next != NULL) {
i++;
tmp = tmp->next;
}
tmp->next = ext;
@@ -1567,7 +1568,7 @@ static off_t lookup_file(const char *name, struct fst_entry *fst, int flag)
off_t faddr = 0;
int rc;
strncpy(uc_name, name, MAX_FNAME);
util_strlcpy(uc_name, name, MAX_FNAME);
str_toupper(uc_name);
if (flag == HIDE_UNLINKED && file_unlinked(uc_name))
@@ -1851,7 +1852,26 @@ static int cmsfs_open(const char *path, struct fuse_file_info *fi)
if (f->wcache == NULL)
return -ENOMEM;
strncpy(f->path, path, MAX_FNAME + 1);
/*
* For fixed-length records f->fst->record_len contains
* the fixed record length, which will not change. For
* variable-length records it contains the (current) maximum
* record length, which could be increased later by appending
* new records, so use MAX_RECORD_LEN for the iconv buffer.
* The MAX_RECORD_LEN is not valid for fixed-length records,
* only for variable-length records, so use the actual record
* length (f->fst->record_len) for fixed-length records.
*/
if (f->fst->record_format == RECORD_LEN_FIXED)
f->iconv_buf = malloc(f->fst->record_len + 1);
else
f->iconv_buf = malloc(MAX_RECORD_LEN + 1);
if (f->iconv_buf == NULL) {
destroy_file_object(f);
return -ENOMEM;
}
util_strlcpy(f->path, path, MAX_FNAME + 1);
str_toupper(f->path);
f->use_count = 1;
@@ -2108,7 +2128,7 @@ static int cmsfs_create(const char *path, mode_t mode,
return rc;
/* force uppercase */
strncpy(uc_name, path + 1, MAX_FNAME);
util_strlcpy(uc_name, path + 1, MAX_FNAME);
str_toupper(uc_name);
rc = encode_edf_name(uc_name, fname, ftype);
@@ -2550,14 +2570,13 @@ static void get_block_data_from_record(struct record *rec, off_t offset,
}
}
static int convert_text(iconv_t conv, char *buf, int size)
static int convert_text(iconv_t conv, char *in_buf, char *out_buf, int size)
{
size_t out_count = size;
size_t in_count = size;
char *data_ptr = buf;
int rc;
rc = iconv(conv, &data_ptr, &in_count, &data_ptr, &out_count);
rc = iconv(conv, &in_buf, &in_count, &out_buf, &out_count);
if ((rc == -1) || (in_count != 0)) {
DEBUG("Code page translation EBCDIC-ASCII failed\n");
return -EIO;
@@ -2618,14 +2637,15 @@ static int cmsfs_read(const char *path, char *buf, size_t size, off_t offset,
/* read one record */
if (addr == NULL_BLOCK)
memset(buf, 0, chunk);
else {
rc = _read(buf, chunk, addr);
else if (f->translate) {
rc = _read(f->iconv_buf, chunk, addr);
if (rc < 0)
return rc;
}
if (f->translate) {
rc = convert_text(cmsfs.iconv_from, buf, chunk);
rc = convert_text(cmsfs.iconv_from, f->iconv_buf, buf, chunk);
if (rc < 0)
return rc;
} else {
rc = _read(buf, chunk, addr);
if (rc < 0)
return rc;
}
@@ -2757,7 +2777,7 @@ static int delete_file(const char *path)
fst_last = find_last_fdir_entry(cmsfs.fdir, cmsfs.dir_levels);
/* remove unlinked file from fcache */
strncpy(file, path + 1, MAX_FNAME);
util_strlcpy(file, path + 1, MAX_FNAME);
str_toupper(file);
invalidate_htab_entry(file);
@@ -2841,20 +2861,21 @@ static int cmsfs_rename(const char *path, const char *new_path)
str_toupper(uc_new_name);
rc = encode_edf_name(uc_new_name, fname, ftype);
free(uc_new_name);
if (rc)
return rc;
memcpy(&fst.name[0], fname, 8);
memcpy(&fst.type[0], ftype, 8);
strncpy(uc_old_name, path + 1, MAX_FNAME);
util_strlcpy(uc_old_name, path + 1, MAX_FNAME);
str_toupper(uc_old_name);
invalidate_htab_entry(uc_old_name);
/* update name in file object if the file is opened */
f = file_open(uc_old_name);
if (f != NULL) {
strncpy(f->path, new_path, MAX_FNAME + 1);
util_strlcpy(f->path, new_path, MAX_FNAME + 1);
str_toupper(f->path);
memcpy(f->fst->name, fname, 8);
memcpy(f->fst->type, ftype, 8);
@@ -3743,7 +3764,7 @@ static int extend_block_variable(struct file *f, const char *buf, int len,
}
DEBUG("%s: wrote %d record bytes\n", __func__, rlen);
if (size <= 0)
if (size == 0)
return copied;
}
@@ -4167,22 +4188,13 @@ static ssize_t find_newline(const char *buf, int len)
return pos - buf;
}
static int cmsfs_write(const char *path, const char *buf, size_t size,
off_t offset, struct fuse_file_info *fi)
static int cmsfs_write_strings(struct file *f, const char *buf,
size_t size, off_t offset)
{
int scan_len = MIN(size, (size_t)MAX_RECORD_LEN + 1);
int rc, nl_byte = 1, null_record = 0, pad = 0;
struct file *f = get_fobj(fi);
ssize_t rsize;
(void) path;
if (cmsfs.readonly)
return -EROFS;
if (!f->linefeed)
return do_write(f, buf, size, offset);
/* remove already committed bytes */
offset -= f->wcache_commited;
@@ -4222,7 +4234,7 @@ static int cmsfs_write(const char *path, const char *buf, size_t size,
}
/* translate */
rc = convert_text(cmsfs.iconv_to, f->wcache, f->wcache_used);
rc = convert_text(cmsfs.iconv_to, f->wcache, f->iconv_buf, f->wcache_used);
if (rc < 0)
return rc;
@@ -4232,6 +4244,7 @@ static int cmsfs_write(const char *path, const char *buf, size_t size,
*/
if (!f->wcache_used) {
*f->wcache = FILLER_EBCDIC;
*f->iconv_buf = FILLER_EBCDIC;
f->wcache_used = 1;
nl_byte = 0;
null_record = 1;
@@ -4242,7 +4255,7 @@ static int cmsfs_write(const char *path, const char *buf, size_t size,
offset += f->pad_bytes;
BUG(offset < 0);
rc = do_write(f, f->wcache, f->wcache_used, offset);
rc = do_write(f, f->iconv_buf, f->wcache_used, offset);
if (rc < 0)
return rc;
@@ -4257,6 +4270,36 @@ static int cmsfs_write(const char *path, const char *buf, size_t size,
return rc;
}
static int cmsfs_write(const char *path, const char *buf, size_t size,
off_t offset, struct fuse_file_info *fi)
{
struct file *f = get_fobj(fi);
int rc, written, nbytes;
(void) path;
if (cmsfs.readonly)
return -EROFS;
if (!f->linefeed)
return do_write(f, buf, size, offset);
/* Limit the size to what we can report back as written */
nbytes = MIN(size, (size_t) INT_MAX);
written = 0;
while (nbytes) {
rc = cmsfs_write_strings(f, buf, nbytes, offset);
if (rc < 0)
return written ? written : rc;
written += rc;
offset += rc;
buf += rc;
nbytes -= rc;
}
return written;
}
static int cmsfs_unlink(const char *path)
{
struct fst_entry fst;
@@ -4284,7 +4327,7 @@ static int flush_wcache(struct file *f)
int rc;
/* translate */
rc = convert_text(cmsfs.iconv_to, f->wcache, f->wcache_used);
rc = convert_text(cmsfs.iconv_to, f->wcache, f->iconv_buf, f->wcache_used);
if (rc < 0)
return rc;
@@ -4292,7 +4335,7 @@ static int flush_wcache(struct file *f)
offset -= (f->fst->nr_records - f->null_records);
BUG(offset < 0);
rc = do_write(f, f->wcache, f->wcache_used, offset);
rc = do_write(f, f->iconv_buf, f->wcache_used, offset);
purge_wcache(f);
f->null_records = 0;
if (rc < 0)
@@ -4415,6 +4458,7 @@ static void destroy_file_object(struct file *f)
struct record *rec;
int i;
free(f->iconv_buf);
free(f->wcache);
free(f->wstate);
@@ -4498,14 +4542,23 @@ static int cmsfs_process_args(void *data, const char *arg, int key,
return 1;
case KEY_HELP:
usage(outargs->argv[0]);
/*
* Usage output needs to go to stdout to be consistent with
* coding guidelines. FUSE versions before 3.0.0 print help
* output to stderr. Redirect stderr to stdout here to enforce
* consistent behavior.
*/
fflush(stderr);
dup2(STDOUT_FILENO, STDERR_FILENO);
fuse_opt_add_arg(outargs, "-ho");
cmsfs_fuse_main(outargs, &cmsfs_oper);
exit(0);
case KEY_VERSION:
fprintf(stderr, COMP "FUSE file system for CMS disks "
fprintf(stdout, COMP "FUSE file system for CMS disks "
"program version %s\n", RELEASE_STRING);
fprintf(stderr, "Copyright IBM Corp. 2010, 2017\n");
fuse_opt_add_arg(outargs, "--version");
fprintf(stdout, "Copyright IBM Corp. 2010, 2017\n");
exit(0);
default:

View File

@@ -19,6 +19,7 @@
#include <sys/types.h>
#include <unistd.h>
#include "lib/util_libc.h"
#include "lib/zt_common.h"
#include "cmsfs-fuse.h"
@@ -65,7 +66,7 @@ static void add_filetype(char *name, struct util_list *list)
entry = malloc(sizeof(*entry));
if (entry == NULL)
DIE_PERROR("malloc failed");
strncpy(entry->name, name, MAX_TYPE_LEN);
util_strlcpy(entry->name, name, MAX_TYPE_LEN);
util_list_add_head(list, entry);
}

View File

@@ -19,6 +19,7 @@
#include <sys/types.h>
#include <unistd.h>
#include "lib/zt_common.h"
#include "cmsfs-fuse.h"
#include "edf.h"
#include "helper.h"

View File

@@ -49,6 +49,4 @@ extern FILE *logfile;
fprintf(stderr, COMP "Warning, " __VA_ARGS__); \
} while (0)
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#endif

View File

@@ -5,7 +5,7 @@ COMMON_INCLUDED = true
# The variable "DISTRELEASE" should be overwritten in rpm spec files with:
# "make DISTRELEASE=%{release}" and "make install DISTRELEASE=%{release}"
VERSION = 2
RELEASE = 6
RELEASE = 13
PATCHLEVEL = 0
DISTRELEASE = build-$(shell date +%Y%m%d)
S390_TOOLS_RELEASE = $(VERSION).$(RELEASE).$(PATCHLEVEL)-$(DISTRELEASE)
@@ -182,9 +182,10 @@ GROUP = $(shell id -gn)
export INSTALLDIR BINDIR LIBDIR MANDIR OWNER GROUP
# Special defines for zfcpdump
ZFCPDUMP_PART_IMAGE = zfcpdump_part.image
ZFCPDUMP_PART_RD = zfcpdump_part.rd
export ZFCPDUMP_DIR ZFCPDUMP_PART_IMAGE ZFCPDUMP_PART_RD
ZFCPDUMP_IMAGE = zfcpdump-image
ZFCPDUMP_INITRD = zfcpdump-initrd
ZFCPDUMP_FLAVOR = zfcpdump
export ZFCPDUMP_DIR ZFCPDUMP_IMAGE ZFCPDUMP_INITRD ZFCPDUMP_FLAVOR
CFLAGS ?= $(DEFAULT_CFLAGS) $(OPT_FLAGS)
HOSTCFLAGS ?= $(DEFAULT_CFLAGS) $(OPT_FLAGS)
@@ -239,7 +240,7 @@ endif
$(CXX) $(ALL_CPPFLAGS) $(ALL_CXXFLAGS) -c $< -o $@
%: %.o
$(LINK) $(ALL_LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
%.a:
$(AR) rcs $@ $^
@@ -330,10 +331,6 @@ $(rootdir)/libzds/libzds.a: $(rootdir)/libzds
$(MAKE) -C $(rootdir)/libzds/ libzds.a
.PHONY: $(rootdir)/libzds
$(rootdir)/libu2s/libu2s.a: $(rootdir)/libu2s
$(MAKE) -C $(rootdir)/libu2s/ libu2s.a
.PHONY: $(rootdir)/libu2s
$(rootdir)/libvmdump/libvmdump.a: $(rootdir)/libvmdump
$(MAKE) -C $(rootdir)/libvmdump/ libvmdump.a
.PHONY: $(rootdir)/libvmdump

View File

@@ -110,7 +110,7 @@ The default command is --print all.
.
.SH FILES
.nf
/var/run/cpacfstatsd_socket
/run/cpacfstatsd_socket
.fi
.
.SH RETURN VALUE

View File

@@ -78,8 +78,8 @@ struct msg_answer {
#define BACKLOG 10
#define SOCKET_FILE "/var/run/cpacfstatsd_socket"
#define PID_FILE "/var/run/cpacfstatsd.pid"
#define SOCKET_FILE "/run/cpacfstatsd_socket"
#define PID_FILE "/run/cpacfstatsd.pid"
#define CPACFSTATS_GROUP "cpacfstats"

View File

@@ -47,7 +47,7 @@ restart the daemon to ensure correct summing of the per-CPU performance
counters.
The starting daemon first checks for any stale pid file
/var/run/cpacfstatsd.pid. If this file exists, and the process ID in the
/run/cpacfstatsd.pid. If this file exists, and the process ID in the
file belongs to an active process, an error message is printed to the
console and the program terminates.
@@ -81,8 +81,8 @@ daemon startup and initialization failures.
.SH FILES
.nf
/var/run/cpacfstatsd_socket
/var/run/cpacfstatsd.pid
/run/cpacfstatsd_socket
/run/cpacfstatsd.pid
.fi
.SH RETURN VALUE

View File

@@ -6,10 +6,11 @@ include ../common.mak
CPUMF_DATADIR = $(TOOLS_DATADIR)/cpumf
DATA_FILES = cpum-cf-hw-counter.map \
cpum-cf-cfvn-1.ctr cpum-cf-cfvn-3.ctr \
cpum-cf-csvn-generic.ctr \
cpum-cf-csvn-12345.ctr cpum-cf-csvn-6.ctr \
cpum-cf-extended-z10.ctr cpum-cf-extended-z196.ctr \
cpum-cf-extended-zEC12.ctr cpum-sf-modes.ctr \
cpum-cf-extended-z13.ctr cpum-cf-extended-z14.ctr
cpum-cf-extended-z13.ctr cpum-cf-extended-z14.ctr \
cpum-cf-extended-z15.ctr
LIB_FILES = bin/cpumf_helper
USRBIN_SCRIPTS = bin/lscpumf
USRSBIN_SCRIPTS = bin/chcpumf

View File

@@ -12,8 +12,6 @@ use warnings;
use Carp qw/croak/;
use Data::Dumper;
use Getopt::Long qw/:config no_ignore_case/;
use Pod::Usage;
# Global constants
my $SERVICE_LEVELS = '/proc/service_levels';
@@ -51,10 +49,11 @@ sub cpumf_get_sfb_size()
my $val = "0,0";
my $SFBSIZE;
return $val unless open($SFBSIZE, '<', $CPUM_SFB_SIZE);
$val = <$SFBSIZE>;
chomp($val);
close($SFBSIZE);
if (open($SFBSIZE, '<', $CPUM_SFB_SIZE)) {
$val = <$SFBSIZE>;
chomp($val);
close($SFBSIZE);
}
return [split /,/, $val];
}
@@ -212,6 +211,7 @@ my $system_z_hwtype_map = {
2965 => 'IBM z13s',
3906 => 'IBM z14',
3907 => 'IBM z14 ZR1',
8561 => 'IBM z15',
};
sub get_hardware_type()
@@ -266,7 +266,12 @@ sub cpumf_load_ctrdef($;$)
# List of "generic" counter sets
my @def = ();
push @def, "cfvn-" . $version->{cfvn};
push @def, "csvn-generic";
if ($version->{csvn} >= 1 && $version->{csvn} <= 6) {
push @def, "csvn-12345";
}
if ($version->{csvn} == 6) {
push @def, "csvn-6";
}
my $h = {};
# Load counter set definition
@@ -345,6 +350,62 @@ sub cpumf_hardware_counter_map()
return $map;
}
my $cpumf_helper_str = <<'END_MESSAGE';
cpumf_helper - Helper module for managing CPU-Measurement Facilities (CPU-MF)
Options:
-i, --info:
Displays detailed information about installed and available
CPU-measurement facilities and the related Linux support.
-c, --counter authorization_value
Displays counter information for the current System z hardware.
The authorization value provides information about the authorized
counter sets. The value must be specified in decimal format.
To display all supported counters, specify C<65535> (FFFF hex).
To display supported counters for a particular System z hardware,
use the --ctr-def option and specify the System z hardware type.
--hardware-type
Displays the System z hardware type.
--ctr-def ctr-definition
Displays detailed information about the specified counter definition.
Valid counter definitions start with C<cfvn-> or <csvn-> followed by
the counter first/second version number of the CPU-Measurement Counter
Facility. To display counter information of model-specific counter
sets, specify the System z hardware type for I<ctr-definition>.
--ctr-set-names
Displays the mapping of counter set IDs to counter set names.
The counter set IDs are numbers that are used in counter definitions.
--ctr-set-ids
Displays the counter set IDs. The counter set IDs are numbers that
match the authorization bits (see QUERY COUNTER INFORMATION).
The output format is a list. To get the ID for a particular counter
set, use an index number as follows:
0: Basic Counter Set
1: Problem-State Counter Set
2: Crypto-Activity Counter Set
3: Extended Counter Set
4: MT-diagnostic Counter Set
5: Coprocessor Group Counter Set
--ctr-sf
Displays the counter definitions for the sampling facility support.
These counter definitions are specific to Linux perf infrastructure.
--sfb-size
Displays the size of the sampling facility buffer (SFB). The minimum
and maximum numbers are measured in units of sample-data-blocks. A
sample-data-block uses about 4 kilobytes.
END_MESSAGE
sub cpumf_helper_main()
{
@@ -362,8 +423,8 @@ sub cpumf_helper_main()
"ctr-set-ids" => \$conf->{opt_ctrset_ids},
"sfb-size" => \$conf->{opt_sfb_size},
"ctr-sf" => \$conf->{opt_sf_ctr},
) or pod2usage(-message =>"One or more options are not valid",
-exitval => 1);
) or die("One or more options are not valid\n" . $cpumf_helper_str);
# Setting up Data::Dumper to create parseable Perl output
local $Data::Dumper::Purity = 1;
@@ -415,8 +476,7 @@ sub cpumf_helper_main()
$result = cpumf_counter_set_ids();
} else {
pod2usage(-message => "No option specified",
-exitval => 1);
die("No option specified\n" . $cpumf_helper_str);
}
# Display result
@@ -427,93 +487,3 @@ sub cpumf_helper_main()
&cpumf_helper_main();
__DATA__
__END__
=head1 NAME
B<cpumf_helper> - Helper module for managing CPU-Measurement Facilities (CPU-MF)
=head1 SYNOPSIS
=head1 DESCRIPTION
The B<cpumf_helper> program is not intended for ordinary use.
=head1 OPTIONS
=over 8
=item B<-i>, B<--info>
Displays detailed information about installed and available CPU-measurement
facilities and the related Linux support.
=item B<-c>, B<--counter> I<authorization_value>
Displays counter information for the current System z hardware. The
authorization value provides information about the authorized counter sets. The
value must be specified in decimal format.
To display all supported counters, specify C<65535> (FFFF hex).
To display supported counters for a particular System z hardware, use the
B<--ctr-def> option and specify the System z hardware type.
=item B<--hardware-type>
Displays the System z hardware type.
=item B<--ctr-def> I<ctr-definition>
Displays detailed information about the specified counter definition.
Valid counter definitions start with C<cfvn-> or <csvn-> followed by
the counter first/second version number of the CPU-Measurement Counter
Facility. To display counter information of model-specific counter
sets, specify the System z hardware type for I<ctr-definition>.
=item B<--ctr-set-names>
Displays the mapping of counter set IDs to counter set names. The counter set
IDs are numbers that are used in counter definitions.
=item B<--ctr-set-ids>
Displays the counter set IDs. The counter set IDs are numbers that match the
authorization bits (see QUERY COUNTER INFORMATION). The output format is a
list. To get the ID for a particular counter set, use an index number as
follows:
=over 16
=item 0: Basic Counter Set
=item 1: Problem-State Counter Set
=item 2: Crypto-Activity Counter Set
=item 3: Extended Counter Set
=item 4: MT-diagnostic Counter Set
=item 5: Coprocessor Group Counter Set
=back
=item B<--ctr-sf>
Displays the counter definitions for the sampling facility support. These
counter definitions are specific to Linux perf infrastructure.
=item B<--sfb-size>
Displays the size of the sampling facility buffer (SFB). The minimum and
maximum numbers are measured in units of sample-data-blocks. A
sample-data-block uses about 4 kilobytes.
=back
=head1 FILES
=head1 SEE ALSO
L<lscpumf(1)>, L<chcpumf(1)>
=cut

View File

@@ -0,0 +1,33 @@
Counter: 80 Name:ECC_FUNCTION_COUNT
Short-Description:ECC Function Count
Description:
This counter counts the
total number of the elliptic-curve cryptography (ECC)
functions issued by the CPU.
.
Counter: 81 Name:ECC_CYCLES_COUNT
Short-Description:ECC Cycles Count
Description:
This counter counts the total
number of CPU cycles when the ECC coprocessor is
busy performing the elliptic-curve cryptography
(ECC) functions issued by the CPU.
.
Counter: 82 Name:ECC_BLOCKED_FUNCTION_COUNT
Short-Description:Ecc Blocked Function Count
Description:
This counter
counts the total number of the elliptic-curve
cryptography (ECC) functions that are issued by the CPU
and are blocked because the ECC coprocessor is
busy performing a function issued by another CPU.
.
Counter: 83 Name:ECC_BLOCKED_CYCLES_COUNT
Short-Description:ECC Blocked Cycles Count
Description:
This counter counts
the total number of CPU cycles blocked for the elliptic-curve
cryptography (ECC) functions issued by the
CPU because the ECC coprocessor is busy perform-
ing a function issued by another CPU.
.

View File

@@ -0,0 +1,376 @@
# Counter decriptions for the
# IBM z14 extended counter and MT-diagnostic counter set
#
# Notes for transactional-execution mode symbolic names:
# TX .. transactional-execution mode
# NC .. nonconstrained
# C .. constrained
#
# Undefined counters in the extended counter set:
# 142
# 158-161
# 176-223
# 227-231
# 233-242
# 246-255
# Undefined counters in the MT-diagnostic counter set:
# 450-495
#
#
# Extended Counter Set
# ---------------------------------------------------------------------
Counter:128 Name:L1D_RO_EXCL_WRITES
Short-Description:L1D Read-only Exclusive Writes
Description:
A directory write to the Level-1 Data cache where the line was
originally in a Read-Only state in the cache but has been updated
to be in the Exclusive state that allows stores to the cache line
.
Counter:129 Name:DTLB2_WRITES
Short-Description:DTLB2 Writes
Description:
A translation has been written into The Translation Lookaside
Buffer 2 (TLB2) and the request was made by the data cache
.
Counter:130 Name:DTLB2_MISSES
Short-Description:DTLB2 Misses
Description:
A TLB2 miss is in progress for a request made by the data cache.
Incremented by one for every TLB2 miss in progress for the Level-1
Data cache on this cycle
.
Counter:131 Name:DTLB2_HPAGE_WRITES
Short-Description:DTLB2 One-Megabyte Page Writes
Description:
A translation entry was written into the Combined Region and Segment
Table Entry array in the Level-2 TLB for a one-megabyte page
.
Counter:132 Name:DTLB2_GPAGE_WRITES
Short-Description:DTLB2 Two-Gigabyte Page Writes
Description:
A translation entry for a two-gigabyte page was written into the
Level-2 TLB
.
Counter:133 Name:L1D_L2D_SOURCED_WRITES
Short-Description:L1D L2D Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the
returned cache line was sourced from the Level-2 Data cache
.
Counter:134 Name:ITLB2_WRITES
Short-Description:ITLB2 Writes
Description:
A translation entry has been written into the Translation Lookaside
Buffer 2 (TLB2) and the request was made by the instruction cache
.
Counter:135 Name:ITLB2_MISSES
Short-Description:ITLB2 Misses
Description:
A TLB2 miss is in progress for a request made by the instruction cache.
Incremented by one for every TLB2 miss in progress for the Level-1
Instruction cache in a cycle
.
Counter:136 Name:L1I_L2I_SOURCED_WRITES
Short-Description:L1I L2I Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from the Level-2 Instruction cache
.
Counter:137 Name:TLB2_PTE_WRITES
Short-Description:TLB2 PTE Writes
Description:
A translation entry was written into the Page Table Entry array in the
Level-2 TLB
.
Counter:138 Name:TLB2_CRSTE_WRITES
Short-Description:TLB2 CRSTE Writes
Description:
Translation entries were written into the Combined Region and Segment
Table Entry array and the Page Table Entry array in the Level-2 TLB
.
Counter:139 Name:TLB2_ENGINES_BUSY
Short-Description:TLB2 Engines Busy
Description:
The number of Level-2 TLB translation engines busy in a cycle
.
Counter:140 Name:TX_C_TEND
Short-Description:Completed TEND instructions in constrained TX mode
Description:
A TEND instruction has completed in a constrained transactional-execution
mode
.
Counter:141 Name:TX_NC_TEND
Short-Description:Completed TEND instructions in non-constrained TX mode
Description:
A TEND instruction has completed in a non-constrained
transactional-execution mode
.
Counter:143 Name:L1C_TLB2_MISSES
Short-Description:L1C TLB2 Misses
Description:
Increments by one for any cycle where a level-1 cache or level-2 TLB miss
is in progress
.
Counter:144 Name:L1D_ONCHIP_L3_SOURCED_WRITES
Short-Description:L1D On-Chip L3 Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an On-Chip Level-3 cache without intervention
.
Counter:145 Name:L1D_ONCHIP_MEMORY_SOURCED_WRITES
Short-Description:L1D On-Chip Memory Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from On-Chip memory
.
Counter:146 Name:L1D_ONCHIP_L3_SOURCED_WRITES_IV
Short-Description:L1D On-Chip L3 Sourced Writes with Intervention
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an On-Chip Level-3 cache with intervention
.
Counter:147 Name:L1D_ONCLUSTER_L3_SOURCED_WRITES
Short-Description:L1D On-Cluster L3 Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from On-Cluster Level-3 cache withountervention
.
Counter:148 Name:L1D_ONCLUSTER_MEMORY_SOURCED_WRITES
Short-Description:L1D On-Cluster Memory Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an On-Cluster memory
.
Counter:149 Name:L1D_ONCLUSTER_L3_SOURCED_WRITES_IV
Short-Description:L1D On-Cluster L3 Sourced Writes with Intervention
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an On-Cluster Level-3 cache with intervention
.
Counter:150 Name:L1D_OFFCLUSTER_L3_SOURCED_WRITES
Short-Description:L1D Off-Cluster L3 Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an Off-Cluster Level-3 cache without
intervention
.
Counter:151 Name:L1D_OFFCLUSTER_MEMORY_SOURCED_WRITES
Short-Description:L1D Off-Cluster Memory Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from Off-Cluster memory
.
Counter:152 Name:L1D_OFFCLUSTER_L3_SOURCED_WRITES_IV
Short-Description:L1D Off-Cluster L3 Sourced Writes with Intervention
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an Off-Cluster Level-3 cache with intervention
.
Counter:153 Name:L1D_OFFDRAWER_L3_SOURCED_WRITES
Short-Description:L1D Off-Drawer L3 Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an Off-Drawer Level-3 cache without
intervention
.
Counter:154 Name:L1D_OFFDRAWER_MEMORY_SOURCED_WRITES
Short-Description:L1D Off-Drawer Memory Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from Off-Drawer memory
.
Counter:155 Name:L1D_OFFDRAWER_L3_SOURCED_WRITES_IV
Short-Description:L1D Off-Drawer L3 Sourced Writes with Intervention
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from an Off-Drawer Level-3 cache with intervention
.
Counter:156 Name:L1D_ONDRAWER_L4_SOURCED_WRITES
Short-Description:L1D On-Drawer L4 Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from On-Drawer Level-4 cache
.
Counter:157 Name:L1D_OFFDRAWER_L4_SOURCED_WRITES
Short-Description:L1D Off-Drawer L4 Sourced Writes
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from Off-Drawer Level-4 cache
.
Counter:158 Name:L1D_ONCHIP_L3_SOURCED_WRITES_RO
Short-Description:L1D On-Chip L3 Sourced Writes read-only
Description:
A directory write to the Level-1 Data cache directory where the returned
cache line was sourced from On-Chip L3 but a read-only invalidate was
done to remove other copies of the cache line
.
Counter:162 Name:L1I_ONCHIP_L3_SOURCED_WRITES
Short-Description:L1I On-Chip L3 Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache ine was sourced from an On-Chip Level-3 cache without
intervention
.
Counter:163 Name:L1I_ONCHIP_MEMORY_SOURCED_WRITES
Short-Description:L1I On-Chip Memory Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache ine was sourced from On-Chip memory
.
Counter:164 Name:L1I_ONCHIP_L3_SOURCED_WRITES_IV
Short-Description:L1I On-Chip L3 Sourced Writes with Intervention
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache ine was sourced from an On-Chip Level-3 cache with
intervention
.
Counter:165 Name:L1I_ONCLUSTER_L3_SOURCED_WRITES
Short-Description:L1I On-Cluster L3 Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from an On-Cluster Level-3 cache without
intervention
.
Counter:166 Name:L1I_ONCLUSTER_MEMORY_SOURCED_WRITES
Short-Description:L1I On-Cluster Memory Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from an On-Cluster memory
.
Counter:167 Name:L1I_ONCLUSTER_L3_SOURCED_WRITES_IV
Short-Description:L1I On-Cluster L3 Sourced Writes with Intervention
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from On-Cluster Level-3 cache with
intervention
.
Counter:168 Name:L1I_OFFCLUSTER_L3_SOURCED_WRITES
Short-Description:L1I Off-Cluster L3 Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from an Off-Cluster Level-3 cache without
intervention
.
Counter:169 Name:L1I_OFFCLUSTER_MEMORY_SOURCED_WRITES
Short-Description:L1I Off-Cluster Memory Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from Off-Cluster memory
.
Counter:170 Name:L1I_OFFCLUSTER_L3_SOURCED_WRITES_IV
Short-Description:L1I Off-Cluster L3 Sourced Writes with Intervention
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from an Off-Cluster Level-3 cache with
intervention
.
Counter:171 Name:L1I_OFFDRAWER_L3_SOURCED_WRITES
Short-Description:L1I Off-Drawer L3 Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from an Off-Drawer Level-3 cache without
intervention
.
Counter:172 Name:L1I_OFFDRAWER_MEMORY_SOURCED_WRITES
Short-Description:L1I Off-Drawer Memory Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from Off-Drawer memory
.
Counter:173 Name:L1I_OFFDRAWER_L3_SOURCED_WRITES_IV
Short-Description:L1I Off-Drawer L3 Sourced Writes with Intervention
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from an Off-Drawer Level-3 cache with
intervention
.
Counter:174 Name:L1I_ONDRAWER_L4_SOURCED_WRITES
Short-Description:L1I On-Drawer L4 Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from On-Drawer Level-4 cache
.
Counter:175 Name:L1I_OFFDRAWER_L4_SOURCED_WRITES
Short-Description:L1I Off-Drawer L4 Sourced Writes
Description:
A directory write to the Level-1 Instruction cache directory where the
returned cache line was sourced from Off-Drawer Level-4 cache
.
Counter:224 Name:BCD_DFP_EXECUTION_SLOTS
Short-Description:BCD DFP Execution Slots
Description:
Count of floating point execution slots used for finished Binary Coded
Decimal to Decimal Floating Point conversions. Instructions: CDZT,
CXZT, CZDT, CZXT
.
Counter:225 Name:VX_BCD_EXECUTION_SLOTS
Short-Description:VX BCD Execution Slots
Description:
Count of floating point execution slots used for finished vector arithmetic
Binary Coded Decimal instructions. Instructions: VAP, VSP, VMPVMSP, VDP,
VSDP, VRP, VLIP, VSRP, VPSOPVCP, VTP, VPKZ, VUPKZ, VCVB, VCVBG, VCVDVCVDG
.
Counter:226 Name:DECIMAL_INSTRUCTIONS
Short-Description:Decimal Instructions
Description:
Decimal instructions dispatched. Instructions: CVB, CVD, AP, CP, DP, ED,
EDMK, MP, SRP, SP, ZAP
.
Counter:232 Name:LAST_HOST_TRANSLATIONS
Short-Description:Last host translation done
Description:
Last Host Translation done
.
Counter:243 Name:TX_NC_TABORT
Short-Description:Aborted transactions in non-constrained TX mode
Description:
A transaction abort has occurred in a non-constrained
transactional-execution mode
.
Counter:244 Name:TX_C_TABORT_NO_SPECIAL
Short-Description:Aborted transactions in constrained TX mode not using special completion logic
Description:
A transaction abort has occurred in a constrained transactional-execution
mode and the CPU is not using any special logic to allow the transaction
to complete
.
Counter:245 Name:TX_C_TABORT_SPECIAL
Short-Description:Aborted transactions in constrained TX mode using special completion logic
Description:
A transaction abort has occurred in a constrained transactional-execution
mode and the CPU is using special logic to allow the transaction to
complete
.
Counter:247 Name:DFLT_ACCESS
Short-Description:Cycles CPU spent obtaining access to Deflate unit
Description:
Cycles CPU spent obtaining access to Deflate unit
.
Counter:252 Name:DFLT_CYCLES
Short-Description:Cycles CPU is using Deflate unit
Description:
Cycles CPU is using Deflate unit
.
Counter:264 Name:DFLT_CC
Short-Description:Increments by one for every DEFLATE CONVERSION CALL instruction executed
Description:
Increments by one for every DEFLATE CONVERSION CALL instruction executed
.
Counter:265 Name:DFLT_CCERROR
Short-Description:Increments by one for every DEFLATE CONVERSION CALL instruction executed that ended in Condition Codes 0, 1 or 2
Description:
Increments by one for every DEFLATE CONVERSION CALL instruction executed that ended in Condition Codes 0, 1 or 2
.
#
# MT-diagnostic counter set
# ---------------------------------------------------------------------
Counter:448 Name:MT_DIAG_CYCLES_ONE_THR_ACTIVE
Short-Description:Cycle count with one thread active
Description:
Cycle count with one thread active
.
Counter:449 Name:MT_DIAG_CYCLES_TWO_THR_ACTIVE
Short-Description:Cycle count with two threads active
Description:
Cycle count with two threads active
.

View File

@@ -14,7 +14,8 @@
'cfvn-3' => 'cpum-cf-cfvn-3.ctr',
# CSVN
'csvn-generic' => 'cpum-cf-csvn-generic.ctr',
'csvn-12345' => 'cpum-cf-csvn-12345.ctr',
'csvn-6' => 'cpum-cf-csvn-6.ctr',
# Extended counters
2097 => 'cpum-cf-extended-z10.ctr',
@@ -27,4 +28,6 @@
2965 => 'cpum-cf-extended-z13.ctr',
3906 => 'cpum-cf-extended-z14.ctr',
3907 => 'cpum-cf-extended-z14.ctr',
8561 => 'cpum-cf-extended-z15.ctr',
8562 => 'cpum-cf-extended-z15.ctr',
};

View File

@@ -7,7 +7,7 @@ LDLIBS += -lm
OBJECTS = daemon.o cpu.o info.o terms.o config.o main.o getopt.o mem.o
cpuplugd: $(OBJECTS)
$(LINK) $(ALL_LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
clean:
rm -f cpuplugd $(OBJECTS)

View File

@@ -3,7 +3,7 @@
*
* Config file parsing
*
* Copyright IBM Corp. 2007, 2017
* Copyright IBM Corp. 2007, 2018
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
@@ -201,6 +201,7 @@ void parse_configfile(char *file)
linebuffer);
parse_configline(linebuffer);
}
fclose(filp);
}
/*

View File

@@ -161,8 +161,8 @@ int is_online(int cpuid)
retval = 1;
if (state == 0)
retval = 0;
fclose(filp);
}
fclose(filp);
}
return retval;
}
@@ -220,8 +220,8 @@ int cpu_is_configured(int cpuid)
retval = 1;
if (state == 0)
retval = 0;
fclose(filp);
}
fclose(filp);
}
return retval;
}

View File

@@ -27,7 +27,7 @@
#define NAME "cpuplugd"
#define MAX_HISTORY 100
#define PIDFILE "/var/run/cpuplugd.pid"
#define PIDFILE "/run/cpuplugd.pid"
#define LOCKFILE "/var/lock/cpuplugd.lock"
#define PROCINFO_LINE 512
#define CPUSTAT_SIZE 1024
@@ -152,7 +152,6 @@ struct symbol_names {
};
extern int foreground;
extern int debug;
extern char *configfile;
extern int debug; /* is verbose specified? */
extern int memory;

View File

@@ -4,7 +4,6 @@ all: dasdfmt
libs = $(rootdir)/libdasd/libdasd.a \
$(rootdir)/libvtoc/libvtoc.a \
$(rootdir)/libu2s/libu2s.a \
$(rootdir)/libutil/libutil.a
dasdfmt: dasdfmt.o $(libs)

View File

@@ -122,6 +122,8 @@ Format the first two tracks and write label and partition information. Only use
this option if you are sure that the target DASD already contains a regular
format with the specified blocksize. A blocksize can optionally be specified
using \fB-b\fR (\fB--blocksize\fR).
.br
For thin-provisioned DASD ESE volumes this is the default mode.
.IP expand
Format all unformatted tracks at the end of the target DASD. This mode assumes
that tracks at the beginning of the DASD volume have already been correctly
@@ -136,6 +138,10 @@ using \fB-b\fR (\fB--blocksize\fR).
Perform a complete format check on a DASD volume. A blocksize can be specified
with \fB-b\fR (\fB--blocksize\fR).
.TP
\fB--no-discard\fR
Omit a full space release when formatting a thin-provisioned DASD ESE volume.
.TP
\fB-r\fR \fIcylindercount\fR or \fB--requestsize\fR=\fIcylindercount\fR
Number of cylinders to be processed in one formatting step.

View File

@@ -53,6 +53,7 @@ static const struct util_prg prg = {
/* Defines for options with no short command */
#define OPT_CHECK 128
#define OPT_NOZERO 129
#define OPT_NODISCARD 130
static struct util_opt opt_vec[] = {
UTIL_OPT_SECTION("FORMAT ACTIONS"),
@@ -105,6 +106,11 @@ static struct util_opt opt_vec[] = {
.desc = "Prevent storage server from modifying record 0",
.flags = UTIL_OPT_FLAG_NOSHORT,
},
{
.option = { "no-discard", no_argument, NULL, OPT_NODISCARD },
.desc = "Do not discard space before formatting",
.flags = UTIL_OPT_FLAG_NOSHORT,
},
{
.option = { NULL, no_argument, NULL, 'y' },
.desc = "Start formatting without further user-confirmation",
@@ -921,6 +927,8 @@ static void dasdfmt_print_info(dasdfmt_info_t *info, char *devname,
printf("Drive Geometry: %d Cylinders * %d Heads = %d Tracks\n",
cylinders, heads, (cylinders * heads));
printf("Device Type: %s Provisioned\n",
info->ese ? "Thinly" : "Fully");
printf("\nI am going to format the device ");
printf("%s in the following way:\n", devname);
printf(" Device number of device : 0x%x\n", info->dasd_info.devno);
@@ -939,7 +947,10 @@ static void dasdfmt_print_info(dasdfmt_info_t *info, char *devname,
(p->intensity & DASD_FMT_INT_COMPAT) ? "yes" : "no");
printf(" Blocksize : %d\n", p->blksize);
printf(" Mode : %s\n", mode_str[mode]);
if (info->ese) {
printf(" Full Space Release : %s\n",
(info->no_discard || mode == FULL) ? "no" : "yes");
}
if (info->testmode)
printf("Test mode active, omitting ioctl.\n");
}
@@ -1234,6 +1245,26 @@ static void dasdfmt_format(dasdfmt_info_t *info, unsigned int cylinders,
process_tracks(info, cylinders, heads, format_params);
}
static void dasdfmt_release_space(dasdfmt_info_t *info)
{
format_data_t r = {
.start_unit = 0,
.stop_unit = 0,
.intensity = DASD_FMT_INT_ESE_FULL,
};
int err = 0;
if (!info->ese || info->no_discard)
return;
printf("Releasing space for the entire device...\n");
err = dasd_release_space(dev_filename, &r);
if (err) {
ERRMSG_EXIT(EXIT_FAILURE, "%s: Could not release space (%s)\n",
prog_name, strerror(err));
}
}
static void dasdfmt_prepare_and_format(dasdfmt_info_t *info,
unsigned int cylinders,
unsigned int heads, format_data_t *p)
@@ -1329,6 +1360,8 @@ static void dasdfmt_quick_format(dasdfmt_info_t *info, unsigned int cylinders,
if (info->force) {
printf("Skipping format check due to --force.\n");
} else if (info->ese) {
printf("Skipping format check due to thin-provisioned device.\n");
} else {
check_blocksize(info, p->blksize);
@@ -1394,7 +1427,7 @@ static void do_format_dasd(dasdfmt_info_t *info, char *devname,
if ((info->verbosity > 0) || !info->withoutprompt || info->testmode)
dasdfmt_print_info(info, devname, vlabel, cylinders, heads, p);
count = u2s_get_host_access_count(devname);
count = dasd_get_host_access_count(devname);
if (info->force_host) {
if (count > 1) {
ERRMSG_EXIT(EXIT_FAILURE,
@@ -1438,6 +1471,7 @@ static void do_format_dasd(dasdfmt_info_t *info, char *devname,
dasdfmt_prepare_and_format(info, cylinders, heads, p);
break;
case QUICK:
dasdfmt_release_space(info);
dasdfmt_quick_format(info, cylinders, heads, p);
break;
case EXPAND:
@@ -1461,6 +1495,19 @@ static void do_format_dasd(dasdfmt_info_t *info, char *devname,
}
}
static void eval_format_mode(dasdfmt_info_t *info)
{
if (!info->force && info->mode_specified && info->ese && mode == EXPAND) {
ERRMSG_EXIT(EXIT_FAILURE,
"WARNING: The specified device is thin-provisioned\n"
"Format mode 'expand' is not feasible.\n"
"Use --mode=full or --mode=quick to perform a clean format\n");
}
if (!info->mode_specified)
mode = info->ese ? QUICK : FULL;
}
int main(int argc, char *argv[])
{
dasdfmt_info_t info = {
@@ -1496,8 +1543,6 @@ int main(int argc, char *argv[])
format_params.blksize = DEFAULT_BLOCKSIZE;
format_params.intensity = DASD_FMT_INT_COMPAT;
mode = FULL;
/*************** parse parameters **********************/
while (1) {
@@ -1601,6 +1646,10 @@ int main(int argc, char *argv[])
"invalid. Consult the man page for "
"more information.\n",
prog_name, optarg);
info.mode_specified = 1;
break;
case OPT_NODISCARD:
info.no_discard = 1;
break;
case OPT_CHECK:
info.check = 1;
@@ -1645,6 +1694,9 @@ int main(int argc, char *argv[])
"device information failed (%s).\n",
prog_name, strerror(rc));
info.ese = dasd_sys_ese(dev_filename);
eval_format_mode(&info);
/* Either let the user specify the blksize or get it from the kernel */
if (!info.blksize_specified) {
if (!(mode == FULL ||

View File

@@ -27,10 +27,6 @@
#include <sys/types.h>
#include <unistd.h>
/****************************************************************************
* SECTION: Definition needed for DASD-API (see dasd.h) *
****************************************************************************/
/*
* Represents possible format modes that can be specified when formatting
* a DASD.
@@ -45,57 +41,16 @@ static const char mode_str[3][10] = {
"Full", "Quick", "Expand"
};
/*
* values to be used for format_data_t.intensity
* 0/8: normal format
* 1/9: also write record zero
* 3/11: also write home address
* 4/12: invalidate track
*/
#define DASD_FMT_INT_FMT_R0 1 /* write record zero */
#define DASD_FMT_INT_FMT_HA 2 /* write home address, also set FMT_R0 ! */
#define DASD_FMT_INT_INVAL 4 /* invalidate tracks */
#define DASD_FMT_INT_COMPAT 8 /* use OS/390 compatible disk layout */
#define DASD_FMT_INT_FMT_NOR0 16 /* remove permission to write record zero */
/*
* values to be used in format_check_t for indicating
* possible format errors
*/
#define DASD_FMT_ERR_TOO_FEW_RECORDS 1
#define DASD_FMT_ERR_TOO_MANY_RECORDS 2
#define DASD_FMT_ERR_BLKSIZE 3
#define DASD_FMT_ERR_RECORD_ID 4
#define DASD_FMT_ERR_KEY_LENGTH 5
/*
* values to be used for dasd_information2_t.format
* 0x00: NOT formatted
* 0x01: Linux disc layout
* 0x02: Common disc layout
*/
#define DASD_FORMAT_NONE 0
#define DASD_FORMAT_LDL 1
#define DASD_FORMAT_CDL 2
/****************************************************************************
* SECTION: DASDFMT internal types *
****************************************************************************/
#define DASD_PARTN_BITS 2
#define PARTN_MASK ((1 << DASD_PARTN_BITS) - 1)
#define EXIT_MISUSE 1
#define EXIT_BUSY 2
#define LABEL_LENGTH 14
#define VLABEL_CHARS 84
#define LINE_LENGTH 80
#define ERR_LENGTH 90
#define DEFAULT_BLOCKSIZE 4096
/* requestsize - number of cylinders in one format step */
#define DEFAULT_REQUESTSIZE 10
#define USABLE_PARTITIONS ((1 << DASD_PARTN_BITS) - 1)
#define ERRMSG(x...) {fflush(stdout);fprintf(stderr,x);}
#define ERRMSG_EXIT(ec,x...) {fflush(stdout);fprintf(stderr,x);exit(ec);}
@@ -137,6 +92,9 @@ typedef struct dasdfmt_info {
int force_host;
int layout_specified;
int check;
int mode_specified;
int ese;
int no_discard;
} dasdfmt_info_t;

View File

@@ -1,7 +1,6 @@
include ../common.mak
libs = $(rootdir)/libu2s/libu2s.a \
$(rootdir)/libutil/libutil.a \
libs = $(rootdir)/libutil/libutil.a \
$(rootdir)/libdasd/libdasd.a
all: dasdinfo

View File

@@ -34,7 +34,7 @@ Print DASD uid
This option prints the full uid of the DASD. When z/VM provides two
virtual devices that are actually located on the same real device, the
first four tokens of the uid will be identical for both devices. z/VM
may provide an additional token that allows to distinguish between
may provide an additional token that can be used to distinguish between
different minidisks. You need both support in the Linux kernel and
z/VM to receive such an additional token.
@@ -45,7 +45,7 @@ available by applying the PTFs for VM APAR VM64273 on z/VM 5.2.0 and higher.
.BI "-u|--uid"
Print DASD uid without z/VM minidisk token
z/VM may provide an additional token that allows to distinguish
z/VM may provide an additional token that can be used to distinguish
between different minidisks (see --extended-uid option). To remain
compatibile with systems that were installed on older Linux or z/VM
levels, the -u option will print the uid excluding any z/VM-provided

View File

@@ -25,6 +25,7 @@
#include "lib/dasd_base.h"
#include "lib/util_base.h"
#include "lib/util_file.h"
#include "lib/util_libc.h"
#include "lib/util_opt.h"
#include "lib/util_prg.h"
#include "lib/zt_common.h"
@@ -192,18 +193,18 @@ static int dinfo_read_dasd_vlabel(char *device, struct volume_label *vlabel,
char *space;
if (dasd_get_blocksize(device, &blksize) != 0) {
printf("Unable to figure out block size.\n");
warnx("Unable to figure out block size");
goto error;
}
if (dasd_get_info(device, &dasd_info) != 0) {
printf("Unable to figure out DASD informations.\n");
warnx("Unable to figure out DASD information");
goto error;
}
f = open(device, O_RDONLY);
if (f < 0) {
printf("Could not open device node.\n");
warnx("Could not open device node");
goto error;
}
@@ -214,7 +215,7 @@ static int dinfo_read_dasd_vlabel(char *device, struct volume_label *vlabel,
bzero(vlabel, vlsize);
if (read(f, vlabel, vlsize) != vlsize) {
printf("Could not read volume label.\n");
warnx("Could not read volume label");
goto error_close;
}
@@ -255,10 +256,9 @@ static void *dinfo_malloc(size_t size)
void *result;
result = malloc(size);
if (result == NULL) {
printf("Could not allocate %lld bytes of memory",
(unsigned long long)size);
}
if (result == NULL)
warnx("Could not allocate %lu bytes of memory", size);
return result;
}
@@ -290,7 +290,7 @@ static int dinfo_create_devnode(dev_t dev, char **devno)
mode = S_IFBLK | S_IRWXU;
/* Try several locations for the temporary device node. */
for (path = 0; path < UTIL_ARRAY_SIZE(pathname); path++) {
for (path = 0; path < ARRAY_SIZE(pathname); path++) {
if (pathname[path] == NULL)
continue;
for (retry = 0; retry < TEMP_DEV_MAX_RETRIES; retry++) {
@@ -318,16 +318,14 @@ static int dinfo_create_devnode(dev_t dev, char **devno)
free(result);
}
}
printf("Error: Unable to create temporary device node");
warnx("Error: Unable to create temporary device node");
return -1;
}
static void dinfo_free_devnode(char *device)
{
if (remove(device)) {
printf("Warning: Could not remove "
"temporary file %s", device);
}
if (remove(device))
warnx("Warning: Could not remove temporary file %s", device);
}
static int dinfo_extract_dev(dev_t *dev, char *str)
@@ -337,10 +335,10 @@ static int dinfo_extract_dev(dev_t *dev, char *str)
int ma, mi;
bzero(tmp, RD_BUFFER_SIZE);
strncpy(tmp, str, RD_BUFFER_SIZE);
util_strlcpy(tmp, str, RD_BUFFER_SIZE);
p = strchr(tmp, ':');
if (p == NULL) {
printf("Error: unable to extract major/minor\n");
warnx("Error: unable to extract major/minor");
return -1;
}
@@ -359,7 +357,7 @@ static int dinfo_get_dev_from_blockdev(char *blockdev, dev_t *dev)
readbuf = dinfo_malloc(RD_BUFFER_SIZE);
if (!readbuf) {
printf("Error: Not enough memory to allocate readbuffer\n");
warnx("Error: Not enough memory to allocate readbuffer");
return -1;
}
if (util_file_read_line(readbuf, RD_BUFFER_SIZE,
@@ -490,7 +488,7 @@ static int dinfo_get_uid_from_devnode(char **uidfile, char *devnode)
int rc = 0;
if (stat(devnode, &stat_buffer) != 0) {
printf("Error: could not stat %s\n", devnode);
warnx("Error: could not stat %s", devnode);
return -1;
}
@@ -499,13 +497,13 @@ static int dinfo_get_uid_from_devnode(char **uidfile, char *devnode)
directory = opendir("/sys/block/");
if (directory == NULL) {
printf("Error: could not open directory /sys/block\n");
warnx("Error: could not open directory /sys/block");
return -1;
}
readbuf = dinfo_malloc(RD_BUFFER_SIZE);
if (!readbuf) {
printf("Error: Not enough memory to allocate readbuffer\n");
warnx("Error: Not enough memory to allocate readbuffer");
return -1;
}
@@ -607,25 +605,23 @@ int main(int argc, char *argv[])
sscanf(uname_buf.release, "%d.%d", &version, &release);
if (strcmp(uname_buf.sysname, "Linux") ||
version < 2 || (version == 2 && release < 6)) {
printf("%s %d.%d is not supported\n", uname_buf.sysname,
version, release);
warnx("%s %d.%d is not supported", uname_buf.sysname,
version, release);
exit(1);
}
if (!busid && !blockdev && !devnode) {
printf("Error: please specify a device using either -b, -i "
"or -d\n");
warnx("Error: please specify a device using either -b, -i or -d");
exit(1);
}
if ((busid && blockdev) || (busid && devnode) || (blockdev && devnode)) {
printf("Error: please specify device only once, either -b, -i "
"or -d\n");
warnx("Error: please specify device only once, either -b, -i or -d");
exit(1);
}
if (!print_uid && !print_extended_uid && !print_vlabel) {
printf("Error: no action specified (e.g. -u)\n");
warnx("Error: no action specified (e.g. -u)");
exit(1);
}
@@ -718,7 +714,7 @@ int main(int argc, char *argv[])
}
error:
printf("Error: could not read unique DASD ID\n");
warnx("Error: could not read unique DASD ID");
rc = 1;
out:

View File

@@ -7,7 +7,6 @@ all: dasdview
libs = $(rootdir)/libdasd/libdasd.a \
$(rootdir)/libzds/libzds.a \
$(rootdir)/libvtoc/libvtoc.a \
$(rootdir)/libu2s/libu2s.a \
$(rootdir)/libutil/libutil.a
dasdview: dasdview.o $(libs)

View File

@@ -28,10 +28,10 @@
#include "lib/dasd_base.h"
#include "lib/dasd_sys.h"
#include "lib/libzds.h"
#include "lib/u2s.h"
#include "lib/util_base.h"
#include "lib/util_opt.h"
#include "lib/util_prg.h"
#include "lib/util_sys.h"
#include "lib/vtoc.h"
#include "lib/zt_common.h"
@@ -160,19 +160,19 @@ dasdview_get_info(dasdview_info_t *info)
if (err != EBADF)
zt_error_print("dasdview: "
"Could not retrieve geo information!\n");
exit(-1);
exit(EXIT_FAILURE);
}
if (dasd_get_blocksize(info->device, &info->blksize) != 0) {
zt_error_print("dasdview: "
"Could not retrieve blocksize information!\n");
exit(-1);
exit(EXIT_FAILURE);
}
if (dasd_get_info(info->device, &info->dasd_info) != 0) {
zt_error_print("dasdview: "
"Could not retrieve disk information!\n");
exit(-1);
exit(EXIT_FAILURE);
}
characteristics = (struct dasd_eckd_characteristics *)
@@ -183,7 +183,7 @@ dasdview_get_info(dasdview_info_t *info)
else
info->hw_cylinders = characteristics->no_cyl;
if (u2s_getbusid(info->device, info->busid) == -1)
if (util_sys_get_dev_addr(info->device, info->busid) != 0)
info->busid_valid = 0;
else
info->busid_valid = 1;
@@ -261,7 +261,7 @@ dasdview_parse_input(unsigned long long *p, dasdview_info_t *info, char *s)
error:
zt_error_print("dasdview: usage error\n"
"%s is not a valid begin/size value!", s);
exit(-1);
exit(EXIT_FAILURE);
}
/*
@@ -404,7 +404,7 @@ dasdview_print_extended_info(dasdview_info_t *info)
if (dasd_info->features == DASD_FEATURE_DEFAULT) {
printf("default\n");
} else {
for (i = 0; i < UTIL_ARRAY_SIZE(flist); i++)
for (i = 0; i < ARRAY_SIZE(flist); i++)
if (dasd_info->features & flist[i].mask)
printf("%s ", flist[i].name);
printf("\n");
@@ -454,7 +454,7 @@ dasdview_print_vlabel(dasdview_info_t *info)
if (rc) {
zt_error_print("error when reading label from device:"
" rc=%d\n", rc);
exit(-1);
exit(EXIT_FAILURE);
}
lzds_dasd_get_vlabel(info->dasd, &tmpvlabel);
memcpy(&vlabel, tmpvlabel, sizeof(vlabel));
@@ -600,7 +600,7 @@ dasdview_print_volser(dasdview_info_t *info)
if (rc) {
zt_error_print("error when reading label from device:"
" rc=%d\n", rc);
exit(-1);
exit(EXIT_FAILURE);
}
lzds_dasd_get_vlabel(info->dasd, &tmpvlabel);
memcpy(&vlabel, tmpvlabel, sizeof(vlabel));
@@ -618,7 +618,7 @@ dasdview_print_volser(dasdview_info_t *info)
strncpy(volser, vlabel.volid, 6);
vtoc_ebcdic_dec(volser, volser, 6);
} else {
strncpy(volser, " ", 6);
memcpy(volser, " ", 6);
}
printf("%6.6s\n", volser);
@@ -644,7 +644,7 @@ dasdview_read_vtoc(dasdview_info_t *info)
zt_error_print("dasdview: disk layout error\n"
"%s is not formatted with the z/OS "
"compatible disk layout!\n", info->device);
exit(-1);
exit(EXIT_FAILURE);
}
vtocblk = (u_int64_t)vtoc_get_cyl_from_cchhb(&vlabel.vtoc) *
@@ -664,7 +664,7 @@ dasdview_read_vtoc(dasdview_info_t *info)
if ((vtocblk <= 0) || (vtocblk > maxblk)) {
zt_error_print("dasdview: VTOC error\n"
"Volume label VTOC pointer is not valid!\n");
exit(-1);
exit(EXIT_FAILURE);
}
vtoc_read_label(info->device, (vtocblk - 1) * info->blksize,
@@ -676,7 +676,7 @@ dasdview_read_vtoc(dasdview_info_t *info)
/* format4 DSCB is invalid */
zt_error_print("dasdview: VTOC error\n"
"Format 4 DSCB is invalid!\n");
exit(-1);
exit(EXIT_FAILURE);
}
info->f4c++;
@@ -724,19 +724,19 @@ dasdview_read_vtoc(dasdview_info_t *info)
if (info->f4c > 1) {
zt_error_print("dasdview: VTOC error\n"
"More than one FMT4 DSCB!\n");
exit(-1);
exit(EXIT_FAILURE);
}
if (info->f5c > 1) {
zt_error_print("dasdview: VTOC error\n"
"More than one FMT5 DSCB!\n");
exit(-1);
exit(EXIT_FAILURE);
}
if (info->f7c > 1) {
zt_error_print("dasdview: VTOC error\n"
"More than one FMT7 DSCB!\n");
exit(-1);
exit(EXIT_FAILURE);
}
}
@@ -975,7 +975,7 @@ static void dasdview_print_format1_8_short_info_raw(format1_label_t *f1,
}
if (rc) {
zt_error_print("dasdview: Broken format 3 DSCB chain \n");
exit(-1);
exit(EXIT_FAILURE);
}
f3 = (dscb && dscb->fmtid == 0xf3) ? (format3_label_t *)dscb : NULL;
@@ -990,7 +990,7 @@ static void dasdview_print_format1_8_short_info_raw(format1_label_t *f1,
if (f3->DS3FMTID != 0xf3) {
zt_error_print("dasdview: Broken format 3 DSCB"
" chain \n");
exit(-1);
exit(EXIT_FAILURE);
}
for (j = 0; j < 4; ++j)
dasdview_print_short_info_extent_raw(&f3->DS3EXTNT[j]);
@@ -1002,7 +1002,7 @@ static void dasdview_print_format1_8_short_info_raw(format1_label_t *f1,
if (rc) {
zt_error_print("dasdview: Broken format 3 DSCB"
" chain \n");
exit(-1);
exit(EXIT_FAILURE);
}
}
printf("\n");
@@ -1025,7 +1025,7 @@ static void dasdview_print_vtoc_info_raw(dasdview_info_t *info)
rc = lzds_raw_vtoc_alloc_dscbiterator(info->rawvtoc, &it);
if (rc) {
zt_error_print("dasdview: could not allocate DSCB iterator \n");
exit(-1);
exit(EXIT_FAILURE);
}
while (!lzds_dscbiterator_get_next_dscb(it, &dscb)) {
if (dscb->fmtid == 0xf1)
@@ -1058,7 +1058,7 @@ static void dasdview_print_vtoc_info_raw(dasdview_info_t *info)
rc = lzds_raw_vtoc_alloc_dscbiterator(info->rawvtoc, &it);
if (rc) {
zt_error_print("dasdview: could not allocate DSCB iterator \n");
exit(-1);
exit(EXIT_FAILURE);
}
while (!lzds_dscbiterator_get_next_dscb(it, &dscb)) {
if (dscb->fmtid == 0xf1 || dscb->fmtid == 0xf8)
@@ -1739,23 +1739,23 @@ static void dasdview_print_vtoc_raw(dasdview_info_t *info)
if (rc) {
zt_error_print("error when reading label from device:"
" rc=%d\n", rc);
exit(-1);
exit(EXIT_FAILURE);
}
rc = lzds_dasd_read_rawvtoc(info->dasd);
rc = lzds_dasd_alloc_rawvtoc(info->dasd);
if (rc == EINVAL) {
zt_error_print("dasdview: Cannot read VTOC because disk does"
" not contain valid VOL1 label.\n",
info->device);
exit(-1);
exit(EXIT_FAILURE);
} else if (rc) {
zt_error_print("error when reading vtoc from device:"
" rc=%d\n", rc);
exit(-1);
exit(EXIT_FAILURE);
}
rc = lzds_dasd_get_rawvtoc(info->dasd, &info->rawvtoc);
if (rc || !info->rawvtoc) {
zt_error_print("dasdview: libvtoc could not read vtoc\n");
exit(-1);
exit(EXIT_FAILURE);
}
if (info->vtoc_info || info->vtoc_all)
@@ -1764,7 +1764,7 @@ static void dasdview_print_vtoc_raw(dasdview_info_t *info)
rc = lzds_raw_vtoc_alloc_dscbiterator(info->rawvtoc, &it);
if (rc) {
zt_error_print("dasdview: could not allocate DSCB iterator\n");
exit(-1);
exit(EXIT_FAILURE);
}
while (!lzds_dscbiterator_get_next_dscb(it, &record))
dasdview_print_vtoc_dscb(info, record);
@@ -1858,7 +1858,7 @@ static void dasdview_view_standard(dasdview_info_t *info)
zt_error_print("dasdview: open error\n"
"Unable to open device %s in read-only mode!\n",
info->device);
exit(-1);
exit(EXIT_FAILURE);
}
j = (info->begin / SEEK_STEP);
@@ -1877,7 +1877,7 @@ static void dasdview_view_standard(dasdview_info_t *info)
zt_error_print("dasdview: seek error\n"
"Unable to seek in device %s!\n",
info->device);
exit(-1);
exit(EXIT_FAILURE);
}
b++;
a += SEEK_STEP;
@@ -1890,7 +1890,7 @@ static void dasdview_view_standard(dasdview_info_t *info)
zt_error_print("dasdview: seek error\n"
"Unable to seek in device %s!\n",
info->device);
exit(-1);
exit(EXIT_FAILURE);
}
}
@@ -1926,7 +1926,7 @@ static void dasdview_view_standard(dasdview_info_t *info)
zt_error_print("dasdview: read error\n"
"Unable to read from device %s!\n",
info->device);
exit(-1);
exit(EXIT_FAILURE);
}
if (info->format1)
@@ -1945,7 +1945,7 @@ static void dasdview_view_standard(dasdview_info_t *info)
zt_error_print("dasdview: read error\n"
"Unable to read from device %s!\n",
info->device);
exit(-1);
exit(EXIT_FAILURE);
}
if (info->format1)
@@ -2112,18 +2112,18 @@ static void dasdview_view_raw(dasdview_info_t *info)
trackdata = memalign(4096, trckbuffsize * RAWTRACKSIZE);
if (!trackdata) {
zt_error_print("failed to allocate memory\n");
exit(-1);
exit(EXIT_FAILURE);
}
rc = lzds_dasd_alloc_dasdhandle(info->dasd, &dasdh);
if (rc) {
zt_error_print("failed to allocate memory\n");
exit(-1);
exit(EXIT_FAILURE);
}
rc = lzds_dasdhandle_open(dasdh);
if (rc) {
lzds_dasdhandle_free(dasdh);
zt_error_print("failed to open device\n");
exit(-1);
exit(EXIT_FAILURE);
}
/* residual is the number of tracks we still have to read */
residual = tracks_to_read;
@@ -2135,7 +2135,7 @@ static void dasdview_view_raw(dasdview_info_t *info)
trckend, trackdata);
if (rc) {
perror("Error on read");
exit(-1);
exit(EXIT_FAILURE);
}
data = trackdata;
for (i = 0; i < trckcount; ++i) {
@@ -2153,7 +2153,7 @@ static void dasdview_view_raw(dasdview_info_t *info)
lzds_dasdhandle_free(dasdh);
if (rc < 0) {
perror("Error on closing file");
exit(-1);
exit(EXIT_FAILURE);
}
}
@@ -2253,7 +2253,7 @@ int main(int argc, char *argv[])
zt_error_print("dasdview: usage error\n"
"%s is no valid argument for"
" option -t/--vtoc\n", optarg);
exit(-1);
exit(EXIT_FAILURE);
}
info.vtoc = 1;
info.action_specified = 1;
@@ -2301,13 +2301,13 @@ int main(int argc, char *argv[])
rc = lzds_zdsroot_alloc(&info.zdsroot);
if (rc) {
zt_error_print("Could not allocate index\n");
exit(-1);
exit(EXIT_FAILURE);
}
rc = lzds_zdsroot_add_device(info.zdsroot, info.device,
&info.dasd);
if (rc) {
zt_error_print("Could not add device to index\n");
exit(-1);
exit(EXIT_FAILURE);
}
}
@@ -2328,7 +2328,7 @@ int main(int argc, char *argv[])
if (info.begin > max) {
zt_error_print("dasdview: usage error\n"
"'begin' value is not within disk range!");
exit(-1);
exit(EXIT_FAILURE);
}
if (info.size_specified)
@@ -2343,7 +2343,7 @@ int main(int argc, char *argv[])
zt_error_print("dasdview: usage error\n"
"'begin' + 'size' is not within "
"disk range!");
exit(-1);
exit(EXIT_FAILURE);
}
if ((info.begin_specified || info.size_specified) &&
@@ -2355,7 +2355,7 @@ int main(int argc, char *argv[])
zt_error_print("dasdview: usage error\n"
"Options -1 or -2 make only sense with "
"options -b or -s!");
exit(-1);
exit(EXIT_FAILURE);
}
/* do the output */

View File

@@ -11,7 +11,6 @@
#define DASDVIEW_H
#include <limits.h>
#include "lib/u2s.h"
/********************************************************************************
* SECTION: Definitions needed for DASD-API (see dasd.h)
@@ -109,7 +108,7 @@ typedef struct dasdview_info
int f8c;
int f9c;
char busid[U2S_BUS_ID_SIZE];
char busid[DASD_BUS_ID_SIZE];
int busid_valid;
int raw_track_access;
struct zdsroot *zdsroot;

View File

@@ -78,7 +78,7 @@ static void set_time(char *dest, size_t len, time_t value)
#define SET_TIME_FIELD(obj, name, value) \
set_time((obj)->name, sizeof((obj)->name), (time_t) (value))
#define SET_STR_FIELD(obj, name, value) \
strncpy((obj)->name, (value), sizeof((obj)->name))
util_strlcpy((obj)->name, (value), sizeof((obj)->name))
/* Initialize the tar file @header with the provided data */
static void init_header(struct tar_header *header, const char *filename,

View File

@@ -13,7 +13,7 @@
DAEMON=cpacfstatsd
DAEMON_PATH=/usr/sbin/cpacfstatsd
RUN_PID_FILE=/var/run/cpacfstatsd.pid
RUN_PID_FILE=/run/cpacfstatsd.pid
RETVAL=0
OPTIONS=""

View File

@@ -17,7 +17,7 @@
DAEMON=cpuplugd
DAEMON_PATH=/usr/sbin/cpuplugd
CONFIG_FILE=/etc/cpuplugd.conf
RUN_PID_FILE=/var/run/cpuplugd.pid
RUN_PID_FILE=/run/cpuplugd.pid
RETVAL=0
OPTIONS="-c $CONFIG_FILE"

View File

@@ -22,7 +22,7 @@ DUMP_CONFIG_FILE=/etc/sysconfig/dumpconf
CMDFULL=$0
CMD="dumpconf"
LOCKFILE=/var/lock/$CMD
PIDFILE=/var/run/$CMD.pid
PIDFILE=/run/$CMD.pid
ERRMSG="Check $DUMP_CONFIG_FILE!"
RETVAL=0

View File

@@ -20,8 +20,8 @@ PROCD=mon_procd
FSSTATD_PATH=/usr/sbin/$FSSTATD
PROCD_PATH=/usr/sbin/$PROCD
CONFIG_FILE=/etc/sysconfig/$DAEMON
FSSTATD_PID_FILE=/var/run/$FSSTATD.pid
PROCD_PID_FILE=/var/run/$PROCD.pid
FSSTATD_PID_FILE=/run/$FSSTATD.pid
PROCD_PID_FILE=/run/$PROCD.pid
# source function library
. /lib/lsb/init-functions

View File

@@ -0,0 +1,2 @@
# Load protected key support module on s390 early at boot
pkey

View File

@@ -3,7 +3,6 @@ include ../common.mak
libs = $(rootdir)/libvtoc/libvtoc.a \
$(rootdir)/libzds/libzds.a \
$(rootdir)/libdasd/libdasd.a \
$(rootdir)/libu2s/libu2s.a \
$(rootdir)/libutil/libutil.a
all: fdasd

View File

@@ -1,7 +1,7 @@
/*
* fdasd - Create or modify partitions on ECKD DASDs
*
* Copyright IBM Corp. 2001, 2017
* Copyright IBM Corp. 2001, 2018
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
@@ -75,7 +75,7 @@ static int get_part_name_by_dsname(char *dsname, char **name)
return 0;
}
for (i = 0; i < UTIL_ARRAY_SIZE(partition_types); i++) {
for (i = 0; i < ARRAY_SIZE(partition_types); i++) {
if (strstr(dsname, partition_types[i].dsname) != NULL) {
*name = partition_types[i].name;
return 0;
@@ -97,7 +97,7 @@ static int get_part_type_by_dsname(char *dsname, int *type)
return 0;
}
for (i = 0; i < UTIL_ARRAY_SIZE(partition_types); i++) {
for (i = 0; i < ARRAY_SIZE(partition_types); i++) {
if (strstr(dsname, partition_types[i].dsname) != NULL) {
*type = partition_types[i].type;
return 0;
@@ -112,7 +112,7 @@ static int get_part_type_by_dsname(char *dsname, int *type)
*/
static int get_part_dsname_by_type(unsigned int type, char **dsname)
{
if (type > UTIL_ARRAY_SIZE(partition_types))
if (type > ARRAY_SIZE(partition_types))
return 1;
if (type == 0)
@@ -258,7 +258,7 @@ static void fdasd_check_volser(char *volser, int devno)
{
int from, to;
for (from = 0, to = 0; volser[from] && from < VOLSER_LENGTH; from++)
for (from = 0, to = 0; from < VOLSER_LENGTH && volser[from]; from++)
if ((volser[from] >= 0x23 &&
volser[from] <= 0x25) || /* # $ % */
(volser[from] >= 0x30 &&
@@ -397,7 +397,7 @@ static void fdasd_error(fdasd_anchor_t *anc, enum fdasd_failure why, char *str)
fputc('\n', stderr);
fputs(err_str, stderr);
fdasd_exit(anc, -1);
fdasd_exit(anc, EXIT_FAILURE);
}
/*
@@ -727,9 +727,9 @@ static int fdasd_parse_conffile(fdasd_anchor_t *anc,
memset(buffer, 0, sizeof(buffer));
rc = read(fd, buffer, sizeof(buffer) - 1);
close(fd);
if (rc < 0)
return -1;
close(fd);
for (i = 0; i < rc; i++)
buffer[i] = toupper(buffer[i]);
@@ -935,7 +935,7 @@ static void fdasd_verify_device(fdasd_anchor_t *anc, char *name)
fdasd_error(anc, device_verification_failed, err_str);
}
count = u2s_get_host_access_count(name);
count = dasd_get_host_access_count(name);
if (anc->force_host) {
if (count > 1) {
snprintf(err_str, ERROR_STRING_SIZE,
@@ -1205,7 +1205,7 @@ static void fdasd_list_known_partitions(void)
unsigned int i;
for (i = VALID_PARTITION_OFFSET;
i < UTIL_ARRAY_SIZE(partition_types); i++) {
i < ARRAY_SIZE(partition_types); i++) {
printf("%3d %s\n",
partition_types[i].type, partition_types[i].name);
}
@@ -1257,7 +1257,7 @@ static void fdasd_write_vtoc_labels(fdasd_anchor_t *anc)
printf("DSCBs: ");
blk = (cchhb2blk(&anc->vlabel->vtoc, &geo) - 1) * anc->blksize;
if (blk <= 0)
if (cchhb2blk(&anc->vlabel->vtoc, &geo) == 0 || blk == 0)
fdasd_error(anc, vlabel_corrupted, "");
maxblk = blk + anc->blksize * 9; /* f4+f5+f7+3*f8+3*f9 */
@@ -1310,7 +1310,7 @@ static void fdasd_write_vtoc_labels(fdasd_anchor_t *anc)
volser[VOLSER_LENGTH] = ' ';
strncpy(c1, volser, VOLSER_LENGTH + 1);
c1 = strchr(ch, ' ');
strncpy(c1, s2, 31);
memcpy(c1, s2, 31);
} else {
if (get_part_type_by_dsname(ch, &part_info->type))
part_info->type = PARTITION_NATIVE;
@@ -1321,23 +1321,23 @@ static void fdasd_write_vtoc_labels(fdasd_anchor_t *anc)
setpos(anc, k, i - 1);
strncpy(ch, "LINUX.V "
memcpy(ch, "LINUX.V "
" ", 44);
strncpy(volser, anc->vlabel->volid, VOLSER_LENGTH);
vtoc_ebcdic_dec(volser, volser, VOLSER_LENGTH);
strncpy(c1, volser, VOLSER_LENGTH);
memcpy(c1, volser, VOLSER_LENGTH);
c1 = strchr(ch, ' ');
strncpy(c1, ".PART", 5);
memcpy(c1, ".PART", 5);
c1 += 5;
sprintf(dsno, "%04d.", k + 1);
strncpy(c1, dsno, 5);
memcpy(c1, dsno, 5);
c1 += 5;
get_part_dsname_by_type(part_info->type, &dsname);
strncpy(c1, dsname, strlen(dsname)); /* We don't want \0 */
memcpy(c1, dsname, strlen(dsname)); /* We don't want \0 */
}
vtoc_ebcdic_enc(ch, ch, 44);
if (anc->verbose)
@@ -1622,7 +1622,7 @@ static void fdasd_change_part_type(fdasd_anchor_t *anc)
part_type = 0;
while (part_type < 1 ||
part_type > UTIL_ARRAY_SIZE(partition_types) - 1) {
part_type > ARRAY_SIZE(partition_types) - 1) {
do {
part_type = read_char("new partition type: ");
} while (!isdigit(part_type));
@@ -1636,7 +1636,7 @@ static void fdasd_change_part_type(fdasd_anchor_t *anc)
ch = strstr(part_info->f1->DS1DSNAM, "PART") + 9;
if (ch != NULL)
strncpy(ch, str, 6);
memcpy(ch, str, 6);
vtoc_ebcdic_enc(part_info->f1->DS1DSNAM, part_info->f1->DS1DSNAM, 44);
anc->vtoc_changed++;
}
@@ -1994,7 +1994,7 @@ static int fdasd_check_volume(fdasd_anchor_t *anc)
printf(" VOL1\n");
blk = (cchhb2blk(&vlabel->vtoc, &geo) - 1) * anc->blksize;
if (blk > 0) {
if (cchhb2blk(&vlabel->vtoc, &geo) > 0 && blk > 0) {
rc = fdasd_valid_vtoc_pointer(anc, blk);
if (anc->print_table && (rc < 0))
@@ -3040,5 +3040,5 @@ int main(int argc, char *argv[])
}
}
return -1;
return EXIT_FAILURE;
}

5
genprotimg/.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
tags
compile_commands.json
src/.check-dep-genprotimg
src/.detect-openssl.dep.c
src/genprotimg

27
genprotimg/Makefile Normal file
View File

@@ -0,0 +1,27 @@
# Common definitions
include ../common.mak
.DEFAULT_GOAL := all
PKGDATADIR := "$(DESTDIR)$(TOOLS_DATADIR)/genprotimg"
TESTS :=
SUBDIRS := boot src man
RECURSIVE_TARGETS := all-recursive install-recursive clean-recursive
all: all-recursive
install: all install-recursive
$(INSTALL) -d -m 755 "$(PKGDATADIR)"
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 boot/stage3a.bin "$(PKGDATADIR)"
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 boot/stage3b_reloc.bin "$(PKGDATADIR)"
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 samples/check_hostkeydoc "$(PKGDATADIR)"
clean: clean-recursive
$(RECURSIVE_TARGETS):
@target=`echo $@ |sed s/-recursive//`; \
for d in $(SUBDIRS); do \
$(MAKE) -C $$d $$target; \
done
.PHONY: all install clean $(RECURSIVE_TARGETS)

85
genprotimg/README.md Normal file
View File

@@ -0,0 +1,85 @@
# genprotimg
`genprotimg` takes a kernel, key files, optionally an initrd image,
optionally a file containing the kernel command line parameters, and
generates a single, bootable image file. The generated image file
consists of a concatenation of a plain text boot loader, the encrypted
components for kernel, initrd, kernel command line, and the
integrity-protected PV header, containing the metadata necessary for
running the guest in protected mode. See [Memory Layout](#memory-layout)
for details about the internal structure of the created image.
It is possible to use the generated image as a kernel for zipl or for
a direct kernel boot using QEMU.
## Getting started
If all dependencies are met a simple `make` call in the source tree
should be enough for building `genprotimg`.
## Details
The main idea of `genprotimg` is:
1. read in all keys, IVs, and other information needed for the
encryption of the components and the generation of the PV header
2. add stub stage3a (so we can calculate the memory addresses)
3. add components: prepare the components (alignment and encryption)
and add them to the memory layout
4. build and add stage3b: generate the stage3b and add it to the memory layout
5. generate the PV header: generate the hashes (pld, ald, and tld) of
the components and create the PV header and IPIB
6. parameterize the stub stage3a: uses the IPIB and PV header
7. write the final image to the specified output path
### Boot Loader
The boot loader consists of two parts:
1. stage3a boot loader (cleartext), this loader is responsible for the
transition into the protected mode by doing diag308 subcode 8 and
10 calls.
2. stage3b boot loader (encrypted), this loader is very similar to the
normal zipl stage3 boot loader. It will be loaded by the Ultravisor
after the successful transition into protected mode. Like the zipl
stage3 boot loader it moves the kernel and patches in the values
for initrd and parmline.
The loaders have the following constraints:
1. It must be possible to place stage3a and stage3b at a location
greater than 0x10000 because the zipl stage3 loader zeroes out
everything at addresses lower than 0x10000 of the image.
2. As the stage3 loader of zipl assumes that the passed kernel image
looks like a normal kernel image, the zipl stage3 loader modifies the
content at the memory area 0x10400 - 0x10800, therefore we leave this
area unused in our stage3a loader.
3. The default entry address used by the zipl stage3 loader is 0x10000
so we add a simple branch to 0x11000 at 0x10000 so the zipl stage3
loader can modify the area 0x10400 - 0x10800 without affecting the
stage3a loader.
#### Detail about stage3b
The stage3b.bin is linked at address 0x9000, therefore it will not
work at another address. The relocation support for the stage3b
loader, so that it can be placed at addresses != 0x9000, is added in
the loader with the name stage3b_reloc.bin. By default, if we're
talking about stage3b we refer to stage3b_reloc.bin.
### Memory Layout
The memory layout of the bootable file looks like:
| Start | End | Use |
|------------------------|------------|-----------------------------------------------------------------------|
| 0 | 0x7 | Short PSW, starting instruction at 0x11000 |
| 0x10000 | 0x10012 | Branch to 0x11000 |
| 0x10013 | 0x10fff | Left intentionally unused |
| 0x11000 | 0x12fff | Stage3a |
| 0x13000 | 0x13fff | IPIB used as argument for the diag308 call |
| 0x14000 | 0x1[45]fff | UV header used for the diag308 call (size can be either 1 or 2 pages) |
| NEXT_PAGE_ALIGNED_ADDR | | Encrypted kernel |
| NEXT_PAGE_ALIGNED_ADDR | | Encrypted kernel parameters |
| NEXT_PAGE_ALIGNED_ADDR | | Encrypted initrd |
| NEXT_PAGE_ALIGNED_ADDR | | Encrypted stage3b_reloc |

4
genprotimg/boot/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
*.elf
*.lds
*.bin
*.d

97
genprotimg/boot/Makefile Normal file
View File

@@ -0,0 +1,97 @@
# Common definitions
include ../../common.mak
ZIPL_DIR := $(rootdir)/zipl
ZIPL_BOOT_DIR := $(ZIPL_DIR)/boot
INCLUDE_PATHS := $(ZIPL_BOOT_DIR) $(ZIPL_DIR)/include $(rootdir)/include
INCLUDE_PARMS := $(addprefix -I,$(INCLUDE_PATHS))
ALL_CFLAGS := $(NO_PIE_CFLAGS) -Os -g \
$(INCLUDE_PARMS) \
-DENABLE_SCLP_ASCII=1 \
-DS390_TOOLS_RELEASE=$(S390_TOOLS_RELEASE) \
-fno-builtin -ffreestanding -fno-asynchronous-unwind-tables \
-fno-delete-null-pointer-checks \
-fexec-charset=IBM1047 -m64 -mpacked-stack \
-mstack-size=4096 -mstack-guard=128 -msoft-float \
-Wall -Wformat-security -Wextra -Werror
FILES := stage3a.bin stage3b.bin stage3b_reloc.bin
ZIPL_SRCS_C := libc.c ebcdic.c ebcdic_conv.c sclp.c
ZIPL_SRCS_ASM := entry.S
ZIPL_OBJS_C := $(ZIPL_SRCS_C:%.c=%.o)
ZIPL_OBJS_ASM := $(ZIPL_SRCS_ASM:%.S=%.o)
ZIPL_OBJS := $(ZIPL_OBJS_C) $(ZIPL_OBJS_ASM)
all: $(FILES)
# Prevent make from using some default rules...
%: %.S
%.o: %.S Makefile
$(CC) $(ALL_CFLAGS) -c -o $@ $<
%.o: %.c Makefile
$(CC) $(ALL_CFLAGS) -c -o $@ $<
# Dependencies for the .lds generation
sources_lds_S = $(wildcard *.lds.S)
dependencies_lds_S = $(sources_lds_S:%.lds.S=.%.lds.d)
# Include all ".lds.d" dependency files for all make targets except for "clean"
ifneq ($(MAKECMDGOALS),clean)
-include $(dependencies_lds_S)
endif
%.lds: %.lds.S Makefile
$(CPP) -Wp,-MD,.$@.d,-MT,$@ $(INCLUDE_PARMS) -P -C -o $@ $<
# Special rules for zipl object files
$(ZIPL_OBJS_C): %.o : $(ZIPL_BOOT_DIR)/%.c
$(CC) $(ALL_CFLAGS) -c -o $@ $<
$(ZIPL_OBJS_ASM): %.o : $(ZIPL_BOOT_DIR)/%.S
$(CC) $(ALL_CFLAGS) -c -o $@ $<
dependencies_zipl_c := $(ZIPL_SRCS_C:%.c=.%.o.d)
$(dependencies_zipl_c): .%.o.d : $(ZIPL_BOOT_DIR)/%.c
$(CC_SILENT) -MM $(ALL_CPPFLAGS) $(ALL_CFLAGS) $< > $@
ifneq ($(MAKECMDGOALS),clean)
-include $(dependencies_zipl_c)
endif
stage3b_reloc.o: stage3b.bin
stage3a.elf: head.o stage3a_init.o stage3a.o stage3a.lds $(ZIPL_OBJS)
stage3b.elf: head.o stage3b.o stage3b.lds $(ZIPL_OBJS)
stage3b_reloc.elf:
%.elf: %.o
case $* in \
stage3a) SFLAGS="$(NO_PIE_LINKFLAGS) -nostdlib -Wl,-T,stage3a.lds";; \
stage3b) SFLAGS="$(NO_PIE_LINKFLAGS) -nostdlib -Wl,-T,stage3b.lds";; \
stage3b_reloc) SFLAGS="$(NO_PIE_LINKFLAGS) -nostdlib -Wl,-estage3b_reloc_start,-Ttext,0";; \
esac; \
$(LINK) $$SFLAGS -m64 $(filter %.o, $^) -o $@
@chmod a-x $@
%.bin: %.elf
$(OBJCOPY) -O binary \
--only-section=.text* \
--only-section=.ex_table* \
--only-section=.fixup* \
--only-section=.data* \
--only-section=.rodata* \
$< $@
@chmod a-x $@
clean:
rm -f *.o *.elf *.bin *.map .*.d *.lds
.PHONY: all clean

View File

@@ -0,0 +1,25 @@
/*
* Common memory layout for stage3a and stage3b bootloader.
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#ifndef COMMON_MEMORY_LAYOUT_H
#define COMMON_MEMORY_LAYOUT_H
#include "boot/loaders_layout.h"
#define STACK_ADDRESS STAGE3_STACK_ADDRESS
#define STACK_SIZE STAGE3_STACK_SIZE
#define HEAP_ADDRESS STAGE3_HEAP_ADDRESS
#define HEAP_SIZE STAGE3_HEAP_SIZE
#ifndef __ASSEMBLER__
#endif /* __ASSEMBLER__ */
#endif /* COMMON_MEMORY_LAYOUT_H */

29
genprotimg/boot/head.S Normal file
View File

@@ -0,0 +1,29 @@
/*
* Entry code for stage 3a boot loader
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include "common_memory_layout.h"
#include "boot/s390.h"
#include "boot/sigp.h"
.section .text.start
.globl _start
_start:
/* Might be called after a diag308 so better set
* architecture and addressing mode
*/
lhi %r1, 1
sigp %r1, %r0, SIGP_SET_ARCHITECTURE
sam64
/* Initialize stack */
lgfi %r15, STACK_ADDRESS + STACK_SIZE - STACK_FRAME_OVERHEAD
brasl %r14, initialize
.previous

62
genprotimg/boot/stage3a.c Normal file
View File

@@ -0,0 +1,62 @@
/*
* Main program for stage3a bootloader
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include "libc.h"
#include "stage3a.h"
#include "lib/zt_common.h"
#include "boot/s390.h"
#include "boot/ipl.h"
#include "sclp.h"
#include "error.h"
static volatile struct stage3a_args __section(".loader_parms") loader_parms;
void __noreturn start(void)
{
int rc;
volatile struct stage3a_args *args = &loader_parms;
/* calculate the IPIB memory address */
struct ipl_parameter_block *ipib = (void *)((uint64_t)args + args->ipib_offs);
/* Calculate the PV header memory address and set it and its
* size in the IPIB. This allows the PV header to be position
* independent.
*/
ipib->pv.pv_hdr_addr = (uint64_t)args + args->hdr_offs;
ipib->pv.pv_hdr_size = args->hdr_size;
/* set up ASCII and line-mode */
sclp_setup(SCLP_LINE_ASCII_INIT);
/* test if Secure Execution Unpack facility is available */
stfle(S390_lowcore.stfle_fac_list,
ARRAY_SIZE(S390_lowcore.stfle_fac_list));
rc = test_facility(UNPACK_FACILITY);
if (rc == 0)
panic(ENOPV, "Secure unpack facility is not available\n");
rc = diag308(DIAG308_SET_PV, ipib);
if (rc != DIAG308_RC_OK)
panic(EPV, "Protected boot setup has failed: 0x%x\n", rc);
rc = diag308(DIAG308_UNPACK_PV, 0x0);
if (rc != DIAG308_RC_OK) {
sclp_setup(SCLP_LINE_ASCII_INIT);
panic(EPV, "Protected boot has failed: 0x%x\n", rc);
}
while (1)
;
}
void panic_notify(unsigned long UNUSED(rc))
{
}

34
genprotimg/boot/stage3a.h Normal file
View File

@@ -0,0 +1,34 @@
/*
* Main program for stage3a bootloader.
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#ifndef STAGE3A_H
#define STAGE3A_H
#include "lib/zt_common.h"
#include "boot/loaders_layout.h"
#define STAGE3A_INIT_ENTRY IMAGE_ENTRY
#define STAGE3A_ENTRY (STAGE3A_INIT_ENTRY + _AC(0x1000, UL))
#define STAGE3A_LOAD_ADDRESS IMAGE_LOAD_ADDRESS
#ifndef __ASSEMBLER__
#include <stdint.h>
/* Must not have any padding */
struct stage3a_args {
uint64_t hdr_offs;
uint64_t hdr_size;
uint64_t ipib_offs;
};
STATIC_ASSERT(sizeof(struct stage3a_args) == 3 * 8)
#endif /* __ASSEMBLER__ */
#endif /* STAGE3A_H */

View File

@@ -0,0 +1,103 @@
/*
* Memory layout for stage 3a
* ==========================
*
* General memory layout
* ---------------------
*
* 0x00000 - 0x01fff Lowcore
* 0x02000 - 0x05fff Memory allocation (heap)
* 0x0f000 - 0x0ffff Stack
* 0x10000 - 0x10012 Jump to the "actual" stage3a code
* 0x11000 - 0x12fff Stage3a code + arguments (offsets and lengths to the
* actual data: IPIB and UV header)
*/
#include "stage3a.h"
#include "common_memory_layout.h"
OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390")
OUTPUT_ARCH(s390:64-bit)
ENTRY(_init)
SECTIONS
{
. = 0x0;
. = HEAP_ADDRESS;
__heap_start = .;
.heap : {
. = . + HEAP_SIZE;
ASSERT(__heap_stop - __heap_start == HEAP_SIZE,
"Heap section doesn't conform to the described memory layout");
}
__heap_stop = .;
. = STACK_ADDRESS;
__stack_start = .;
.stack : {
. = . + STACK_SIZE;
ASSERT(__stack_end - __stack_start == STACK_SIZE,
"Stack section doesn't conform to the described memory layout");
}
__stack_end = .;
. = STAGE3A_INIT_ENTRY;
__text_init_start = .;
.text : {
stage3a_init.o(.text.init)
__text_init_stop = ABSOLUTE(.);
/* Text size of text_init must be smaller than 'PARMAREA - IMAGE_ENTRY',
* otherwise the text data could be overwritten by the original zipl stage3
* boot loader */
ASSERT(__text_init_stop - __text_init_start < PARMAREA - IMAGE_ENTRY,
"Text size must be smaller than 'PARMAREA - IMAGE_ENTRY'");
. = 0x1000;
ASSERT(ABSOLUTE(.) == STAGE3A_ENTRY,
"Text section doesn't conform to the described memory layout");
head.o(.text.start)
*(.text)
}
.ex_table ALIGN(16) : {
__ex_table_start = .;
*(.ex_table)
__ex_table_stop = .;
}
.bss ALIGN(16) : {
__bss_start = .;
*(.bss)
__bss_stop = .;
}
.rodata ALIGN(16) : {
*(.rodata)
*(.rodata.*)
}
.data ALIGN(16) : {
*(.data)
. = ALIGN(16);
/* The IPIB offset and the UV header offset and size will be
* saved in 'loader_parms' */
__loader_parms_start = .;
KEEP(*(.loader_parms));
__loader_parms_stop = .;
ASSERT(__loader_parms_stop - __loader_parms_start == 3 * 8,
"Data size must be equal to 'sizeof(struct stage3a_args)'");
ASSERT(ABSOLUTE(.) < 0x13000, "Data section doesn't conform to the described memory layout");
}
/* List this explicitly as otherwise .note.gnu.build-id will be
* put at 0x0 */
.notes : {
*(.note.*)
}
/* Sections to be discarded */
/DISCARD/ : {
*(.eh_frame)
}
}

View File

@@ -0,0 +1,26 @@
/*
* Entry code for stage 3a boot loader
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include "stage3a.h"
#include "boot/sigp.h"
.section .text.init
.globl _init
_init:
/* set architecture and switch to 64bit */
lhi %r1, 1
sigp %r1, %r0, SIGP_SET_ARCHITECTURE
sam64
/* The original stage3 boot loader will try to store the
* kernel command line and the address and size of the
* ramdisk. Simply ignore this by starting at 0x11000.
*/
lgfi %r1, STAGE3A_ENTRY
br %r1
.previous

77
genprotimg/boot/stage3b.c Normal file
View File

@@ -0,0 +1,77 @@
/*
* Main program for stage3b bootloader
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include "libc.h"
#include "stage3b.h"
#include "lib/zt_common.h"
#include "boot/s390.h"
#include "boot/linux_layout.h"
#include "boot/loaders_layout.h"
#include "sclp.h"
#include "error.h"
static volatile struct stage3b_args __section(".loader_parms") loader_parms;
static inline void __noreturn load_psw(struct psw_t psw)
{
asm volatile("lpswe %0" : : "Q"(psw) : "cc");
while (1)
;
}
void __noreturn start(void)
{
volatile struct stage3b_args *args = &loader_parms;
volatile struct memblob *kernel = &args->kernel;
volatile struct memblob *cmdline = &args->cmdline;
volatile struct memblob *initrd = &args->initrd;
volatile struct psw_t psw = args->psw;
/* set up ASCII and line-mode */
sclp_setup(SCLP_LINE_ASCII_INIT);
if (kernel->size < IMAGE_LOAD_ADDRESS)
panic(EINTERNAL, "Invalid kernel\n");
if (cmdline->size > COMMAND_LINE_SIZE)
panic(EINTERNAL, "Command line is too large\n");
/* move the kernel and cut the kernel header */
memmove((void *)IMAGE_LOAD_ADDRESS,
(void *)(kernel->src + IMAGE_LOAD_ADDRESS),
kernel->size - IMAGE_LOAD_ADDRESS);
/* move the kernel cmdline */
memmove((void *)COMMAND_LINE,
(void *)cmdline->src,
cmdline->size);
/* the initrd does not need to be moved */
if (initrd->size != 0) {
/* copy initrd start address and size into new kernel space */
*(unsigned long long *)INITRD_START = initrd->src;
*(unsigned long long *)INITRD_SIZE = initrd->size;
}
/* disable ASCII and line-mode */
sclp_setup(SCLP_DISABLE);
/* use lpswe instead of diag308 as a I/O subsystem reset is not
* needed as this was already done by the diag308 subcode 10 call
* in stage3a
*/
load_psw(psw);
}
void panic_notify(unsigned long UNUSED(rc))
{
}

42
genprotimg/boot/stage3b.h Normal file
View File

@@ -0,0 +1,42 @@
/*
* Main program for stage3b bootloader
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#ifndef STAGE3B_H
#define STAGE3B_H
#include "lib/zt_common.h"
#include "boot/loaders_layout.h"
#define STAGE3B_ENTRY STAGE3_ENTRY
#define STAGE3B_LOAD_ADDRESS STAGE3B_ENTRY
#ifndef __ASSEMBLER__
#include <stdint.h>
#include "boot/s390.h"
/* Must not have any padding included */
struct memblob {
uint64_t src;
uint64_t size;
};
STATIC_ASSERT(sizeof(struct memblob) == 2 * 8)
/* Must not have any padding included */
struct stage3b_args {
struct memblob kernel;
struct memblob cmdline;
struct memblob initrd;
struct psw_t psw;
};
STATIC_ASSERT(sizeof(struct stage3b_args) == 3 * sizeof(struct memblob) + 16)
#endif /* __ASSEMBLER__ */
#endif /* STAGE3B_H */

View File

@@ -0,0 +1,87 @@
/*
* Memory layout for stage 3b
* ==========================
*
* General memory layout
* ---------------------
*
* 0x00000 - 0x01fff Lowcore
* 0x02000 - 0x05fff Memory allocation (heap)
* 0x0a000 - 0x0efff Stage3b code
* 0x0f000 - 0x0ffff Stack
*/
#include "stage3b.h"
#include "common_memory_layout.h"
OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390")
OUTPUT_ARCH(s390:64-bit)
ENTRY(_start)
SECTIONS
{
. = 0x0;
. = HEAP_ADDRESS;
__heap_start = .;
.heap : {
. = . + HEAP_SIZE;
ASSERT(__heap_stop - __heap_start == HEAP_SIZE,
"Heap section doesn't conform to the described memory layout");
}
__heap_stop = .;
. = STAGE3B_ENTRY;
.text : {
head.o(.text.start)
*(.text)
}
.ex_table ALIGN(16) : {
__ex_table_start = .;
*(.ex_table)
__ex_table_stop = .;
}
.bss ALIGN(16) : {
__bss_start = .;
*(.bss)
__bss_stop = .;
}
.rodata ALIGN(16) : {
*(.rodata)
*(.rodata.*)
}
.data ALIGN(16) : {
*(.data)
. = ALIGN(16);
__loader_parms_start = .;
KEEP(*(.loader_parms));
__loader_parms_end = .;
ASSERT(__loader_parms_end - __loader_parms_start == 3 * 16 + 16,
"Data size must be equal to 'sizeof(struct stage3b_args)'");
}
. = STACK_ADDRESS;
__stack_start = .;
.stack : {
. = . + STACK_SIZE;
ASSERT(__stack_end - __stack_start == STACK_SIZE,
"Stack section doesn't conform to the described memory layout");
}
__stack_end = .;
/* List this explicitly as otherwise .note.gnu.build-id will be
* put at 0x0 */
.notes : {
*(.note.*)
}
/* Sections to be discarded */
/DISCARD/ : {
*(.eh_frame)
}
}

View File

@@ -0,0 +1,53 @@
/*
* Relocator code for stage 3b boot loader
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include "stage3b.h"
#include "boot/sigp.h"
.macro MEMCPY dst,src,len
lgr %r0, \dst
lgr %r1, \len
lgr %r2, \src
lgr %r3, \len
20: mvcle %r0, %r2, 0
jo 20b
.endm
.org 0x0
.section .text.start
.globl stage3b_reloc_start
stage3b_reloc_start:
/* Might be called after a diag308 so better set
* architecture and addressing mode
*/
lhi %r1, 1
sigp %r1, %r0, SIGP_SET_ARCHITECTURE
sam64
.copy_stage3b:
/* Location of stage3b in memory */
larl %r8, stage3b_start
/* Destination for stage3b */
lgfi %r9, STAGE3B_LOAD_ADDRESS
/* Size of stage3b */
lghi %r11, stage3b_end - stage3b_start
/* Copy the stage3b loader to address STAGE3B_LOAD_ADDRESS */
MEMCPY %r9, %r8, %r11
/* Branch to STAGE3B_ENTRY */
lgfi %r9, STAGE3B_ENTRY
br %r9
stage3b_start:
.incbin "stage3b.bin"
stage3b_end:
.previous

12
genprotimg/man/Makefile Normal file
View File

@@ -0,0 +1,12 @@
# Common definitions
include ../../common.mak
all:
install:
$(INSTALL) -d -m 755 $(DESTDIR)$(MANDIR)/man8
$(INSTALL) -m 644 -c genprotimg.8 $(DESTDIR)$(MANDIR)/man8
clean:
.PHONY: all install clean

View File

@@ -0,0 +1,97 @@
.\" Copyright 2020 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.
.\"
.TH GENPROTIMG 8 "March 2020" "s390-tools"
.SH NAME
genprotimg \- Create a protected virtualization image
.SH SYNOPSIS
.SY
.B genprotimg
\fB\-k\fR \fIHOST_KEY_DOCUMENT\fR...
\fB\-i\fR \fIVMLINUZ\fR
[\fB\-r\fR \fIRAMDISK\fR]
[\fB\-p\fR \fIPARMFILE\fR]
\fB\-o\fR \fIOUTFILE\fR
[\fIOPTION\fR]...
.YS
.SH DESCRIPTION
.PP
Use \fBgenprotimg\fR to generate a single bootable image file with
encrypted and integrity-protected parts. The command requires a kernel
image, a host-key document, and an output file name. Optionally,
specify an initial RAM filesystem, and a file containing the kernel
parameters. Should special circumstances require it, you can
optionally specify your own keys for the encryption by using the
experimental options. In the resulting image file, a plain text boot
loader, the encrypted components for kernel, initial RAM disk, kernel
parameters, and the encrypted and integrity-protected header are
concatenated. The header contains metadata necessary for running the
guest in protected mode.
.PP
Use this image file as a kernel image for zipl or for a direct kernel
boot using QEMU.
.SH OPTIONS
.TP
\fB\-h\fR, \fB\-\-help\fR
Prints usage information, then exits.
.TP
\fB\-\-help-experimental\fR
Prints experimental usage information, then exits.
.TP
\fB\-\-help-all\fR
Prints all usage information, then exits.
.TP
\fB\-V\fR, \fB\-\-verbose\fR
Provides more detailed output.
.TP
\fB\-k\fR, \fB\-\-host-key-document\fR=\fI\,HOST_KEY_DOCUMENT\/\fR
Specifies a host-key document. At least one is required. Specify this
option multiple times to enable the image to run on more than one
host.
.TP
\fB\-o\fR, \fB\-\-output\fR=\fI\,OUTPUT_FILE\/\fR
Specifies the output file. Required.
.TP
\fB\-i\fR, \fB\-\-image\fR=\fI\,VMLINUZ\/\fR
Specifies the Linux kernel image file. Required.
.TP
\fB\-r\fR, \fB\-\-ramdisk\fR=\fI\,RAMDISK\/\fR
Specifies the RAM disk image. Optional.
.TP
\fB\-p\fR, \fB\-\-parmfile\fR=\fI\,PARMFILE\/\fR
Specifies the kernel command line stored in \fI\,PARMFILE\/\fR. Optional.
.TP
\fB\-\-no-verify\fR
Do not require the host-key documents to be valid. For testing
purposes, do not use for a production image. Optional.
.TP
\fB\-v\fR, \fB\-\-version\fR
Prints version information, then exits.
.SH EXAMPLE
.PP
Generate a protected virtualization image in
\fI\,/boot/vmlinuz.pv\/\fR, using the kernel file \fI\,vmlinuz\/\fR,
the initrd in \fI\,initramfs\/\fR, the kernel parameters contained in
\fI\,parmfile\/\fR, and the host-key document in \fI\,host_key.crt\/\fR:
.PP
.Vb 1
.EX
\& genprotimg \-i \fI\,vmlinuz\/\fR \-r \fI\,initramfs\/\fR \-p \fI\,parmfile\/\fR \-k \fI\,host_key.crt\/\fR \-o \fI\,/boot/vmlinuz.pv\/\fR
.EE
.Ve
.PP
.SH NOTES
.IP "1." 4
An ELF file cannot be used as a Linux kernel image.
.IP "2." 4
Remember to re-run \fBzipl\fR after updating a protected
virtualization image.
.SH SEE ALSO
\&\fBzipl\fR\|(5), \fBqemu\fR\|(1)

View File

@@ -0,0 +1,276 @@
#!/bin/sh
#
# check_hostkeydoc - Verify an IBM Secure Execution host key document
#
# Sample script to verify that a host key document is genuine by
# verifying the issuer, the validity date and the signature.
# Optionally verify the full trust chain using a CA certficate.
#
# Revocation list checking not yet implemented.
#
# Sample invocation:
#
# ./check_hostkeydoc HKD1234.crt signing-key.crt
#
# Copyright IBM Corp. 2020
#
# s390-tools is free software; you can redistribute it and/or modify
# it under the terms of the MIT license. See LICENSE for details.
# Allocate temporary files
ISSUER_PUBKEY_FILE=$(mktemp)
SIGNATURE_FILE=$(mktemp)
BODY_FILE=$(mktemp)
ISSUER_DN_FILE=$(mktemp)
SUBJECT_DN_FILE=$(mktemp)
DEF_ISSUER_DN_FILE=$(mktemp)
CRL_SERIAL_FILE=$(mktemp)
# Cleanup on exit
cleanup()
{
rm -f $ISSUER_PUBKEY_FILE $SIGNATURE_FILE $BODY_FILE \
$ISSUER_DN_FILE $SUBJECT_DN_FILE $DEF_ISSUER_DN_FILE \
$CRL_SERIAL_FILE
}
trap cleanup EXIT
# Enhanced error checking for bash
if echo $SHELL | grep /bin/bash > /dev/null
then
set -o pipefail
set -o nounset
fi
set -e
# Usage
usage()
{
cat <<-EOF
Usage: `basename $1` host-key-doc signing-key-cert [-c CA-cert] [-r CRL]
Verify an IBM Secure Execution host key document against
a signing key.
Note that in order to have the full trust chain verified
it is necessary to provide the issueing CA's certificate.
EOF
}
check_verify_chain()
{
# Verify certificate chain in case a CA certificate file/bundle
# was specified on the command line.
if [ $# = 1 ]
then
cat >&2 <<-EOF
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
No CA certificate specified! Skipping trust chain verification.
Make sure that '$1' is a valid certificate.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
EOF
else
openssl verify -crl_download -crl_check $2 &&
openssl verify -crl_download -crl_check -untrusted $2 $1 ||
exit 1
fi
}
extract_pubkey()
{
openssl x509 -in $1 -pubkey -noout > $2
}
extract_signature()
{
# Assuming that the last field is the signature
SIGOFFSET=$(openssl asn1parse -in $1 | tail -1 | cut -d : -f 1)
openssl asn1parse -in $1 -out $2 -strparse $SIGOFFSET -noout
}
extract_body()
{
# Assuming that the first field is the full cert body
SIGOFFSET=$(openssl asn1parse -in $1 | head -2 | tail -1 | cut -d : -f 1)
openssl asn1parse -in $1 -out $2 -strparse $SIGOFFSET -noout
}
verify_signature()
{
# Assuming that the signature algorith is SHA512 with RSA
openssl sha512 -verify $1 -signature $2 $3
}
canonical_dn()
{
OBJTYPE=$1
OBJ=$2
DNTYPE=$3
OUTPUT=$4
openssl $OBJTYPE -in $OBJ -$DNTYPE -noout -nameopt multiline \
| sort | grep -v $DNTYPE= > $OUTPUT
}
default_issuer()
{
cat <<-EOF
commonName = International Business Machines Corporation
countryName = US
localityName = Poughkeepsie
organizationalUnitName = IBM Z Host Key Signing Service
organizationName = International Business Machines Corporation
stateOrProvinceName = New York
EOF
}
verify_issuer_files()
{
default_issuer > $DEF_ISSUER_DN_FILE
if ! diff $ISSUER_DN_FILE $DEF_ISSUER_DN_FILE
then
echo Incorrect default issuer >&2 && exit 1
fi
if diff $ISSUER_DN_FILE $SUBJECT_DN_FILE
then
echo Issuer verification OK
else
echo Issuer verification failed >&2 && exit 1
fi
}
cert_time()
{
DATE=$(openssl x509 -in $1 -$2 -noout | sed "s/^.*=//")
date -d "$DATE" +%s
}
crl_time()
{
DATE=$(openssl crl -in $1 -$2 -noout | sed "s/^.*=//")
date -d "$DATE" +%s
}
verify_dates()
{
START="$1"
END="$2"
MSG="${3:-Certificate}"
NOW=$(date +%s)
if [ $START -le $NOW -a $NOW -le $END ]
then
echo "${MSG} dates are OK"
else
echo "${MSG} date verification failed" >&2 && exit 1
fi
}
crl_serials()
{
openssl crl -in $1 -text -noout | \
grep "Serial Number" > $CRL_SERIAL_FILE
}
check_serial()
{
CERT_SERIAL=$(openssl x509 -in $1 -noout -serial | cut -d = -f 2)
grep -q $CERT_SERIAL $CRL_SERIAL_FILE
}
check_file()
{
[ $# = 0 ] ||
[ -e "$1" ] ||
(echo "File '$1' not found" >&2 && exit 1)
}
# check args
CRL_FILE=
CA_FILE=
args=$(getopt -qu "r:c:h" $*)
if [ $? = 0 ]
then
set -- $args
while [ $1 != "" ]
do
case $1 in
-r) CRL_FILE=$2; shift 2;;
-c) CA_FILE=$2; shift 2;;
-h) usage $0; exit 0;;
--) shift; break;;
esac
done
else
usage $0 >&2
exit 1
fi
if [ $# -ne 2 ]
then
usage $0 >&2
exit 1
fi
HKD_FILE=$1
HKSK_FILE=$2
# Check whether all specified files exist
check_file $HKD_FILE
check_file $HKSK_FILE
check_file $CA_FILE
check_file $CRL_FILE
# Check trust chain
check_verify_chain $HKSK_FILE $CA_FILE
# Verify host key document signature
echo -n "Checking host key document signature: "
extract_pubkey $HKSK_FILE $ISSUER_PUBKEY_FILE &&
extract_signature $HKD_FILE $SIGNATURE_FILE &&
extract_body $HKD_FILE $BODY_FILE &&
verify_signature $ISSUER_PUBKEY_FILE $SIGNATURE_FILE $BODY_FILE ||
exit 1
# Verify the issuer
canonical_dn x509 $HKD_FILE issuer $ISSUER_DN_FILE
canonical_dn x509 $HKSK_FILE subject $SUBJECT_DN_FILE
verify_issuer_files
# Verify dates
verify_dates $(cert_time $HKD_FILE startdate) $(cert_time $HKD_FILE enddate)
# Check CRL if specified
if [ -n "$CRL_FILE" ]
then
echo -n "Checking CRL signature: "
extract_signature $CRL_FILE $SIGNATURE_FILE &&
extract_body $CRL_FILE $BODY_FILE &&
verify_signature $ISSUER_PUBKEY_FILE $SIGNATURE_FILE $BODY_FILE ||
exit 1
echo -n "CRL "
canonical_dn crl $CRL_FILE issuer $ISSUER_DN_FILE
canonical_dn x509 $HKSK_FILE subject $SUBJECT_DN_FILE
verify_issuer_files
verify_dates $(crl_time $CRL_FILE lastupdate) $(crl_time $CRL_FILE nextupdate) 'CRL'
crl_serials $CRL_FILE
check_serial $HKD_FILE &&
echo "Certificate is revoked, do not use it anymore!" >&2 &&
exit 1
fi
# We made it
echo All checks reqested for \'$HKD_FILE\' were successful

101
genprotimg/src/Makefile Normal file
View File

@@ -0,0 +1,101 @@
# Common definitions
include ../../common.mak
bin_PROGRAM = genprotimg
PKGDATADIR ?= "$(DESTDIR)$(TOOLS_DATADIR)/genprotimg"
SRC_DIR := $(dir $(realpath $(firstword $(MAKEFILE_LIST))))
TOP_SRCDIR := $(SRC_DIR)/../
ROOT_DIR = $(TOP_SRC_DIR)/../../
ZIPL_DIR = $(ROOT_DIR)/zipl
LOADER_DIR = $(TOP_SRCDIR)/boot
INCLUDE_PATHS = "$(SRC_DIR)" "$(TOP_SRCDIR)" "$(ROOTDIR)/include"
INCLUDE_PARMS = $(addprefix -I,$(INCLUDE_PATHS))
WARNINGS := -Wall -Wextra -Wshadow \
-Wcast-align -Wwrite-strings -Wmissing-prototypes \
-Wmissing-declarations -Wredundant-decls -Wnested-externs -Winline \
-Wno-long-long -Wuninitialized -Wconversion -Wstrict-prototypes \
-Wpointer-arith -Werror \
$(NULL)
$(bin_PROGRAM)_SRCS := $(bin_PROGRAM).c pv/pv_stage3.c pv/pv_image.c \
pv/pv_comp.c pv/pv_hdr.c pv/pv_ipib.c utils/crypto.c utils/file_utils.c \
pv/pv_args.c utils/buffer.c pv/pv_comps.c pv/pv_error.c \
pv/pv_opt_item.c \
$(NULL)
$(bin_PROGRAM)_OBJS := $($(bin_PROGRAM)_SRCS:.c=.o)
ALL_CFLAGS += -std=gnu11 -DPKGDATADIR=$(PKGDATADIR) \
$(GLIB2_CFLAGS) $(LIBCRYPTO_CFLAGS) \
$(WARNINGS) \
$(NULL)
ALL_CPPFLAGS += $(INCLUDE_PARMS)
LDLIBS += $(GLIB2_LIBS) $(LIBCRYPTO_LIBS)
ifneq ($(shell sh -c 'command -v pkg-config'),)
GLIB2_CFLAGS := $(shell pkg-config --silence-errors --cflags glib-2.0)
GLIB2_LIBS := $(shell pkg-config --silence-errors --libs glib-2.0)
LIBCRYPTO_CFLAGS := $(shell pkg-config --silence-errors --cflags libcrypto)
LIBCRYPTO_LIBS := $(shell pkg-config --silence-errors --libs libcrypto)
else
GLIB2_CFLAGS := -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include
GLIB2_LIBS := -lglib-2.0
LIBCRYPTO_CFLAGS :=
LIBCRYPTO_LIBS := -lcrypto
endif
BUILD_TARGETS := skip-$(bin_PROGRAM)
INSTALL_TARGETS := skip-$(bin_PROGRAM)
ifneq (${HAVE_OPENSSL},0)
ifneq (${HAVE_GLIB2},0)
BUILD_TARGETS := $(bin_PROGRAM)
INSTALL_TARGETS := install-$(bin_PROGRAM)
endif
endif
all: $(BUILD_TARGETS)
install: $(INSTALL_TARGETS)
$(bin_PROGRAM): $($(bin_PROGRAM)_OBJS)
skip-$(bin_PROGRAM):
echo " SKIP $(bin_PROGRAM) due to unresolved dependencies"
install-$(bin_PROGRAM): $(bin_PROGRAM)
$(INSTALL) -d -m 755 $(DESTDIR)$(USRBINDIR)
$(INSTALL) -c $^ $(DESTDIR)$(USRBINDIR)
clean:
$(RM) -f $($(bin_PROGRAM)_OBJS) $(bin_PROGRAM) .check-dep-$(bin_PROGRAM) .detect-openssl.dep.c
.PHONY: all install clean skip-$(bin_PROGRAM) install-$(bin_PROGRAM)
$($(bin_PROGRAM)_OBJS): .check-dep-$(bin_PROGRAM)
.detect-openssl.dep.c:
echo "#include <openssl/evp.h>" > $@
echo "#if OPENSSL_VERSION_NUMBER < 0x10100000L" >> $@
echo " #error openssl version 1.1.0 is required" >> $@
echo "#endif" >> $@
echo "static void __attribute__((unused)) test(void) {" >> $@
echo " EVP_MD_CTX *ctx = EVP_MD_CTX_new();" >> $@
echo " EVP_MD_CTX_free(ctx);" >> $@
echo "}" >> $@
.check-dep-$(bin_PROGRAM): .detect-openssl.dep.c
$(call check_dep, \
"$(bin_PROGRAM)", \
"glib.h", \
"glib2-devel / libglib2.0-dev", \
"HAVE_GLIB2=0")
$(call check_dep, \
"$(bin_PROGRAM)", \
$^, \
"openssl-devel / libssl-dev version >= 1.1.0", \
"HAVE_OPENSSL=0", \
"-I.")
touch $@

35
genprotimg/src/common.h Normal file
View File

@@ -0,0 +1,35 @@
#ifndef COMMON_H
#define COMMON_H
#define GETTEXT_PACKAGE "genprotimg"
#include <glib.h>
#include <glib/gi18n-lib.h>
#include "boot/linux_layout.h"
#include "boot/s390.h"
#include "lib/zt_common.h"
static const gchar tool_name[] = "genprotimg";
static const gchar copyright_notice[] = "Copyright IBM Corp. 2020";
/* default values */
#define GENPROTIMG_STAGE3A_PATH (STRINGIFY(PKGDATADIR) "/stage3a.bin")
#define GENPROTIMG_STAGE3B_PATH (STRINGIFY(PKGDATADIR) "/stage3b_reloc.bin")
#define DEFAULT_INITIAL_PSW_ADDR IMAGE_ENTRY
#define DEFAULT_INITIAL_PSW_MASK (PSW_MASK_EA | PSW_MASK_BA)
#define DO_PRAGMA(x) _Pragma(#x)
# ifdef __clang__
# define WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(...) \
DO_PRAGMA(clang diagnostic push) \
DO_PRAGMA(clang diagnostic ignored "-Wunused-function") \
G_DEFINE_AUTOPTR_CLEANUP_FUNC(__VA_ARGS__) \
DO_PRAGMA(clang diagnostic pop)
# else
# define WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(...) \
G_DEFINE_AUTOPTR_CLEANUP_FUNC(__VA_ARGS__)
# endif
#endif

181
genprotimg/src/genprotimg.c Normal file
View File

@@ -0,0 +1,181 @@
/*
* genprotimg - build relocatable secure images
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include <errno.h>
#include <glib.h>
#include <glib/gstdio.h>
#include <glib/gtypes.h>
#include <locale.h>
#include <signal.h>
#include <stdio.h>
#include "common.h"
#include "pv/pv_args.h"
#include "pv/pv_image.h"
enum {
LOG_LEVEL_CRITICAL = 0,
LOG_LEVEL_INFO = 1,
LOG_LEVEL_DEBUG = 2,
};
static gint log_level = LOG_LEVEL_CRITICAL;
static gchar *tmp_dir;
static void rmdir_recursive(gchar *dir_path, GError **err)
{
const gchar *file = NULL;
g_autoptr(GDir) d = NULL;
if (!dir_path)
return;
d = g_dir_open(dir_path, 0, err);
if (!d) {
g_set_error(err, G_FILE_ERROR,
(gint)g_file_error_from_errno(errno),
_("Failed to open directory '%s': %s"), dir_path,
g_strerror(errno));
return;
}
while ((file = g_dir_read_name(d)) != NULL) {
g_autofree gchar *file_path =
g_build_filename(dir_path, file, NULL);
/* ignore error */
(void)g_unlink(file_path);
}
if (g_rmdir(dir_path) != 0) {
g_set_error(err, G_FILE_ERROR,
(gint)g_file_error_from_errno(errno),
_("Failed to remove directory '%s': %s"), dir_path,
g_strerror(errno));
return;
}
}
static void sig_term_handler(int signal G_GNUC_UNUSED)
{
rmdir_recursive(tmp_dir, NULL);
exit(EXIT_FAILURE);
}
static void log_handler_cb(const gchar *log_domain G_GNUC_UNUSED,
GLogLevelFlags level, const gchar *message,
gpointer user_data G_GNUC_UNUSED)
{
const gchar *prefix = "";
/* filter out messages depending on debugging level */
if ((level & G_LOG_LEVEL_DEBUG) && log_level < LOG_LEVEL_DEBUG)
return;
if ((level & G_LOG_LEVEL_INFO) && log_level < LOG_LEVEL_INFO)
return;
if (level & G_LOG_LEVEL_WARNING)
prefix = "WARNING: ";
if (level & G_LOG_LEVEL_ERROR)
prefix = "ERROR: ";
if (level & (G_LOG_LEVEL_WARNING | G_LOG_LEVEL_ERROR))
g_printerr("%s%s\n", prefix, message);
else
g_print("%s%s\n", prefix, message);
}
static void setup_prgname(const gchar *name)
{
g_set_prgname(name);
g_set_application_name(_(name));
}
static void setup_handler(const gint *signals, const gsize signals_n)
{
/* set up logging handler */
g_log_set_handler(NULL,
G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL |
G_LOG_FLAG_RECURSION,
log_handler_cb, NULL);
/* set signal handler */
for (gsize i = 0; i < signals_n; i++)
signal(signals[i], sig_term_handler);
}
static void remove_signal_handler(const gint *signals, const gsize signals_n)
{
for (gsize i = 0; i < signals_n; i++)
signal(signals[i], SIG_DFL);
}
gint main(gint argc, gchar *argv[])
{
g_autoptr(PvArgs) args = pv_args_new();
gint signals[] = { SIGINT, SIGTERM };
g_autoptr(PvImage) img = NULL;
gint ret = EXIT_FAILURE;
GError *err = NULL;
setlocale(LC_CTYPE, "");
setup_prgname(tool_name);
setup_handler(signals, G_N_ELEMENTS(signals));
if (pv_args_parse_options(args, &argc, &argv, &err) < 0)
goto error;
/* set new log level */
log_level = args->log_level;
/* if the user has not specified a temporary directory let's
* create one
*/
if (!args->tmp_dir) {
tmp_dir = g_dir_make_tmp("genprotimg-XXXXXX", &err);
if (!tmp_dir)
goto error;
args->tmp_dir = g_strdup(tmp_dir);
}
/* allocate and initialize ``pv_img`` data structure */
img = pv_img_new(args, GENPROTIMG_STAGE3A_PATH, &err);
if (!img)
goto error;
/* add user components: `args->comps` must be sorted by the
* component type => by memory address
*/
for (GSList *iterator = args->comps; iterator; iterator = iterator->next) {
const PvArg *arg = iterator->data;
if (pv_img_add_component(img, arg, &err) < 0)
goto error;
}
if (pv_img_finalize(img, GENPROTIMG_STAGE3B_PATH, &err) < 0)
goto error;
if (pv_img_write(img, args->output_path, &err) < 0)
goto error;
ret = EXIT_SUCCESS;
error:
if (err) {
fputs(err->message, stderr);
fputc('\n', stderr);
g_clear_error(&err);
}
rmdir_recursive(tmp_dir, NULL);
remove_signal_handler(signals, G_N_ELEMENTS(signals));
g_free(tmp_dir);
exit(ret);
}

View File

@@ -0,0 +1,25 @@
/*
* PV cryptography related definitions
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#ifndef PV_CRYPTO_DEF_H
#define PV_CRYPTO_DEF_H
#include <stdint.h>
#include "lib/zt_common.h"
union ecdh_pub_key {
struct {
uint8_t x[80];
uint8_t y[80];
};
uint8_t data[160];
} __packed;
#endif

View File

@@ -0,0 +1,84 @@
/*
* PV header definitions
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#ifndef PV_HDR_DEF_H
#define PV_HDR_DEF_H
#include <openssl/sha.h>
#include "boot/s390.h"
#include "lib/zt_common.h"
#include "utils/crypto.h"
#include "pv_crypto_def.h"
/* Magic number which is used to identify the file containing the PV
* header
*/
#define PV_MAGIC_NUMBER 0x49424d5365634578ULL
#define PV_VERSION_1 0x00000100U
/* prevent Ultravisor decryption during unpack operation */
#define PV_CFLAG_NO_DECRYPTION 0x10000000ULL
/* maxima for the PV version 1 */
#define PV_V1_IPIB_MAX_SIZE PAGE_SIZE
#define PV_V1_PV_HDR_MAX_SIZE (2 * PAGE_SIZE)
typedef struct pv_hdr_key_slot {
uint8_t digest_key[SHA256_DIGEST_LENGTH];
uint8_t wrapped_key[32];
uint8_t tag[AES_256_GCM_TAG_SIZE];
} __packed PvHdrKeySlot;
typedef struct pv_hdr_opt_item {
uint32_t otype;
uint8_t ibk[32];
uint8_t data[];
} __packed PvHdrOptItem;
/* integrity protected data (by GCM tag), but non-encrypted */
struct pv_hdr_head {
uint64_t magic;
uint32_t version;
uint32_t phs;
uint8_t iv[AES_256_GCM_IV_SIZE];
uint32_t res1;
uint64_t nks;
uint64_t sea;
uint64_t nep;
uint64_t pcf;
union ecdh_pub_key cust_pub_key;
uint8_t pld[SHA512_DIGEST_LENGTH];
uint8_t ald[SHA512_DIGEST_LENGTH];
uint8_t tld[SHA512_DIGEST_LENGTH];
} __packed;
/* Must not have any padding */
struct pv_hdr_encrypted {
uint8_t cust_comm_key[32];
uint8_t img_enc_key_1[AES_256_XTS_KEY_SIZE / 2];
uint8_t img_enc_key_2[AES_256_XTS_KEY_SIZE / 2];
struct psw_t psw;
uint64_t scf;
uint32_t noi;
uint32_t res2;
};
STATIC_ASSERT(sizeof(struct pv_hdr_encrypted) ==
32 + 32 + 32 + sizeof(struct psw_t) + 8 + 4 + 4)
typedef struct pv_hdr {
struct pv_hdr_head head;
struct pv_hdr_key_slot *slots;
struct pv_hdr_encrypted *encrypted;
struct pv_hdr_opt_item **optional_items;
uint8_t tag[AES_256_GCM_TAG_SIZE];
} PvHdr;
#endif

405
genprotimg/src/pv/pv_args.c Normal file
View File

@@ -0,0 +1,405 @@
/*
* PV arguments related definitions and functions
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include <glib.h>
#include <glib/gprintf.h>
#include "common.h"
#include "pv_comp.h"
#include "pv_error.h"
#include "pv_args.h"
static gchar summary[] =
"Use genprotimg to create a protected virtualization kernel image file,\n"
"which can be loaded using zipl or QEMU.";
static gint pv_arg_compare(gconstpointer arg_1, gconstpointer arg_2)
{
g_assert(arg_1);
g_assert(arg_2);
PvComponentType a = ((PvArg *)arg_1)->type;
PvComponentType b = ((PvArg *)arg_2)->type;
if (a < b)
return -1;
if (a == b)
return 0;
return 1;
}
static gint pv_arg_has_type(gconstpointer arg, gconstpointer type)
{
const PvArg *c = arg;
const PvComponentType *t = type;
g_assert(arg);
if (c->type == *t)
return 0;
if (c->type < *t)
return -1;
return 1;
}
static gint pv_args_set_defaults(PvArgs *args, GError **err G_GNUC_UNUSED)
{
if (!args->psw_addr)
args->psw_addr =
g_strdup_printf("0x%lx", DEFAULT_INITIAL_PSW_ADDR);
return 0;
}
static gint pv_args_validate_options(PvArgs *args, GError **err)
{
PvComponentType KERNEL = PV_COMP_TYPE_KERNEL;
if (args->unused_values->len > 0) {
g_autofree gchar *unused = NULL;
for (gsize i = args->unused_values->len; i > 0; i--) {
g_autofree gchar *tmp = unused;
unused = g_strjoin(" ", g_ptr_array_index(args->unused_values, i - 1),
tmp,
NULL);
}
g_set_error(err, PV_PARSE_ERROR, PR_PARSE_ERROR_INVALID_ARGUMENT,
_("Unrecognized arguments: '%s'.\nUse 'genprotimg --help' for more information"),
unused);
return -1;
}
if (!args->output_path) {
g_set_error(err, PV_PARSE_ERROR, PR_PARSE_ERROR_MISSING_ARGUMENT,
_("Option '--output' is required.\nUse 'genprotimg --help' for more information"));
return -1;
}
if (!g_slist_find_custom(args->comps, &KERNEL, pv_arg_has_type)) {
g_set_error(err, PV_PARSE_ERROR, PR_PARSE_ERROR_MISSING_ARGUMENT,
_("Option '--image' is required.\nUse 'genprotimg --help' for more information"));
return -1;
}
if (!args->host_keys || g_strv_length(args->host_keys) == 0) {
g_set_error(err, PV_PARSE_ERROR, PR_PARSE_ERROR_MISSING_ARGUMENT,
_("Option '--host-key-document' is required.\nUse 'genprotimg --help' for more information"));
return -1;
}
if (!args->no_verify) {
g_set_error(err, PV_PARSE_ERROR, PR_PARSE_ERROR_MISSING_ARGUMENT,
_("Use the option '--no-verify' as the verification support is not available yet."));
return -1;
}
return 0;
}
static gboolean cb_add_component(const gchar *option, const gchar *value,
PvArgs *args, GError **err)
{
PvArg *comp = NULL;
gint type = -1;
if (g_str_equal(option, "-i") || g_str_equal(option, "--image"))
type = PV_COMP_TYPE_KERNEL;
if (g_str_equal(option, "-r") || g_str_equal(option, "--ramdisk"))
type = PV_COMP_TYPE_INITRD;
if (g_str_equal(option, "-p") || g_str_equal(option, "--parmfile"))
type = PV_COMP_TYPE_CMDLINE;
if (type < 0) {
g_set_error(err, PV_PARSE_ERROR, PV_PARSE_ERROR_SYNTAX,
_("Invalid option '%s': "), option);
return FALSE;
}
if (g_slist_find_custom(args->comps, &type, pv_arg_has_type)) {
g_set_error(err, PV_PARSE_ERROR, PV_PARSE_ERROR_SYNTAX,
_("Multiple values for option '%s'"), option);
return FALSE;
}
comp = pv_arg_new((PvComponentType)type, value);
args->comps = g_slist_insert_sorted(args->comps, comp, pv_arg_compare);
return TRUE;
}
static gboolean cb_set_string_option(const gchar *option, const gchar *value,
PvArgs *args, GError **err)
{
gchar **args_option = NULL;
if (g_str_equal(option, "-o") || g_str_equal(option, "--output"))
args_option = &args->output_path;
if (g_str_equal(option, "--x-comp-key"))
args_option = &args->xts_key_path;
if (g_str_equal(option, "--x-comm-key"))
args_option = &args->cust_comm_key_path;
if (g_str_equal(option, "--x-header-key"))
args_option = &args->cust_root_key_path;
if (g_str_equal(option, "--x-pcf"))
args_option = &args->pcf;
if (g_str_equal(option, "--x-psw"))
args_option = &args->psw_addr;
if (g_str_equal(option, "--x-scf"))
args_option = &args->scf;
if (!args_option) {
g_set_error(err, PV_PARSE_ERROR, PV_PARSE_ERROR_SYNTAX,
_("Invalid option '%s': "), option);
return FALSE;
}
if (*args_option) {
g_set_error(err, PV_PARSE_ERROR, PV_PARSE_ERROR_SYNTAX,
_("Multiple values for option '%s'"), option);
return FALSE;
}
*args_option = g_strdup(value);
return TRUE;
}
static gboolean cb_set_log_level(const gchar *option G_GNUC_UNUSED,
const gchar *value G_GNUC_UNUSED, PvArgs *args,
GError **err G_GNUC_UNUSED)
{
args->log_level++;
return TRUE;
}
static gboolean cb_remaining_values(const gchar *option G_GNUC_UNUSED,
const gchar *value, PvArgs *args,
GError **err G_GNUC_UNUSED)
{
g_ptr_array_add(args->unused_values, g_strdup(value));
return TRUE;
}
#define INDENT " "
gint pv_args_parse_options(PvArgs *args, gint *argc, gchar **argv[],
GError **err)
{
g_autoptr(GOptionContext) context = NULL;
gboolean print_version = FALSE;
GOptionGroup *group, *x_group;
g_autofree gchar *psw_desc = g_strdup_printf(
_("Load from the specified hexadecimal ADDRESS.\n" INDENT
"Optional; default: '0x%lx'."),
DEFAULT_INITIAL_PSW_ADDR);
GOptionEntry entries[] = {
{ .long_name = "host-key-document",
.short_name = 'k',
.flags = G_OPTION_FLAG_NONE,
.arg = G_OPTION_ARG_FILENAME_ARRAY,
.arg_data = &args->host_keys,
.description =
_("FILE specifies a host-key document. At least\n" INDENT
"one is required."),
.arg_description = _("FILE") },
{ .long_name = "output",
.short_name = 'o',
.flags = G_OPTION_FLAG_FILENAME,
.arg = G_OPTION_ARG_CALLBACK,
.arg_data = cb_set_string_option,
.description = _("Set FILE as the output file."),
.arg_description = _("FILE") },
{ .long_name = "image",
.short_name = 'i',
.flags = G_OPTION_FLAG_FILENAME,
.arg = G_OPTION_ARG_CALLBACK,
.arg_data = cb_add_component,
.description = _("Use IMAGE as the Linux kernel image."),
.arg_description = _("IMAGE") },
{ .long_name = "ramdisk",
.short_name = 'r',
.flags = G_OPTION_FLAG_OPTIONAL_ARG | G_OPTION_FLAG_FILENAME,
.arg = G_OPTION_ARG_CALLBACK,
.arg_data = cb_add_component,
.description = _("Use RAMDISK as the initial RAM disk\n" INDENT
"(optional)."),
.arg_description = _("RAMDISK") },
{ .long_name = "parmfile",
.short_name = 'p',
.flags = G_OPTION_FLAG_OPTIONAL_ARG | G_OPTION_FLAG_FILENAME,
.arg = G_OPTION_ARG_CALLBACK,
.arg_data = cb_add_component,
.description = _("Use the kernel parameters stored in PARMFILE\n" INDENT
"(optional)."),
.arg_description = _("PARMFILE") },
{ .long_name = "no-verify",
.short_name = 0,
.flags = G_OPTION_FLAG_NONE,
.arg = G_OPTION_ARG_NONE,
.arg_data = &args->no_verify,
.description = _("Disable the host-key document verification\n" INDENT
"(optional)."),
.arg_description = NULL },
{ .long_name = "verbose",
.short_name = 'V',
.flags = G_OPTION_FLAG_NO_ARG,
.arg = G_OPTION_ARG_CALLBACK,
.arg_data = cb_set_log_level,
.description = _("Provide more detailed output (optional)."),
.arg_description = NULL },
{ .long_name = "version",
.short_name = 'v',
.flags = G_OPTION_FLAG_NONE,
.arg = G_OPTION_ARG_NONE,
.arg_data = &print_version,
.description = _("Print the version and exit."),
.arg_description = NULL },
{ .long_name = G_OPTION_REMAINING,
.short_name = 0,
.flags = 0,
.arg = G_OPTION_ARG_CALLBACK,
.arg_data = cb_remaining_values,
.description = NULL,
.arg_description = NULL },
{ 0 },
};
GOptionEntry x_entries[] = {
{ .long_name = "x-comm-key",
.short_name = 0,
.flags = G_OPTION_FLAG_FILENAME,
.arg = G_OPTION_ARG_CALLBACK,
.arg_data = cb_set_string_option,
.description = _(
"Use FILE as the customer communication key.\n" INDENT
"Optional; default: auto-generated."),
.arg_description = _("FILE") },
{ .long_name = "x-comp-key",
.short_name = 0,
.flags = G_OPTION_FLAG_FILENAME,
.arg = G_OPTION_ARG_CALLBACK,
.arg_data = cb_set_string_option,
.description = _(
"Use FILE as the AES 256-bit XTS key\n" INDENT
"that is used for the component encryption.\n" INDENT
"Optional; default: auto-generated."),
.arg_description = _("FILE") },
{ .long_name = "x-header-key",
.short_name = 0,
.flags = G_OPTION_FLAG_FILENAME,
.arg = G_OPTION_ARG_CALLBACK,
.arg_data = cb_set_string_option,
.description = _(
"Use FILE as the AES 256-bit GCM header key\n" INDENT
"that protects the PV header.\n" INDENT
"Optional; default: auto-generated."),
.arg_description = _("FILE") },
{ .long_name = "x-pcf",
.short_name = 0,
.flags = G_OPTION_FLAG_NONE,
.arg = G_OPTION_ARG_CALLBACK,
.arg_data = cb_set_string_option,
.description =
_("Specify the plaintext control flags\n" INDENT
"as a hexadecimal value.\n" INDENT
"Optional; default: '0x0'."),
.arg_description = _("VALUE") },
{ .long_name = "x-psw",
.short_name = 0,
.flags = G_OPTION_FLAG_NONE,
.arg = G_OPTION_ARG_CALLBACK,
.arg_data = cb_set_string_option,
.description = psw_desc,
.arg_description = _("ADDRESS") },
{ .long_name = "x-scf",
.short_name = 0,
.flags = G_OPTION_FLAG_NONE,
.arg = G_OPTION_ARG_CALLBACK,
.arg_data = cb_set_string_option,
.description = _("Specify the secret control flags\n" INDENT
"as a hexadecimal value.\n" INDENT
"Optional; default: '0x0'."),
.arg_description = _("VALUE") },
{ 0 },
};
context = g_option_context_new(
_("- Create a protected virtualization image"));
g_option_context_set_summary(context, _(summary));
group = g_option_group_new(GETTEXT_PACKAGE, _("Application Options:"),
_("Show help options"), args, NULL);
g_option_group_add_entries(group, entries);
g_option_context_set_main_group(context, group);
x_group = g_option_group_new("experimental", _("Experimental Options:"),
_("Show experimental options"), args, NULL);
g_option_group_add_entries(x_group, x_entries);
g_option_context_add_group(context, x_group);
if (!g_option_context_parse(context, argc, argv, err))
return -1;
if (print_version) {
g_printf(_("%s version %s\n"), tool_name, RELEASE_STRING);
g_printf("%s\n", copyright_notice);
exit(EXIT_SUCCESS);
}
if (pv_args_set_defaults(args, err) < 0)
return -1;
return pv_args_validate_options(args, err);
}
PvArgs *pv_args_new(void)
{
g_autoptr(PvArgs) args = g_new0(PvArgs, 1);
args->unused_values = g_ptr_array_new_with_free_func(g_free);
return g_steal_pointer(&args);
}
void pv_args_free(PvArgs *args)
{
if (!args)
return;
g_free(args->pcf);
g_free(args->scf);
g_free(args->psw_addr);
g_free(args->cust_root_key_path);
g_free(args->cust_comm_key_path);
g_free(args->gcm_iv_path);
g_strfreev(args->host_keys);
g_free(args->xts_key_path);
g_slist_free_full(args->comps, (GDestroyNotify)pv_arg_free);
g_ptr_array_free(args->unused_values, TRUE);
g_free(args->output_path);
g_free(args->tmp_dir);
g_free(args);
}
void pv_arg_free(PvArg *arg)
{
if (!arg)
return;
g_free(arg->path);
g_free(arg);
}
PvArg *pv_arg_new(PvComponentType type, const gchar *path)
{
g_autoptr(PvArg) ret = g_new0(struct pv_arg, 1);
ret->type = type;
ret->path = g_strdup(path);
return g_steal_pointer(&ret);
}

View File

@@ -0,0 +1,53 @@
/*
* PV arguments related definitions and functions
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#ifndef PV_ARGS_H
#define PV_ARGS_H
#include <glib.h>
#include "pv_comp.h"
typedef struct pv_arg {
PvComponentType type;
gchar *path;
} PvArg;
PvArg *pv_arg_new(PvComponentType type, const gchar *path);
void pv_arg_free(PvArg *arg);
typedef struct {
gint log_level;
gint no_verify;
gchar *pcf;
gchar *scf;
gchar *psw_addr; /* PSW address which will be used for the start of
* the actual component (e.g. Linux kernel)
*/
gchar *cust_root_key_path;
gchar *cust_comm_key_path;
gchar *gcm_iv_path;
gchar **host_keys;
gchar *xts_key_path;
GSList *comps;
gchar *output_path;
gchar *tmp_dir;
GPtrArray *unused_values;
} PvArgs;
PvArgs *pv_args_new(void);
void pv_args_free(PvArgs *args);
gint pv_args_parse_options(PvArgs *args, gint *argc, gchar **argv[],
GError **err);
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(PvArg, pv_arg_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(PvArgs, pv_args_free)
#endif

446
genprotimg/src/pv/pv_comp.c Normal file
View File

@@ -0,0 +1,446 @@
/*
* PV component related definitions and functions
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include <glib.h>
#include <glib/gtypes.h>
#include <openssl/bn.h>
#include <openssl/evp.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "boot/s390.h"
#include "common.h"
#include "utils/align.h"
#include "utils/buffer.h"
#include "utils/crypto.h"
#include "utils/file_utils.h"
#include "pv_comp.h"
#include "pv_error.h"
static void comp_file_free(CompFile *comp)
{
if (!comp)
return;
g_free(comp->path);
g_free(comp);
}
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(CompFile, comp_file_free)
static PvComponent *pv_component_new(PvComponentType type, gsize size,
PvComponentDataType d_type, void **data,
GError **err)
{
g_autoptr(PvComponent) ret = g_new0(PvComponent, 1);
g_assert(type >= 0 && type <= UINT16_MAX);
ret->type = (int)type;
ret->d_type = (int)d_type;
ret->data = g_steal_pointer(data);
ret->orig_size = size;
if (generate_tweak(&ret->tweak, (uint16_t)type, err) < 0)
return NULL;
return g_steal_pointer(&ret);
}
PvComponent *pv_component_new_file(PvComponentType type, const gchar *path,
GError **err)
{
g_autoptr(CompFile) file = g_new0(CompFile, 1);
gsize size;
gint rc;
g_assert(path != NULL);
rc = file_size(path, &size, err);
if (rc < 0)
return NULL;
file->path = g_strdup(path);
file->size = size;
return pv_component_new(type, size, DATA_FILE, (void **)&file, err);
}
PvComponent *pv_component_new_buf(PvComponentType type, const Buffer *buf,
GError **err)
{
g_assert(buf);
g_autoptr(Buffer) dup_buf = buffer_dup(buf, FALSE);
return pv_component_new(type, buf->size, DATA_BUFFER, (void **)&dup_buf,
err);
}
void pv_component_free(PvComponent *component)
{
if (!component)
return;
switch ((PvComponentDataType)component->d_type) {
case DATA_BUFFER:
buffer_clear(&component->buf);
break;
case DATA_FILE:
comp_file_free(component->file);
break;
}
g_free(component);
}
gint pv_component_type(const PvComponent *component)
{
return component->type;
}
const gchar *pv_component_name(const PvComponent *component)
{
gint type = pv_component_type(component);
switch ((PvComponentType)type) {
case PV_COMP_TYPE_KERNEL:
return "kernel";
case PV_COMP_TYPE_INITRD:
return "ramdisk";
case PV_COMP_TYPE_CMDLINE:
return "parmline";
case PV_COMP_TYPE_STAGE3B:
return "stage3b";
}
g_assert_not_reached();
}
uint64_t pv_component_size(const PvComponent *component)
{
switch ((PvComponentDataType)component->d_type) {
case DATA_BUFFER:
return component->buf->size;
case DATA_FILE:
return component->file->size;
}
g_assert_not_reached();
}
uint64_t pv_component_get_src_addr(const PvComponent *component)
{
return component->src_addr;
}
uint64_t pv_component_get_orig_size(const PvComponent *component)
{
return component->orig_size;
}
uint64_t pv_component_get_tweak_prefix(const PvComponent *component)
{
return GUINT64_FROM_BE(component->tweak.cmp_idx.data);
}
gboolean pv_component_is_stage3b(const PvComponent *component)
{
return pv_component_type(component) == PV_COMP_TYPE_STAGE3B;
}
gint pv_component_align_and_encrypt(PvComponent *component, const gchar *tmp_path,
void *opaque, GError **err)
{
struct cipher_parms *parms = opaque;
switch ((PvComponentDataType)component->d_type) {
case DATA_BUFFER: {
g_autoptr(Buffer) enc_buf = NULL;
if (!(IS_PAGE_ALIGNED(pv_component_size(component)))) {
g_autoptr(Buffer) new = NULL;
/* create a page aligned copy */
new = buffer_dup(component->buf, TRUE);
buffer_clear(&component->buf);
component->buf = g_steal_pointer(&new);
}
enc_buf = encrypt_buf(parms, component->buf, err);
if (!enc_buf)
return -1;
buffer_clear(&component->buf);
component->buf = g_steal_pointer(&enc_buf);
return 0;
}
case DATA_FILE: {
const gchar *comp_name = pv_component_name(component);
gchar *path_in = component->file->path;
g_autofree gchar *path_out = NULL;
gsize orig_size;
gsize prep_size;
g_assert(path_in);
path_out = g_build_filename(tmp_path, comp_name, NULL);
if (encrypt_file(parms, path_in, path_out, &orig_size,
&prep_size, err) < 0)
return -1;
if (component->orig_size != orig_size) {
g_set_error(err, G_FILE_ERROR, PV_ERROR_INTERNAL,
_("File has changed during the preparation '%s'"),
path_out);
return -1;
}
g_free(component->file->path);
component->file->size = prep_size;
component->file->path = g_steal_pointer(&path_out);
return 0;
}
}
g_assert_not_reached();
}
/* Page align the size of the component */
gint pv_component_align(PvComponent *component, const gchar *tmp_path,
void *opaque G_GNUC_UNUSED, GError **err)
{
if (IS_PAGE_ALIGNED(pv_component_size(component)))
return 0;
switch (component->d_type) {
case DATA_BUFFER: {
g_autoptr(Buffer) buf = NULL;
buf = buffer_dup(component->buf, TRUE);
buffer_clear(&component->buf);
component->buf = g_steal_pointer(&buf);
return 0;
} break;
case DATA_FILE: {
const gchar *comp_name = pv_component_name(component);
g_autofree gchar *path_out =
g_build_filename(tmp_path, comp_name, NULL);
gchar *path_in = component->file->path;
gsize size_out;
if (pad_file_right(path_out, path_in, &size_out, PAGE_SIZE,
err) < 0)
return -1;
g_free(component->file->path);
component->file->path = g_steal_pointer(&path_out);
component->file->size = size_out;
return 0;
} break;
}
g_assert_not_reached();
}
/* Convert uint64_t address to byte array */
static void uint64_to_uint8_buf(uint8_t dst[8], uint64_t addr)
{
uint8_t *p = (uint8_t *)&addr;
g_assert(dst);
for (gint i = 0; i < 8; i++) {
/* cppcheck-suppress objectIndex */
dst[i] = p[i];
}
}
int64_t pv_component_update_ald(const PvComponent *comp, EVP_MD_CTX *ctx,
GError **err)
{
uint64_t addr = pv_component_get_src_addr(comp);
uint64_t size = pv_component_size(comp);
uint64_t cur = addr;
int64_t nep = 0;
g_assert(IS_PAGE_ALIGNED(size) && size != 0);
do {
uint64_t cur_be = GUINT64_TO_BE(cur);
uint8_t addr_buf[8];
uint64_to_uint8_buf(addr_buf, cur_be);
if (EVP_DigestUpdate(ctx, addr_buf, sizeof(addr_buf)) != 1) {
g_set_error(err, PV_CRYPTO_ERROR,
PV_CRYPTO_ERROR_INTERNAL,
_("EVP_DigestUpdate failed"));
return -1;
}
cur += PAGE_SIZE;
nep++;
} while (cur < addr + size);
return nep;
}
int64_t pv_component_update_pld(const PvComponent *comp, EVP_MD_CTX *ctx,
GError **err)
{
uint64_t size = pv_component_size(comp);
int64_t nep = 0;
g_assert(IS_PAGE_ALIGNED(size) && size != 0);
switch (comp->d_type) {
case DATA_BUFFER: {
const Buffer *buf = comp->buf;
g_assert(buf->size <= INT64_MAX);
g_assert(buf->size == size);
if (EVP_DigestUpdate(ctx, buf->data, buf->size) != 1) {
g_set_error(err, PV_CRYPTO_ERROR,
PV_CRYPTO_ERROR_INTERNAL,
_("EVP_DigestUpdate failed"));
return -1;
}
nep = (int64_t)(buf->size / PAGE_SIZE);
break;
}
case DATA_FILE: {
const gchar *in_path = comp->file->path;
guchar in_buf[PAGE_SIZE];
gsize num_bytes_read_total = 0;
gsize num_bytes_read = 0;
FILE *f_in;
f_in = file_open(in_path, "rb", err);
if (!f_in)
return -1;
do {
/* Read data in blocks. Update the digest
* context each read.
*/
if (file_read(f_in, in_buf, sizeof(*in_buf),
sizeof(in_buf), &num_bytes_read,
err) < 0) {
fclose(f_in);
return -1;
}
num_bytes_read_total += num_bytes_read;
if (EVP_DigestUpdate(ctx, in_buf, sizeof(in_buf)) != 1) {
g_set_error(err, PV_CRYPTO_ERROR,
PV_CRYPTO_ERROR_INTERNAL,
_("EVP_DigestUpdate failed"));
fclose(f_in);
return -1;
}
nep++;
} while (num_bytes_read_total < pv_component_size(comp) &&
num_bytes_read != 0);
if (num_bytes_read_total != pv_component_size(comp)) {
g_set_error(err, G_FILE_ERROR, PV_ERROR_INTERNAL,
_("'%s' has changed during the preparation"),
in_path);
fclose(f_in);
return -1;
}
fclose(f_in);
break;
}
default:
g_assert_not_reached();
}
return nep;
}
int64_t pv_component_update_tld(const PvComponent *comp, EVP_MD_CTX *ctx,
GError **err)
{
uint64_t size = pv_component_size(comp);
const union tweak *tweak = &comp->tweak;
g_autoptr(BIGNUM) tweak_num = NULL;
int64_t nep = 0;
g_assert(IS_PAGE_ALIGNED(size) && size != 0);
tweak_num = BN_bin2bn(tweak->data, sizeof(tweak->data), NULL);
if (!tweak_num) {
g_set_error(err, PV_CRYPTO_ERROR,
PV_CRYPTO_ERROR_INTERNAL,
_("BN_bin2bn failed"));
}
for (uint64_t cur = 0; cur < size; cur += PAGE_SIZE) {
guchar tmp[sizeof(tweak->data)] = { 0 };
g_assert(BN_num_bytes(tweak_num) >= 0);
g_assert(sizeof(tmp) - (guint)BN_num_bytes(tweak_num) > 0);
if (BN_bn2binpad(tweak_num, tmp, sizeof(tmp)) < 0) {
g_set_error(err, PV_CRYPTO_ERROR,
PV_CRYPTO_ERROR_INTERNAL,
_("BN_bn2binpad failed"));
}
if (EVP_DigestUpdate(ctx, tmp, sizeof(tmp)) != 1) {
g_set_error(err, PV_CRYPTO_ERROR,
PV_CRYPTO_ERROR_INTERNAL,
_("EVP_DigestUpdate failed"));
return -1;
}
/* calculate new tweak value */
if (BN_add_word(tweak_num, PAGE_SIZE) != 1) {
g_set_error(err, PV_CRYPTO_ERROR,
PV_CRYPTO_ERROR_INTERNAL,
_("BN_add_word failed"));
}
nep++;
}
return nep;
}
gint pv_component_write(const PvComponent *component, FILE *f, GError **err)
{
uint64_t offset = pv_component_get_src_addr(component);
g_assert(f);
switch (component->d_type) {
case DATA_BUFFER: {
const Buffer *buf = component->buf;
if (seek_and_write_buffer(f, buf, offset, err) < 0)
return -1;
return 0;
}
case DATA_FILE: {
const CompFile *file = component->file;
if (seek_and_write_file(f, file, offset, err) < 0)
return -1;
return 0;
}
}
g_assert_not_reached();
}

View File

@@ -0,0 +1,78 @@
/*
* PV component related definitions and functions
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#ifndef PV_COMP_H
#define PV_COMP_H
#include <glib.h>
#include <openssl/evp.h>
#include <stdint.h>
#include "utils/crypto.h"
/* The order of this enum also implicitly defines the order of the
* components within the PV image!
*/
typedef enum {
PV_COMP_TYPE_KERNEL = 0,
PV_COMP_TYPE_CMDLINE = 1,
PV_COMP_TYPE_INITRD = 2,
PV_COMP_TYPE_STAGE3B = 3,
} PvComponentType;
typedef enum {
DATA_FILE = 0,
DATA_BUFFER,
} PvComponentDataType;
typedef struct comp_file {
gchar *path;
gsize size;
} CompFile;
typedef struct {
gint type; /* PvComponentType */
gint d_type; /* PvComponentDataType */
union {
struct comp_file *file;
Buffer *buf;
void *data;
};
uint64_t src_addr;
uint64_t orig_size;
union tweak tweak; /* used for the AES XTS encryption */
} PvComponent;
PvComponent *pv_component_new_file(PvComponentType type, const gchar *path,
GError **err);
PvComponent *pv_component_new_buf(PvComponentType type, const Buffer *buf,
GError **err);
void pv_component_free(PvComponent *component);
gint pv_component_type(const PvComponent *component);
const gchar *pv_component_name(const PvComponent *component);
uint64_t pv_component_size(const PvComponent *component);
uint64_t pv_component_get_src_addr(const PvComponent *component);
uint64_t pv_component_get_orig_size(const PvComponent *component);
uint64_t pv_component_get_tweak_prefix(const PvComponent *component);
gboolean pv_component_is_stage3b(const PvComponent *component);
gint pv_component_align_and_encrypt(PvComponent *component, const gchar *tmp_path,
void *opaque, GError **err);
gint pv_component_align(PvComponent *component, const gchar *tmp_path,
void *opaque G_GNUC_UNUSED, GError **err);
int64_t pv_component_update_pld(const PvComponent *comp, EVP_MD_CTX *ctx,
GError **err);
int64_t pv_component_update_ald(const PvComponent *comp, EVP_MD_CTX *ctx,
GError **err);
int64_t pv_component_update_tld(const PvComponent *comp, EVP_MD_CTX *ctx,
GError **err);
gint pv_component_write(const PvComponent *component, FILE *f, GError **err);
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(PvComponent, pv_component_free)
#endif

View File

@@ -0,0 +1,252 @@
/*
* PV components related definitions and functions
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include <glib.h>
#include <glib/gtypes.h>
#include <openssl/evp.h>
#include <stdint.h>
#include "boot/s390.h"
#include "boot/stage3b.h"
#include "common.h"
#include "utils/align.h"
#include "utils/crypto.h"
#include "pv_comp.h"
#include "pv_comps.h"
#include "pv_error.h"
#include "pv_stage3.h"
struct _pv_img_comps {
gboolean finalized;
uint64_t next_src;
uint64_t nep;
EVP_MD_CTX *ald; /* context used for the hash of the addresses */
EVP_MD_CTX *pld; /* context used for the hash of the pages content */
EVP_MD_CTX *tld; /* context used for the hash of the tweaks */
GSList *comps; /* elements sorted by component type */
};
void pv_img_comps_free(PvImgComps *comps)
{
if (!comps)
return;
EVP_MD_CTX_free(comps->ald);
EVP_MD_CTX_free(comps->pld);
EVP_MD_CTX_free(comps->tld);
g_slist_free_full(comps->comps, (GDestroyNotify)pv_component_free);
g_free(comps);
}
PvImgComps *pv_img_comps_new(const EVP_MD *ald_md, const EVP_MD *pld_md,
const EVP_MD *tld_md, GError **err)
{
g_autoptr(PvImgComps) ret = g_new0(PvImgComps, 1);
ret->ald = digest_ctx_new(ald_md, err);
if (!ret->ald)
return NULL;
ret->pld = digest_ctx_new(pld_md, err);
if (!ret->pld)
return NULL;
ret->tld = digest_ctx_new(tld_md, err);
if (!ret->tld)
return NULL;
return g_steal_pointer(&ret);
}
guint pv_img_comps_length(const PvImgComps *comps)
{
return g_slist_length(comps->comps);
}
/* Update hashes and nep */
/* Returns 0 in case of success and -1 in case of a failure */
static gint pv_img_comps_hash_comp(PvImgComps *comps, const PvComponent *comp,
GError **err)
{
int64_t nep_1 = 0;
int64_t nep_2 = 0;
int64_t nep_3 = 0;
/* update pld */
nep_1 = pv_component_update_pld(comp, comps->pld, err);
if (nep_1 < 0)
return -1;
/* update ald */
nep_2 = pv_component_update_ald(comp, comps->ald, err);
if (nep_2 < 0)
return -1;
/* update tld */
nep_3 = pv_component_update_tld(comp, comps->tld, err);
if (nep_3 < 0)
return -1;
g_assert(nep_1 == nep_2);
g_assert(nep_2 == nep_3);
/* update comps->nep */
g_assert_true(g_uint64_checked_add(&comps->nep, comps->nep,
(uint64_t)nep_1));
return 0;
}
gint pv_img_comps_add_component(PvImgComps *comps, PvComponent **comp,
GError **err)
{
g_assert(comp);
g_assert(*comp);
g_assert(comps);
g_assert(IS_PAGE_ALIGNED(comps->next_src));
uint64_t src_addr = comps->next_src;
uint64_t src_size = pv_component_size(*comp)
? PAGE_ALIGN(pv_component_size(*comp))
: PAGE_SIZE;
if (comps->finalized) {
g_set_error(err, PV_COMPONENT_ERROR, PV_COMPONENT_ERROR_FINALIZED,
_("Failed to add component, image is already finalized"));
return -1;
}
/* set the address of the component in the memory layout */
(*comp)->src_addr = src_addr;
g_info("%12s:\t0x%012lx (%12ld / %12ld Bytes)",
pv_component_name(*comp), pv_component_get_src_addr(*comp),
pv_component_size(*comp), pv_component_get_orig_size(*comp));
/* append the component and pass the responsibility of @comp
* to @comps
*/
comps->comps = g_slist_append(comps->comps, g_steal_pointer(comp));
comps->next_src += src_size;
g_assert(IS_PAGE_ALIGNED(comps->next_src));
g_assert(!*comp);
return 0;
}
struct stage3b_args *pv_img_comps_get_stage3b_args(const PvImgComps *comps,
struct psw_t *psw)
{
g_autofree struct stage3b_args *ret = g_new0(struct stage3b_args, 1);
for (GSList *iterator = comps->comps; iterator; iterator = iterator->next) {
const PvComponent *img_comp = iterator->data;
uint64_t src_addr, dst_size;
g_assert(img_comp);
src_addr = pv_component_get_src_addr(img_comp);
dst_size = pv_component_get_orig_size(img_comp);
g_assert(dst_size <= pv_component_size(img_comp));
switch ((PvComponentType)pv_component_type(img_comp)) {
case PV_COMP_TYPE_KERNEL:
memblob_init(&ret->kernel, src_addr, dst_size);
break;
case PV_COMP_TYPE_CMDLINE:
memblob_init(&ret->cmdline, src_addr, dst_size);
break;
case PV_COMP_TYPE_INITRD:
memblob_init(&ret->initrd, src_addr, dst_size);
break;
case PV_COMP_TYPE_STAGE3B:
/* nothing needs to be done since it is the
* stage3b itself
*/
break;
default:
g_assert_not_reached();
break;
}
}
/* for `stage3b_args` big-endian format must be used */
ret->psw.mask = GUINT64_TO_BE(psw->mask);
ret->psw.addr = GUINT64_TO_BE(psw->addr);
return g_steal_pointer(&ret);
}
gint pv_img_comps_set_offset(PvImgComps *comps, gsize offset, GError **err)
{
g_assert(IS_PAGE_ALIGNED(comps->next_src));
if (!IS_PAGE_ALIGNED(offset)) {
g_set_error(err, PV_IMAGE_ERROR, PV_IMAGE_ERROR_OFFSET,
_("Offset must be page aligned"));
return -1;
}
if (pv_img_comps_length(comps) > 0) {
g_set_error(err, PV_IMAGE_ERROR, PV_IMAGE_ERROR_OFFSET,
_("Offset cannot be changed after a component was added"));
return -1;
}
comps->next_src += offset;
g_assert(IS_PAGE_ALIGNED(comps->next_src));
return 0;
}
GSList *pv_img_comps_get_comps(const PvImgComps *comps)
{
return comps->comps;
}
gint pv_img_comps_finalize(PvImgComps *comps, Buffer **pld_digest,
Buffer **ald_digest, Buffer **tld_digest,
uint64_t *nep, GError **err)
{
g_autoptr(Buffer) tmp_pld_digest = NULL;
g_autoptr(Buffer) tmp_ald_digest = NULL;
g_autoptr(Buffer) tmp_tld_digest = NULL;
comps->finalized = TRUE;
for (GSList *iterator = comps->comps; iterator; iterator = iterator->next) {
const PvComponent *comp = iterator->data;
/* update hashes and nep */
if (pv_img_comps_hash_comp(comps, comp, err) < 0)
return -1;
}
tmp_pld_digest = digest_ctx_finalize(comps->pld, err);
if (!tmp_pld_digest)
return -1;
tmp_ald_digest = digest_ctx_finalize(comps->ald, err);
if (!tmp_ald_digest)
return -1;
tmp_tld_digest = digest_ctx_finalize(comps->tld, err);
if (!tmp_tld_digest)
return -1;
*pld_digest = g_steal_pointer(&tmp_pld_digest);
*ald_digest = g_steal_pointer(&tmp_ald_digest);
*tld_digest = g_steal_pointer(&tmp_tld_digest);
*nep = comps->nep;
return 0;
}
PvComponent *pv_img_comps_get_nth_comp(PvImgComps *comps, guint n)
{
return g_slist_nth_data(comps->comps, n);
}

View File

@@ -0,0 +1,42 @@
/*
* PV components related definitions and functions
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#ifndef PV_COMPS_H
#define PV_COMPS_H
#include <glib.h>
#include <openssl/evp.h>
#include <stdint.h>
#include "boot/s390.h"
#include "boot/stage3b.h"
#include "utils/buffer.h"
#include "pv_comp.h"
typedef struct _pv_img_comps PvImgComps;
PvImgComps *pv_img_comps_new(const EVP_MD *ald_md, const EVP_MD *pld_md,
const EVP_MD *tld_md, GError **err);
guint pv_img_comps_length(const PvImgComps *comps);
GSList *pv_img_comps_get_comps(const PvImgComps *comps);
struct stage3b_args *pv_img_comps_get_stage3b_args(const PvImgComps *comps,
struct psw_t *psw);
gint pv_img_comps_add_component(PvImgComps *comps, PvComponent **comp,
GError **err);
PvComponent *pv_img_comps_get_nth_comp(PvImgComps *comps, guint n);
gint pv_img_comps_set_offset(PvImgComps *comps, gsize offset, GError **err);
gint pv_img_comps_finalize(PvImgComps *comps, Buffer **pld_digest,
Buffer **ald_digest, Buffer **tld_digest,
uint64_t *nep, GError **err);
void pv_img_comps_free(PvImgComps *comps);
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(PvImgComps, pv_img_comps_free)
#endif

View File

@@ -0,0 +1,37 @@
/*
* PV error related functions
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include <glib.h>
#include "pv_error.h"
GQuark pv_error_quark(void)
{
return g_quark_from_static_string("pv-error-quark");
}
GQuark pv_crypto_error_quark(void)
{
return g_quark_from_static_string("pv-crypto-error-quark");
}
GQuark pv_component_error_quark(void)
{
return g_quark_from_static_string("pv-component-error-quark");
}
GQuark pv_image_error_quark(void)
{
return g_quark_from_static_string("pv-image-error-quark");
}
GQuark pv_parse_error_quark(void)
{
return g_quark_from_static_string("pv-parse-error-quark");
}

View File

@@ -0,0 +1,62 @@
/*
* PV error related definitions and functions
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#ifndef PV_ERROR_H
#define PV_ERROR_H
#include <glib.h>
GQuark pv_error_quark(void);
GQuark pv_parse_error_quark(void);
GQuark pv_component_error_quark(void);
GQuark pv_crypto_error_quark(void);
GQuark pv_image_error_quark(void);
#define PV_ERROR pv_error_quark()
#define PV_PARSE_ERROR pv_parse_error_quark()
#define PV_CRYPTO_ERROR pv_crypto_error_quark()
#define PV_COMPONENT_ERROR pv_component_error_quark()
#define PV_IMAGE_ERROR pv_image_error_quark()
typedef enum {
PV_ERROR_IPIB_SIZE,
PV_ERROR_PV_HDR_SIZE,
PV_ERROR_INTERNAL,
} PvErrors;
typedef enum {
PV_PARSE_ERROR_OK = 0,
PV_PARSE_ERROR_SYNTAX,
PR_PARSE_ERROR_INVALID_ARGUMENT,
PR_PARSE_ERROR_MISSING_ARGUMENT,
} PvParseErrors;
typedef enum {
PV_COMPONENT_ERROR_UNALIGNED,
PV_COMPONENT_ERROR_FINALIZED,
} PvComponentErrors;
typedef enum {
PV_IMAGE_ERROR_OFFSET,
PV_IMAGE_ERROR_FINALIZED,
} PvImageErrors;
typedef enum {
PV_CRYPTO_ERROR_VERIFICATION,
PV_CRYPTO_ERROR_INIT,
PV_CRYPTO_ERROR_READ_CERTIFICATE,
PV_CRYPTO_ERROR_INTERNAL,
PV_CRYPTO_ERROR_DERIVE,
PV_CRYPTO_ERROR_KEYGENERATION,
PV_CRYPTO_ERROR_RANDOMIZATION,
PV_CRYPTO_ERROR_INVALID_PARM,
PV_CRYPTO_ERROR_INVALID_KEY_SIZE,
} PvCryptoErrors;
#endif

293
genprotimg/src/pv/pv_hdr.c Normal file
View File

@@ -0,0 +1,293 @@
/*
* PV header related functions
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include <glib.h>
#include <glib/gtypes.h>
#include <openssl/aes.h>
#include <openssl/evp.h>
#include <stdint.h>
#include <string.h>
#include "boot/s390.h"
#include "include/pv_crypto_def.h"
#include "utils/buffer.h"
#include "utils/crypto.h"
#include "pv_comp.h"
#include "pv_hdr.h"
#include "pv_image.h"
void pv_hdr_free(PvHdr *hdr)
{
if (!hdr)
return;
g_free(hdr->optional_items);
g_free(hdr->encrypted);
g_free(hdr->slots);
g_free(hdr);
}
uint32_t pv_hdr_size(const PvHdr *hdr)
{
return GUINT32_FROM_BE(hdr->head.phs);
}
gboolean pv_hdr_uses_encryption(const PvHdr *hdr)
{
return !(GUINT64_FROM_BE(hdr->head.pcf) & PV_CFLAG_NO_DECRYPTION);
}
uint64_t pv_hdr_enc_size(const PvHdr *hdr)
{
return GUINT64_FROM_BE(hdr->head.sea);
}
uint32_t pv_hdr_enc_size_casted(const PvHdr *hdr)
{
uint64_t size = pv_hdr_enc_size(hdr);
if (size > UINT32_MAX)
g_abort();
return (uint32_t)size;
}
static guint pv_hdr_tag_size(const PvHdr *hdr)
{
return sizeof(hdr->tag);
}
uint32_t pv_hdr_aad_size(const PvHdr *hdr)
{
return pv_hdr_size(hdr) - pv_hdr_enc_size_casted(hdr) -
pv_hdr_tag_size(hdr);
}
uint64_t pv_hdr_get_nks(const PvHdr *hdr)
{
return GUINT64_FROM_BE(hdr->head.nks);
}
/* In-place modification of ``buf`` */
static gint pv_hdr_encrypt(const PvHdr *hdr, const PvImage *img, Buffer *buf,
GError **err)
{
uint32_t hdr_len = pv_hdr_size(hdr);
uint32_t aad_len = pv_hdr_aad_size(hdr);
guint tag_len = pv_hdr_tag_size(hdr);
uint32_t enc_len = pv_hdr_enc_size_casted(hdr);
const Buffer aad_part = { .data = buf->data, .size = aad_len };
Buffer enc_part = { .data = (uint8_t *)buf->data + aad_len,
.size = enc_len };
Buffer tag_part = { .data = (uint8_t *)buf->data + hdr_len - tag_len,
.size = tag_len };
struct cipher_parms parms;
int64_t c_len;
g_assert(aad_part.size + enc_part.size + tag_part.size == buf->size);
g_assert(img->cust_root_key->size <= INT_MAX);
g_assert(img->gcm_iv->size <= INT_MAX);
g_assert(EVP_CIPHER_key_length(img->gcm_cipher) ==
(int)img->cust_root_key->size);
g_assert(EVP_CIPHER_iv_length(img->gcm_cipher) == (int)img->gcm_iv->size);
parms.key = img->cust_root_key;
parms.iv_or_tweak = img->gcm_iv;
parms.cipher = img->gcm_cipher;
/* in-place encryption */
c_len = gcm_encrypt(&enc_part, &aad_part, &parms, &enc_part, &tag_part, err);
if (c_len < 0)
return -1;
g_assert(c_len == enc_len);
return 0;
}
/* Initializes the unencrypted, but integrity protected part of the PV
* header
*/
static gint pv_hdr_aad_init(PvHdr *hdr, const PvImage *img, GError **err)
{
g_autofree union ecdh_pub_key *cust_pub_key = NULL;
struct pv_hdr_key_slot *hdr_slot = hdr->slots;
struct pv_hdr_head *head = &hdr->head;
g_autoptr(Buffer) pld = NULL;
g_autoptr(Buffer) ald = NULL;
g_autoptr(Buffer) tld = NULL;
uint64_t nep = 0;
g_assert(sizeof(head->iv) == img->gcm_iv->size);
g_assert(sizeof(head->cust_pub_key) == sizeof(*cust_pub_key));
cust_pub_key = evp_pkey_to_ecdh_pub_key(img->cust_pub_priv_key, err);
if (!cust_pub_key)
return -1;
head->magic = GUINT64_TO_BE(PV_MAGIC_NUMBER);
head->version = GUINT32_TO_BE(PV_VERSION_1);
/* ``phs`` is already set so we can skip it here */
memcpy(head->iv, img->gcm_iv->data, sizeof(head->iv));
/* ``nks`` is already set so we can skip it here */
/* ``sea`` is already set so we can skip it here */
head->pcf = GUINT64_TO_BE(img->pcf);
memcpy(head->cust_pub_key.data, cust_pub_key,
sizeof(head->cust_pub_key));
if (pv_img_calc_pld_ald_tld_nep(img, &pld, &ald, &tld, &nep, err) < 0)
return -1;
g_assert(sizeof(head->pld) == pld->size);
g_assert(sizeof(head->ald) == ald->size);
g_assert(sizeof(head->tld) == tld->size);
head->nep = GUINT64_TO_BE(nep);
memcpy(head->pld, pld->data, sizeof(head->pld));
memcpy(head->ald, ald->data, sizeof(head->ald));
memcpy(head->tld, tld->data, sizeof(head->tld));
/* set the key slots */
for (GSList *iterator = img->key_slots; iterator; iterator = iterator->next) {
const PvHdrKeySlot *slot = iterator->data;
g_assert(slot);
/* the memory for the slots is pre-allocated so we
* have not to allocate and since PvHdrKeySlot is
* stored in the big-edian format we can simply use
* memcpy.
*/
memcpy(hdr_slot++, slot, sizeof(*slot));
}
return 0;
}
/* Initializes the encrypted and also integrity protected part of the
* PV header
*/
static gint pv_hdr_enc_init(PvHdr *hdr, const PvImage *img, GError **err)
{
struct pv_hdr_encrypted *enc = hdr->encrypted;
const PvComponent *stage3b;
struct psw_t psw;
g_assert(sizeof(enc->img_enc_key_1) + sizeof(enc->img_enc_key_2) ==
EVP_CIPHER_key_length(img->xts_cipher));
g_assert(sizeof(enc->cust_comm_key) == img->cust_comm_key->size);
g_assert(img->xts_key->size ==
(guint)EVP_CIPHER_key_length(img->xts_cipher));
stage3b = pv_img_get_stage3b_comp(img, err);
if (!stage3b)
return -1;
memcpy(enc->cust_comm_key, img->cust_comm_key->data,
sizeof(enc->cust_comm_key));
memcpy(enc->img_enc_key_1, img->xts_key->data,
sizeof(enc->img_enc_key_1));
memcpy(enc->img_enc_key_2,
(uint8_t *)img->xts_key->data + sizeof(enc->img_enc_key_1),
sizeof(enc->img_enc_key_2));
/* Setup program check handler */
psw.mask = GUINT64_TO_BE(DEFAULT_INITIAL_PSW_MASK);
psw.addr = GUINT64_TO_BE(pv_component_get_src_addr(stage3b));
enc->psw = psw;
enc->scf = GUINT64_TO_BE(img->scf);
enc->noi = GUINT32_TO_BE(g_slist_length(img->optional_items));
/* set the optional items */
for (GSList *iterator = img->optional_items; iterator;
iterator = iterator->next) {
const struct pv_hdr_opt_item *item = iterator->data;
g_assert(item);
/* not supported in the first version */
g_assert_not_reached();
}
return 0;
}
PvHdr *pv_hdr_new(const PvImage *img, GError **err)
{
uint32_t noi = g_slist_length(img->optional_items);
uint32_t hdr_size = pv_img_get_pv_hdr_size(img);
gsize nks = g_slist_length(img->key_slots);
uint32_t sea = pv_img_get_enc_size(img);
g_autoptr(PvHdr) ret = NULL;
g_assert(nks > 0);
/* must be a multiple of AES block size */
g_assert(sea % AES_BLOCK_SIZE == 0);
g_assert(sea >= sizeof(struct pv_hdr_encrypted));
ret = g_new0(PvHdr, 1);
ret->slots = g_new0(struct pv_hdr_key_slot, nks);
ret->head.phs = GUINT32_TO_BE(hdr_size);
ret->head.nks = GUINT64_TO_BE(nks);
ret->head.sea = GUINT64_TO_BE(sea);
ret->encrypted = g_new0(struct pv_hdr_encrypted, 1);
ret->optional_items = g_malloc0(sea - sizeof(struct pv_hdr_encrypted));
ret->encrypted->noi = GUINT32_TO_BE(noi);
if (pv_hdr_aad_init(ret, img, err) < 0)
return NULL;
if (pv_hdr_enc_init(ret, img, err) < 0)
return NULL;
return g_steal_pointer(&ret);
}
static void pv_hdr_memcpy(const PvHdr *hdr, const Buffer *dst)
{
uint64_t nks = pv_hdr_get_nks(hdr);
uint8_t *data;
g_assert(dst->size == pv_hdr_size(hdr));
g_assert(pv_hdr_enc_size_casted(hdr) >= sizeof(*hdr->encrypted));
data = memcpy(dst->data, &hdr->head, sizeof(hdr->head));
data = memcpy(data + sizeof(hdr->head), hdr->slots,
sizeof(struct pv_hdr_key_slot) * nks);
data = memcpy(data + sizeof(struct pv_hdr_key_slot) * nks,
hdr->encrypted, sizeof(*hdr->encrypted));
if (pv_hdr_enc_size_casted(hdr) - sizeof(*hdr->encrypted) > 0) {
(void)memcpy(data + sizeof(*hdr->encrypted),
hdr->optional_items,
pv_hdr_enc_size_casted(hdr) - sizeof(*hdr->encrypted));
}
}
Buffer *pv_hdr_serialize(const PvHdr *hdr, const PvImage *img,
enum PvCryptoMode mode, GError **err)
{
uint32_t hdr_size = pv_hdr_size(hdr);
g_autoptr(Buffer) ret = NULL;
ret = buffer_alloc(hdr_size);
pv_hdr_memcpy(hdr, ret);
if (mode == PV_ENCRYPT) {
/* The buffer @ret is modified in-place */
if (pv_hdr_encrypt(hdr, img, ret, err) < 0)
return NULL;
} else {
/* Simply copy the tag */
memcpy((uint8_t *)ret->data + hdr_size - pv_hdr_tag_size(hdr),
hdr->tag, pv_hdr_tag_size(hdr));
}
return g_steal_pointer(&ret);
}

View File

@@ -0,0 +1,36 @@
/*
* PV header related functions
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#ifndef PV_HDR_H
#define PV_HDR_H
#include <glib.h>
#include <stdint.h>
#include "boot/s390.h"
#include "include/pv_hdr_def.h"
#include "utils/crypto.h"
#include "utils/buffer.h"
#include "pv_image.h"
PvHdr *pv_hdr_new(const PvImage *img, GError **err);
void pv_hdr_free(PvHdr *hdr);
G_GNUC_UNUSED gboolean pv_hdr_uses_encryption(const PvHdr *hdr);
Buffer *pv_hdr_serialize(const PvHdr *hdr, const PvImage *img,
enum PvCryptoMode mode, GError **err);
uint32_t pv_hdr_size(const PvHdr *hdr);
uint32_t pv_hdr_aad_size(const PvHdr *hdr);
uint64_t pv_hdr_enc_size(const PvHdr *hdr);
uint32_t pv_hdr_enc_size_casted(const PvHdr *hdr);
uint64_t pv_hdr_get_nks(const PvHdr *hdr);
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(PvHdr, pv_hdr_free)
#endif

View File

@@ -0,0 +1,821 @@
/*
* PV image related definitions and functions
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include <errno.h>
#include <glib.h>
#include <openssl/evp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "boot/s390.h"
#include "boot/stage3a.h"
#include "common.h"
#include "include/pv_crypto_def.h"
#include "include/pv_hdr_def.h"
#include "utils/align.h"
#include "utils/crypto.h"
#include "utils/file_utils.h"
#include "pv_args.h"
#include "pv_comps.h"
#include "pv_error.h"
#include "pv_hdr.h"
#include "pv_image.h"
#include "pv_ipib.h"
#include "pv_opt_item.h"
#include "pv_stage3.h"
const PvComponent *pv_img_get_stage3b_comp(const PvImage *img, GError **err)
{
const PvComponent *comp;
g_return_val_if_fail(pv_img_comps_length(img->comps) >= 1, NULL);
comp = pv_img_comps_get_nth_comp(img->comps,
pv_img_comps_length(img->comps) - 1);
if (!pv_component_is_stage3b(comp)) {
g_set_error(err, PV_ERROR, PV_ERROR_INTERNAL,
_("Failed to get 'stage3b' component"));
return NULL;
}
return comp;
}
typedef gint (*prepare_func)(PvComponent *obj, const gchar *tmp_path,
void *opaque, GError **err);
static gint pv_img_prepare_component(const PvImage *img, PvComponent *comp,
GError **err)
{
struct cipher_parms parms = { 0 };
g_autoptr(Buffer) tweak = NULL;
prepare_func func = NULL;
void *opaque = NULL;
gint rc;
if (img->pcf & PV_CFLAG_NO_DECRYPTION) {
/* we only need to align the components */
func = pv_component_align;
opaque = NULL;
} else {
const EVP_CIPHER *cipher = img->xts_cipher;
g_assert_cmpint((int)img->xts_key->size, ==,
EVP_CIPHER_key_length(cipher));
g_assert_cmpint((int)PAGE_SIZE % EVP_CIPHER_block_size(cipher),
==, 0);
g_assert_cmpint(sizeof(comp->tweak), ==,
EVP_CIPHER_iv_length(cipher));
g_assert(img->xts_key->size <= UINT_MAX);
tweak = buffer_alloc(sizeof(comp->tweak.data));
memcpy(tweak->data, comp->tweak.data, tweak->size);
func = pv_component_align_and_encrypt;
parms.cipher = cipher;
parms.key = img->xts_key;
parms.iv_or_tweak = tweak;
opaque = &parms;
}
rc = (*func)(comp, img->tmp_dir, opaque, err);
if (rc < 0)
return -1;
return 0;
}
static Buffer *pv_img_read_key(const gchar *path, guint key_size,
GError **err)
{
g_autoptr(Buffer) tmp_ret = NULL;
Buffer *ret = NULL;
gsize bytes_read;
FILE *f = NULL;
gsize size;
if (file_size(path, &size, err) != 0)
return NULL;
if (size - key_size != 0) {
g_set_error(err, PV_ERROR, PV_CRYPTO_ERROR_INVALID_KEY_SIZE,
_("Wrong file size '%s': read %zd, expected %u"), path, size,
key_size);
return NULL;
}
f = file_open(path, "rb", err);
if (!f)
return NULL;
tmp_ret = buffer_alloc(size);
if (file_read(f, tmp_ret->data, 1, tmp_ret->size, &bytes_read, err) < 0)
goto err;
if (bytes_read - key_size != 0) {
g_set_error(err, PV_ERROR, PV_CRYPTO_ERROR_INVALID_KEY_SIZE,
_("Wrong file size '%s': read %zd, expected %u"),
path, bytes_read, key_size);
goto err;
}
ret = g_steal_pointer(&tmp_ret);
err:
if (f)
fclose(f);
return ret;
}
static EVP_PKEY *pv_img_get_cust_pub_priv_key(gint nid, GError **err)
{
return generate_ec_key(nid, err);
}
static HostKeyList *pv_img_get_host_keys(gchar **host_cert_paths,
X509_STORE *store, gint nid,
GError **err)
{
g_autoslist(EVP_PKEY) ret = NULL;
g_assert(host_cert_paths);
for (gchar **iterator = host_cert_paths; iterator != NULL && *iterator != NULL;
iterator++) {
g_autoptr(EVP_PKEY) host_key = NULL;
const gchar *path = *iterator;
g_assert(path);
host_key = read_ec_pubkey_cert(store, nid, path, err);
if (!host_key)
return NULL;
ret = g_slist_append(ret, g_steal_pointer(&host_key));
}
return g_steal_pointer(&ret);
}
static Buffer *pv_img_get_key(const EVP_CIPHER *cipher, const gchar *path,
GError **err)
{
gint key_len = EVP_CIPHER_key_length(cipher);
g_assert(key_len > 0);
if (path)
return pv_img_read_key(path, (guint)key_len, err);
return generate_aes_key((guint)key_len, err);
}
static Buffer *pv_img_get_iv(const EVP_CIPHER *cipher, const gchar *path,
GError **err)
{
gint iv_len = EVP_CIPHER_iv_length(cipher);
g_assert(iv_len > 0);
if (path)
return pv_img_read_key(path, (guint)iv_len, err);
return generate_aes_iv((guint)iv_len, err);
}
static int hex_str_toull(const gchar *nptr, uint64_t *dst,
GError **err)
{
uint64_t value;
gchar *end;
g_assert(dst);
if (!g_str_is_ascii(nptr)) {
g_set_error(err, PV_ERROR, EINVAL,
_("Invalid value: '%s'. A hexadecimal value is required, for example '0xcfe'"),
nptr);
return -1;
}
value = g_ascii_strtoull(nptr, &end, 16);
if ((value == G_MAXUINT64 && errno == ERANGE) ||
(end && *end != '\0')) {
g_set_error(err, PV_ERROR, EINVAL,
_("Invalid value: '%s'. A hexadecimal value is required, for example '0xcfe'"),
nptr);
return -1;
}
*dst = value;
return 0;
}
static gint pv_img_set_psw_addr(PvImage *img, const gchar *psw_addr_s,
GError **err)
{
if (psw_addr_s) {
uint64_t psw_addr;
if (hex_str_toull(psw_addr_s, &psw_addr, err) < 0)
return -1;
img->initial_psw.addr = psw_addr;
}
return 0;
}
static gint pv_img_set_control_flags(PvImage *img, const gchar *pcf_s,
const gchar *scf_s, GError **err)
{
uint64_t flags;
if (pcf_s) {
if (hex_str_toull(pcf_s, &flags, err) < 0)
return -1;
img->pcf = flags;
}
if (scf_s) {
if (hex_str_toull(scf_s, &flags, err) < 0)
return -1;
img->scf = flags;
}
return 0;
}
/* read in the keys or auto-generate them */
static gint pv_img_set_keys(PvImage *img, const PvArgs *args, GError **err)
{
g_autoptr(X509_STORE) store = NULL;
g_assert(img->xts_cipher);
g_assert(img->cust_comm_cipher);
g_assert(img->gcm_cipher);
g_assert(img->nid);
img->xts_key = pv_img_get_key(img->xts_cipher, args->xts_key_path, err);
if (!img->xts_key)
return -1;
img->cust_comm_key = pv_img_get_key(img->cust_comm_cipher,
args->cust_comm_key_path, err);
if (!img->cust_comm_key)
return -1;
img->cust_root_key =
pv_img_get_key(img->gcm_cipher, args->cust_root_key_path, err);
if (!img->cust_root_key)
return -1;
img->gcm_iv = pv_img_get_iv(img->gcm_cipher, args->gcm_iv_path, err);
if (!img->gcm_iv)
return -1;
img->cust_pub_priv_key = pv_img_get_cust_pub_priv_key(img->nid, err);
if (!img->cust_pub_priv_key)
return -1;
img->host_pub_keys =
pv_img_get_host_keys(args->host_keys, store, img->nid, err);
if (!img->host_pub_keys)
return -1;
return 0;
}
static void pv_img_add_host_slot(PvImage *img, PvHdrKeySlot *slot)
{
img->key_slots = g_slist_append(img->key_slots, slot);
}
static void pv_hdr_key_slot_free(PvHdrKeySlot *slot)
{
if (!slot)
return;
g_free(slot);
}
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(PvHdrKeySlot, pv_hdr_key_slot_free)
static PvHdrKeySlot *pv_hdr_key_slot_new(const EVP_CIPHER *gcm_cipher,
const Buffer *cust_root_key,
EVP_PKEY *cust_key, EVP_PKEY *host_key,
GError **err)
{
g_autoptr(PvHdrKeySlot) ret = g_new0(PvHdrKeySlot, 1);
g_autofree union ecdh_pub_key *pub = NULL;
g_autoptr(Buffer) exchange_key = NULL;
g_autoptr(Buffer) digest_key = NULL;
g_autoptr(Buffer) iv = NULL;
Buffer pub_buf;
/* No AAD data is used */
Buffer aad = { .data = NULL, .size = 0 };
/* Set the output buffers for the encrypted data and the
* generated GCM tag
*/
Buffer enc = { .data = ret->wrapped_key, .size = sizeof(ret->wrapped_key) };
Buffer tag = { .data = ret->tag, .size = sizeof(ret->tag) };
struct cipher_parms parms;
int64_t c_len = 0;
g_assert(EVP_CIPHER_iv_length(gcm_cipher) >= 0);
pub = evp_pkey_to_ecdh_pub_key(host_key, err);
if (!pub)
return NULL;
pub_buf.data = pub->data;
pub_buf.size = sizeof(*pub);
digest_key = sha256_buffer(&pub_buf, err);
if (!digest_key)
return NULL;
g_assert(digest_key->size == sizeof(ret->digest_key));
/* set `digest_key` field */
memcpy(ret->digest_key, digest_key->data, sizeof(ret->digest_key));
exchange_key = compute_exchange_key(cust_key, host_key, err);
if (!exchange_key)
return NULL;
/* initialize cipher parameters */
g_assert(exchange_key->size <= INT_MAX);
g_assert(exchange_key->size == (guint)EVP_CIPHER_key_length(gcm_cipher));
/* create zero IV */
iv = buffer_alloc((guint)EVP_CIPHER_iv_length(gcm_cipher));
parms.iv_or_tweak = iv;
parms.key = exchange_key;
parms.cipher = gcm_cipher;
/* Encrypt the customer root key that is used for the encryption
* of the PV header
*/
c_len = gcm_encrypt(cust_root_key, &aad, &parms, &enc, &tag, err);
if (c_len < 0)
return NULL;
g_assert(c_len == (int64_t)cust_root_key->size);
return g_steal_pointer(&ret);
}
static gint pv_img_set_host_slots(PvImage *img, GError **err)
{
for (GSList *iterator = img->host_pub_keys; iterator; iterator = iterator->next) {
EVP_PKEY *host_key = iterator->data;
g_assert(host_key);
PvHdrKeySlot *slot = pv_hdr_key_slot_new(img->gcm_cipher,
img->cust_root_key,
img->cust_pub_priv_key,
host_key, err);
if (!slot)
return -1;
pv_img_add_host_slot(img, slot);
}
return 0;
}
static gint pv_img_set_comps_offset(PvImage *img, uint64_t offset, GError **err)
{
return pv_img_comps_set_offset(img->comps, offset, err);
}
PvImage *pv_img_new(PvArgs *args, const gchar *stage3a_path, GError **err)
{
g_autoptr(PvImage) ret = g_new0(PvImage, 1);
uint64_t offset;
g_assert(args->tmp_dir);
g_assert(stage3a_path);
if (args->no_verify)
g_warning(_("host-key document verification is disabled. Your workload is not secured."));
ret->comps = pv_img_comps_new(EVP_sha512(), EVP_sha512(), EVP_sha512(), err);
if (!ret->comps)
return NULL;
ret->cust_comm_cipher = EVP_aes_256_gcm();
ret->gcm_cipher = EVP_aes_256_gcm();
ret->initial_psw.addr = DEFAULT_INITIAL_PSW_ADDR;
ret->initial_psw.mask = DEFAULT_INITIAL_PSW_MASK;
ret->nid = NID_secp521r1;
ret->tmp_dir = g_strdup(args->tmp_dir);
ret->xts_cipher = EVP_aes_256_xts();
/* set initial PSW that will be loaded by the stage3b */
if (pv_img_set_psw_addr(ret, args->psw_addr, err) < 0)
return NULL;
/* set the control flags: PCF and SCF */
if (pv_img_set_control_flags(ret, args->pcf, args->scf, err) < 0)
return NULL;
/* read in the keys */
if (pv_img_set_keys(ret, args, err) < 0)
return NULL;
if (pv_img_set_host_slots(ret, err) < 0)
return NULL;
/* allocate enough memory for the stage3a args and load the
* stage3a template into memory and set the loader_psw
*/
if (pv_img_load_and_set_stage3a(ret, stage3a_path, err) < 0)
return NULL;
offset = PAGE_ALIGN(STAGE3A_LOAD_ADDRESS + ret->stage3a->size);
/* shift right all components by the size of stage3a loader */
if (pv_img_set_comps_offset(ret, offset, err) < 0)
return NULL;
return g_steal_pointer(&ret);
}
void pv_img_free(PvImage *img)
{
if (!img)
return;
g_slist_free_full(img->optional_items,
(GDestroyNotify)pv_opt_item_free);
g_slist_free_full(img->key_slots, (GDestroyNotify)pv_hdr_key_slot_free);
g_slist_free_full(img->host_pub_keys, (GDestroyNotify)EVP_PKEY_free);
EVP_PKEY_free(img->cust_pub_priv_key);
buffer_clear(&img->stage3a);
pv_img_comps_free(img->comps);
g_free(img->tmp_dir);
buffer_free(img->xts_key);
buffer_free(img->cust_root_key);
buffer_free(img->gcm_iv);
buffer_free(img->cust_comm_key);
g_free(img);
}
static gint pv_img_prepare_and_add_component(PvImage *img, PvComponent **comp,
GError **err)
{
g_assert(comp);
g_assert(*comp);
/* prepares the component: does the alignment and encryption
* if required
*/
if (pv_img_prepare_component(img, *comp, err) < 0)
return -1;
/* calculates the memory layout and adds the component to its
* internal list
*/
if (pv_img_comps_add_component(img->comps, comp, err) < 0)
return -1;
g_assert(!*comp);
return 0;
}
gint pv_img_add_component(PvImage *img, const PvArg *arg, GError **err)
{
g_autoptr(PvComponent) comp = NULL;
comp = pv_component_new_file(arg->type, arg->path, err);
if (!comp)
return -1;
if (pv_img_prepare_and_add_component(img, &comp, err) < 0)
return -1;
g_assert(!comp);
return 0;
}
gint pv_img_calc_pld_ald_tld_nep(const PvImage *img, Buffer **pld, Buffer **ald,
Buffer **tld, uint64_t *nep, GError **err)
{
return pv_img_comps_finalize(img->comps, pld, ald, tld, nep, err);
}
static gint pv_img_build_stage3b(PvImage *img, Buffer *stage3b, GError **err)
{
g_autofree struct stage3b_args *args = NULL;
args = pv_img_comps_get_stage3b_args(img->comps, &img->initial_psw);
if (!args) {
g_set_error(err, PV_ERROR, PV_ERROR_INTERNAL,
_("Cannot generate stage3b arguments"));
return -1;
}
build_stage3b(stage3b, args);
return 0;
}
gint pv_img_add_stage3b_comp(PvImage *img, const gchar *path, GError **err)
{
g_autoptr(PvComponent) comp = NULL;
g_autoptr(Buffer) stage3b = NULL;
stage3b = stage3b_getblob(path, err);
if (!stage3b)
return -1;
/* set the stage3b data */
if (pv_img_build_stage3b(img, stage3b, err) < 0)
return -1;
comp = pv_component_new_buf(PV_COMP_TYPE_STAGE3B, stage3b, err);
if (!comp)
return -1;
if (pv_img_prepare_and_add_component(img, &comp, err) < 0)
return -1;
g_assert(!comp);
return 0;
}
static uint32_t pv_img_get_aad_size(const PvImage *img)
{
uint32_t key_size, size = 0;
g_assert(sizeof(struct pv_hdr_head) <= UINT32_MAX);
g_assert(sizeof(struct pv_hdr_key_slot) <= UINT32_MAX);
g_assert_true(g_uint_checked_add(&size, size,
(uint32_t)sizeof(struct pv_hdr_head)));
g_assert_true(g_uint_checked_mul(&key_size,
(uint32_t)sizeof(struct pv_hdr_key_slot),
g_slist_length(img->key_slots)));
g_assert_true(g_uint_checked_add(&size, size, key_size));
return size;
}
static uint32_t pv_img_get_opt_items_size(const PvImage *img)
{
uint32_t ret = 0;
g_assert(img);
for (GSList *iterator = img->optional_items; iterator;
iterator = iterator->next) {
const struct pv_hdr_opt_item *item = iterator->data;
g_assert(item);
g_assert_true(g_uint_checked_add(&ret, ret, pv_opt_item_size(item)));
}
return ret;
}
uint32_t pv_img_get_enc_size(const PvImage *img)
{
uint32_t ret = 0;
g_assert(sizeof(struct pv_hdr_encrypted) <= UINT32_MAX);
g_assert_true(g_uint_checked_add(
&ret, ret, (uint32_t)sizeof(struct pv_hdr_encrypted)));
g_assert_true(
g_uint_checked_add(&ret, ret, pv_img_get_opt_items_size(img)));
return ret;
}
static uint32_t pv_img_get_tag_size(const PvImage *img G_GNUC_UNUSED)
{
g_assert(sizeof(((struct pv_hdr *)0)->tag) <= UINT32_MAX);
return (uint32_t)sizeof(((struct pv_hdr *)0)->tag);
}
uint32_t pv_img_get_pv_hdr_size(const PvImage *img)
{
uint32_t size = 0;
g_assert_true(
g_uint_checked_add(&size, size, pv_img_get_aad_size(img)));
g_assert_true(
g_uint_checked_add(&size, size, pv_img_get_enc_size(img)));
g_assert_true(
g_uint_checked_add(&size, size, pv_img_get_tag_size(img)));
return size;
}
static gint get_stage3a_data_size(const PvImage *img, gsize *data_size,
GError **err)
{
gsize ipib_size, hdr_size;
g_assert(data_size);
g_assert(*data_size == 0);
ipib_size = pv_ipib_get_size(pv_img_comps_length(img->comps));
if (ipib_size > PV_V1_IPIB_MAX_SIZE) {
g_set_error(err, PV_ERROR, PV_ERROR_IPIB_SIZE,
_("IPIB size is too large: '%zu' > '%zu'"),
ipib_size, PV_V1_IPIB_MAX_SIZE);
return -1;
}
hdr_size = pv_img_get_pv_hdr_size(img);
if (hdr_size > PV_V1_PV_HDR_MAX_SIZE) {
g_set_error(err, PV_ERROR, PV_ERROR_PV_HDR_SIZE,
_("PV header size is too large: '%zu' > '%zu'"),
hdr_size, PV_V1_PV_HDR_MAX_SIZE);
return -1;
}
*data_size += PAGE_ALIGN(ipib_size);
*data_size += PAGE_ALIGN(hdr_size);
return 0;
}
gint pv_img_load_and_set_stage3a(PvImage *img, const gchar *path, GError **err)
{
g_autoptr(Buffer) stage3a = NULL;
gsize bin_size, data_size = 0;
if (get_stage3a_data_size(img, &data_size, err) < 0)
return -1;
stage3a = stage3a_getblob(path, &bin_size, data_size, err);
if (!stage3a)
return -1;
img->stage3a_psw.addr = STAGE3A_ENTRY;
img->stage3a_psw.mask = DEFAULT_INITIAL_PSW_MASK;
/* set addresses and size */
img->stage3a = g_steal_pointer(&stage3a);
img->stage3a_bin_size = bin_size;
return 0;
}
/* Creates the PV IPIB and sets the stage3a arguments */
static gint pv_img_build_stage3a(Buffer *stage3a, gsize stage3a_bin_size,
GSList *comps, const Buffer *hdr, GError **err)
{
g_autofree struct ipl_parameter_block *ipib = NULL;
g_assert(stage3a);
g_assert(hdr);
ipib = pv_ipib_new(comps, hdr, err);
if (!ipib)
return -1;
if (build_stage3a(stage3a, stage3a_bin_size, hdr, ipib, err) < 0)
return -1;
g_info("%12s:\t0x%012lx (%12ld / %12ld Bytes)", "stage3a",
STAGE3A_LOAD_ADDRESS, stage3a->size, stage3a->size);
return 0;
}
/* Creates the actual PV header (serialized and AES-GCM encrypted) */
static Buffer *pv_img_create_pv_hdr(PvImage *img, GError **err)
{
g_autoptr(Buffer) hdr_buf = NULL;
g_autoptr(PvHdr) hdr = NULL;
hdr = pv_hdr_new(img, err);
if (!hdr)
return NULL;
hdr_buf = pv_hdr_serialize(hdr, img, PV_ENCRYPT, err);
if (!hdr_buf)
return NULL;
return g_steal_pointer(&hdr_buf);
}
/* No changes to the components are allowed after calling this
* function
*/
gint pv_img_finalize(PvImage *pv, const gchar *stage3b_path, GError **err)
{
g_autoptr(Buffer) hdr = NULL;
/* load stage3b template into memory and add it to the list of
* components. This must be done before calling
* `pv_img_load_and_set_stage3a`.
*/
if (pv_img_add_stage3b_comp(pv, stage3b_path, err) < 0)
return -1;
/* create the PV header */
hdr = pv_img_create_pv_hdr(pv, err);
if (!hdr)
return -1;
/* generate stage3a. At this point in time the PV header and
* the stage3b must be generated and encrypted
*/
if (pv_img_build_stage3a(pv->stage3a, pv->stage3a_bin_size,
pv_img_comps_get_comps(pv->comps), hdr, err) < 0)
return -1;
return 0;
}
static gint convert_psw_to_short_psw(const struct psw_t *psw, uint64_t *dst,
GError **err)
{
g_assert(psw);
g_assert(dst);
uint64_t psw_addr = psw->addr;
uint64_t psw_mask = psw->mask;
/* test if PSW mask can be converted */
if (psw_mask & PSW32_ADDR_MASK) {
g_set_error(err, PV_ERROR, PV_ERROR_INTERNAL,
_("Failed to convert PSW to short PSW"));
return -1;
}
/* test for bit 12 */
if (psw_mask & PSW_MASK_BIT_12) {
g_set_error(err, PV_ERROR, PV_ERROR_INTERNAL,
_("Failed to convert PSW to short PSW"));
return -1;
}
/* test if PSW addr can be converted */
if (psw_addr & ~PSW32_ADDR_MASK) {
g_set_error(err, PV_ERROR, PV_ERROR_INTERNAL,
_("Failed to convert PSW to short PSW"));
return -1;
}
*dst = psw_mask;
/* set bit 12 to 1 */
*dst |= PSW_MASK_BIT_12;
*dst |= psw_addr;
return 0;
}
static gint write_short_psw(FILE *f, struct psw_t *psw, GError **err)
{
uint64_t short_psw, short_psw_be;
if (convert_psw_to_short_psw(psw, &short_psw, err) < 0)
return -1;
short_psw_be = GUINT64_TO_BE(short_psw);
return file_write(f, &short_psw_be, 1, sizeof(short_psw_be), NULL, err);
}
gint pv_img_write(PvImage *img, const gchar *path, GError **err)
{
gint ret = -1;
FILE *f = file_open(path, "wb", err);
if (!f)
return -1;
if (write_short_psw(f, &img->stage3a_psw, err) < 0) {
g_prefix_error(err, _("Failed to write image '%s': "), path);
goto err;
}
if (seek_and_write_buffer(f, img->stage3a, STAGE3A_LOAD_ADDRESS, err) <
0) {
g_prefix_error(err, _("Failed to write image '%s': "), path);
goto err;
}
/* list is sorted by component type => by address */
for (GSList *iterator = pv_img_comps_get_comps(img->comps); iterator;
iterator = iterator->next) {
gint rc;
const PvComponent *comp = iterator->data;
rc = pv_component_write(comp, f, err);
if (rc < 0) {
g_prefix_error(err, _("Failed to write image '%s': "),
path);
goto err;
}
}
ret = 0;
err:
if (f)
fclose(f);
return ret;
}

View File

@@ -0,0 +1,68 @@
/*
* PV image related definitions and functions
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#ifndef PV_IMAGE_H
#define PV_IMAGE_H
#include <glib.h>
#include <glib/gtypes.h>
#include <openssl/evp.h>
#include <stdint.h>
#include "boot/s390.h"
#include "utils/buffer.h"
#include "pv_args.h"
#include "pv_comp.h"
#include "pv_comps.h"
#include "pv_stage3.h"
typedef struct {
gchar *tmp_dir; /* directory used for temporary files */
Buffer *stage3a; /* stage3a containing IPIB and PV header */
gsize stage3a_bin_size; /* size of stage3a.bin */
struct psw_t stage3a_psw; /* (short) PSW that is written to
* location 0 of the created image
*/
struct psw_t initial_psw; /* PSW loaded by stage3b */
EVP_PKEY *cust_pub_priv_key; /* customer private/public key */
GSList *host_pub_keys; /* public host keys */
gint nid; /* Elliptic Curve used for the key derivation */
/* keys and cipher used for the AES-GCM encryption */
Buffer *cust_root_key;
Buffer *gcm_iv;
const EVP_CIPHER *gcm_cipher;
/* Information for the IPIB and PV header */
uint64_t pcf;
uint64_t scf;
Buffer *cust_comm_key;
const EVP_CIPHER *cust_comm_cipher;
Buffer *xts_key;
const EVP_CIPHER *xts_cipher;
GSList *key_slots;
GSList *optional_items;
PvImgComps *comps;
} PvImage;
PvImage *pv_img_new(PvArgs *args, const gchar *stage3a_path, GError **err);
void pv_img_free(PvImage *img);
gint pv_img_add_component(PvImage *img, const PvArg *arg, GError **err);
gint pv_img_finalize(PvImage *img, const gchar *stage3b_path, GError **err);
gint pv_img_calc_pld_ald_tld_nep(const PvImage *img, Buffer **pld, Buffer **ald,
Buffer **tld, uint64_t *nep, GError **err);
gint pv_img_load_and_set_stage3a(PvImage *img, const gchar *path, GError **err);
const PvComponent *pv_img_get_stage3b_comp(const PvImage *img, GError **err);
gint pv_img_add_stage3b_comp(PvImage *img, const gchar *path, GError **err);
uint32_t pv_img_get_enc_size(const PvImage *img);
uint32_t pv_img_get_pv_hdr_size(const PvImage *img);
gint pv_img_write(PvImage *img, const gchar *path, GError **err);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(PvImage, pv_img_free)
#endif

128
genprotimg/src/pv/pv_ipib.c Normal file
View File

@@ -0,0 +1,128 @@
/*
* PV IPIB related definitions and functions
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include <glib.h>
#include <glib/gtypes.h>
#include <stdint.h>
#include <stdio.h>
#include "boot/ipl.h"
#include "boot/s390.h"
#include "common.h"
#include "include/pv_hdr_def.h"
#include "lib/zt_common.h"
#include "utils/align.h"
#include "utils/buffer.h"
#include "pv_comp.h"
#include "pv_error.h"
#include "pv_ipib.h"
uint64_t pv_ipib_get_size(uint32_t num_comp)
{
gsize ipib_size = sizeof(struct ipl_pl_hdr) +
sizeof(struct ipl_pb0_pv) +
num_comp * sizeof(struct ipl_pb0_pv_comp);
/* the minimal size is one page */
return MAX(ipib_size, PAGE_SIZE);
}
static gint pv_ipib_init(IplParameterBlock *ipib, GSList *comps,
const Buffer *hdr)
{
g_assert(sizeof(struct ipl_pl_hdr) <= UINT32_MAX);
g_assert(sizeof(struct ipl_pb0_pv_comp) <= UINT32_MAX);
g_assert(sizeof(struct ipl_pb0_pv) <= UINT32_MAX);
g_assert(ipib);
guint comps_length = g_slist_length(comps);
uint32_t ipl_pl_hdr_size = (uint32_t)sizeof(struct ipl_pl_hdr);
struct ipl_pb0_pv *pv = &ipib->pv;
uint32_t ipib_comps_size;
uint32_t blk0_len;
uint32_t ipib_size;
gsize i;
g_assert_true(
g_uint_checked_mul(&ipib_comps_size, comps_length,
(uint32_t)sizeof(struct ipl_pb0_pv_comp)));
g_assert_true(g_uint_checked_add(&blk0_len, (uint32_t)sizeof(*pv),
ipib_comps_size));
g_assert(ipl_pl_hdr_size + blk0_len <= PAGE_SIZE);
ipib_size = MAX(ipl_pl_hdr_size + blk0_len, (uint32_t)PAGE_SIZE);
g_assert(pv_ipib_get_size(comps_length) == ipib_size);
pv->pbt = IPL_TYPE_PV;
pv->len = GUINT32_TO_BE(blk0_len);
pv->num_comp = GUINT32_TO_BE(comps_length);
/* both values will be overwritten during the IPL process by
* the stage3a loader
*/
pv->pv_hdr_addr = GUINT64_TO_BE(0x0);
pv->pv_hdr_size = GUINT64_TO_BE(hdr->size);
ipib->hdr.len = GUINT32_TO_BE(ipib_size);
ipib->hdr.version = IPL_PARM_BLOCK_VERSION;
i = 0;
for (GSList *iterator = comps; iterator; iterator = iterator->next, i++) {
const PvComponent *comp = iterator->data;
uint64_t comp_addr, comp_size;
g_assert(comp);
comp_addr = pv_component_get_src_addr(comp);
comp_size = pv_component_size(comp);
g_assert(IS_PAGE_ALIGNED(comp_size));
pv->components[i].addr = GUINT64_TO_BE(comp_addr);
pv->components[i].len = GUINT64_TO_BE(comp_size);
pv->components[i].tweak_pref =
GUINT64_TO_BE(pv_component_get_tweak_prefix(comp));
if (i > 0) {
/* tweak prefixes of the components must grow
* strictly monotonous
*/
g_assert(GUINT64_FROM_BE(pv->components[i].tweak_pref) >
GUINT64_FROM_BE(pv->components[i - 1].tweak_pref));
}
}
return 0;
}
IplParameterBlock *pv_ipib_new(GSList *comps, const Buffer *hdr, GError **err)
{
uint64_t ipib_size = pv_ipib_get_size(g_slist_length(comps));
g_autoptr(IplParameterBlock) ret = NULL;
if (ipib_size > PV_V1_IPIB_MAX_SIZE) {
g_set_error(err, PV_ERROR, PV_ERROR_IPIB_SIZE,
_("IPIB size is too large: %lu < %lu"), ipib_size,
PAGE_SIZE);
return NULL;
}
ret = g_malloc0(ipib_size);
if (pv_ipib_init(ret, comps, hdr) < 0)
return NULL;
return g_steal_pointer(&ret);
}
void pv_ipib_free(IplParameterBlock *ipib)
{
if (!ipib)
return;
g_free(ipib);
}

View File

@@ -0,0 +1,27 @@
/*
* PV IPIB related definitions and functions
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#ifndef PV_IPIB_H
#define PV_IPIB_H
#include <glib.h>
#include <stdint.h>
#include "boot/ipl.h"
#include "utils/buffer.h"
typedef struct ipl_parameter_block IplParameterBlock;
uint64_t pv_ipib_get_size(uint32_t num_comp);
IplParameterBlock *pv_ipib_new(GSList *comps, const Buffer *hdr, GError **err);
void pv_ipib_free(IplParameterBlock *ipib);
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(IplParameterBlock, pv_ipib_free)
#endif

View File

@@ -0,0 +1,26 @@
/*
* PV optional item related definitions and functions
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include <glib.h>
#include "pv_opt_item.h"
uint32_t pv_opt_item_size(const struct pv_hdr_opt_item *item G_GNUC_UNUSED)
{
/* not implemented yet */
g_assert_not_reached();
}
void pv_opt_item_free(struct pv_hdr_opt_item *item)
{
if (!item)
return;
g_free(item);
}

View File

@@ -0,0 +1,20 @@
/*
* PV optional item related definitions and functions
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#ifndef PV_OPT_ITEM_H
#define PV_OPT_ITEM_H
#include <stdint.h>
#include "include/pv_hdr_def.h"
uint32_t pv_opt_item_size(const struct pv_hdr_opt_item *item);
void pv_opt_item_free(struct pv_hdr_opt_item *item);
#endif

View File

@@ -0,0 +1,164 @@
/*
* PV stage3 loader related definitions and functions
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include <glib.h>
#include <stdint.h>
#include <string.h>
#include "boot/ipl.h"
#include "boot/stage3a.h"
#include "boot/stage3b.h"
#include "common.h"
#include "utils/align.h"
#include "pv_error.h"
#include "pv_stage3.h"
#define STAGE3A_ARGS(data_ptr, loader_size) \
((struct stage3a_args *)((uint64_t)data_ptr + loader_size - \
sizeof(struct stage3a_args)))
static Buffer *loader_getblob(const gchar *filename, gsize *loader_size,
gsize args_size, gsize data_size,
gboolean data_aligned, GError **err)
{
g_autoptr(GMappedFile) mapped_file = NULL;
g_autoptr(Buffer) ret = NULL;
gsize size, tmp_loader_size;
gchar *loader_data;
g_assert(loader_size);
mapped_file = g_mapped_file_new(filename, FALSE, err);
if (!mapped_file)
return NULL;
loader_data = g_mapped_file_get_contents(mapped_file);
if (!loader_data) {
g_set_error(err, G_FILE_ERROR, G_FILE_ERROR_BADF,
_("File '%s' is empty"), filename);
return NULL;
}
tmp_loader_size = g_mapped_file_get_length(mapped_file);
if (tmp_loader_size < args_size) {
g_set_error(err, G_FILE_ERROR, G_FILE_ERROR_BADF,
_("File size less than expected: %lu < %ln"),
tmp_loader_size, loader_size);
return NULL;
}
/* For example, the PV header and IPIB data must be page
* aligned.
*/
size = (data_aligned ? PAGE_ALIGN(tmp_loader_size) : tmp_loader_size) +
data_size;
ret = buffer_alloc(size);
/* copy the loader "template" */
memcpy(ret->data, loader_data, tmp_loader_size);
/* reset our dummy data (offsets and length) to zeros */
memset((uint8_t *)ret->data + tmp_loader_size - args_size, 0,
args_size);
*loader_size = tmp_loader_size;
return g_steal_pointer(&ret);
}
Buffer *stage3a_getblob(const gchar *filename, gsize *loader_size,
gsize data_size, GError **err)
{
return loader_getblob(filename, loader_size,
sizeof(struct stage3a_args), data_size, TRUE,
err);
}
/* For the memory layout see stage3a.lds */
/* Set the right offsets and sizes in the stage3a template + add
* the IPIB block with the PV header
*/
static gint stage3a_set_data(Buffer *loader, gsize loader_size,
const Buffer *hdr, struct ipl_parameter_block *ipib,
GError **err)
{
uint32_t ipib_size = GUINT32_FROM_BE(ipib->hdr.len);
gsize args_size = sizeof(struct stage3a_args);
uint32_t hdr_size = (uint32_t)hdr->size;
uint64_t args_addr, next_data_addr;
if (hdr->size > UINT32_MAX) {
g_set_error(err, PV_ERROR, PV_ERROR_INTERNAL,
_("Invalid header size: %zu"), hdr->size);
return -1;
}
/* we assume here that the loader ``stage3a`` is loaded page
* aligned in the guest
*/
args_addr = (uint64_t)loader->data + loader_size - args_size;
/* therefore `next_data_addr` is also page aligned */
next_data_addr = (uint64_t)loader->data + PAGE_ALIGN(loader_size);
/* copy IPIB data */
memcpy((void *)next_data_addr, ipib, ipib_size);
/* set IPIB offset in relation to the stage3a arguments */
STAGE3A_ARGS(loader->data, loader_size)->ipib_offs =
GUINT64_TO_BE(next_data_addr - args_addr);
next_data_addr = next_data_addr + PAGE_ALIGN(ipib_size);
/* copy PV header */
memcpy((void *)next_data_addr, hdr->data, hdr_size);
/* set PV header size and offset in relation to the stage3a
* arguments
*/
STAGE3A_ARGS(loader->data, loader_size)->hdr_offs =
GUINT64_TO_BE(next_data_addr - args_addr);
STAGE3A_ARGS(loader->data, loader_size)->hdr_size = GUINT64_TO_BE(hdr_size);
return 0;
}
gint build_stage3a(Buffer *loader, gsize loader_size, const Buffer *hdr,
struct ipl_parameter_block *ipib, GError **err)
{
return stage3a_set_data(loader, loader_size, hdr, ipib, err);
}
Buffer *stage3b_getblob(const gchar *filename, GError **err)
{
g_autoptr(Buffer) ret = NULL;
gsize rb_size;
ret = loader_getblob(filename, &rb_size, sizeof(struct stage3b_args), 0,
FALSE, err);
if (!ret)
return NULL;
g_assert(ret->size == rb_size);
return g_steal_pointer(&ret);
}
void build_stage3b(Buffer *stage3b, const struct stage3b_args *args)
{
g_assert(stage3b->size > sizeof(*args));
/* at the end of the stage3b there are the stage3b args
* positioned
*/
memcpy((uint8_t *)stage3b->data + stage3b->size - sizeof(*args), args,
sizeof(*args));
}
void memblob_init(struct memblob *arg, uint64_t src, uint64_t size)
{
arg->src = GUINT64_TO_BE(src);
arg->size = GUINT64_TO_BE(size);
}

View File

@@ -0,0 +1,30 @@
/*
* PV stage3 loader related definitions and functions
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#ifndef PV_STAGE3_H
#define PV_STAGE3_H
#include <glib.h>
#include <glib/gtypes.h>
#include <stdint.h>
#include "boot/ipl.h"
#include "boot/s390.h"
#include "boot/stage3b.h"
#include "utils/buffer.h"
Buffer *stage3a_getblob(const gchar *filename, gsize *loader_size,
gsize data_size, GError **err);
gint build_stage3a(Buffer *dc, gsize dc_size, const Buffer *hdr,
struct ipl_parameter_block *ipib, GError **err);
Buffer *stage3b_getblob(const gchar *filename, GError **err);
void build_stage3b(Buffer *stage3b, const struct stage3b_args *args);
void memblob_init(struct memblob *arg, uint64_t src, uint64_t size);
#endif

View File

@@ -0,0 +1,24 @@
/*
* Alignment utils
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#ifndef PV_UTILS_ALIGN_H
#define PV_UTILS_ALIGN_H
#include "boot/s390.h"
#include "lib/zt_common.h"
#define IS_ALIGNED(addr, size) (!(addr & (size - 1)))
/* align addr to the next page boundary */
#define PAGE_ALIGN(addr) ALIGN((unsigned long)addr, PAGE_SIZE)
/* test whether an address is aligned to PAGE_SIZE or not */
#define IS_PAGE_ALIGNED(addr) IS_ALIGNED((unsigned long)(addr), PAGE_SIZE)
#endif

View File

@@ -0,0 +1,69 @@
/*
* Buffer functions
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include <errno.h>
#include <glib.h>
#include <stdio.h>
#include <string.h>
#include "align.h"
#include "buffer.h"
#include "common.h"
#include "file_utils.h"
Buffer *buffer_alloc(gsize size)
{
Buffer *ret = g_new0(Buffer, 1);
ret->data = g_malloc0(size);
ret->size = size;
return ret;
}
Buffer *buffer_dup(const Buffer *buf, gboolean page_aligned)
{
Buffer *ret;
gsize size;
if (!buf)
return NULL;
size = buf->size;
if (page_aligned)
size = PAGE_ALIGN(size);
ret = buffer_alloc(size);
/* content will be 0-right-padded */
memcpy(ret->data, buf->data, buf->size);
return ret;
}
gint buffer_write(const Buffer *buf, FILE *file, GError **err)
{
return file_write(file, buf->data, buf->size, 1, NULL, err);
}
void buffer_free(Buffer *buf)
{
if (!buf)
return;
g_free(buf->data);
g_free(buf);
}
void buffer_clear(Buffer **buf)
{
if (!buf || !*buf)
return;
buffer_free(*buf);
*buf = NULL;
}

View File

@@ -0,0 +1,31 @@
/*
* Buffer definition and functions
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#ifndef PV_UTILS_BUFFER_H
#define PV_UTILS_BUFFER_H
#include <glib.h>
#include <stdio.h>
#include "common.h"
typedef struct Buffer {
void *data;
gsize size; /* in bytes */
} Buffer;
Buffer *buffer_alloc(gsize size);
void buffer_free(Buffer *buf);
void buffer_clear(Buffer **buf);
gint buffer_write(const Buffer *buf, FILE *file, GError **err);
Buffer *buffer_dup(const Buffer *buf, gboolean page_aligned);
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(Buffer, buffer_free)
#endif

View File

@@ -0,0 +1,798 @@
/*
* General cryptography helper functions
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include <glib.h>
#include <glib/gtypes.h>
#include <limits.h>
#include <openssl/aes.h>
#include <openssl/bn.h>
#include <openssl/ec.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/rand.h>
#include <stdint.h>
#include <string.h>
#include "boot/s390.h"
#include "common.h"
#include "include/pv_crypto_def.h"
#include "pv/pv_error.h"
#include "buffer.h"
#include "crypto.h"
EVP_MD_CTX *digest_ctx_new(const EVP_MD *md, GError **err)
{
g_autoptr(EVP_MD_CTX) ctx = EVP_MD_CTX_new();
if (!ctx)
g_abort();
if (EVP_DigestInit_ex(ctx, md, NULL) != 1) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL,
_("EVP_DigestInit_ex failed"));
return NULL;
}
return g_steal_pointer(&ctx);
}
Buffer *digest_ctx_finalize(EVP_MD_CTX *ctx, GError **err)
{
gint md_size = EVP_MD_size(EVP_MD_CTX_md(ctx));
g_autoptr(Buffer) ret = NULL;
guint digest_size;
g_assert(md_size > 0);
ret = buffer_alloc((guint)md_size);
if (EVP_DigestFinal_ex(ctx, ret->data, &digest_size) != 1) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL,
_("EVP_DigestFinal_ex failed"));
return NULL;
}
g_assert(digest_size == (guint)md_size);
g_assert(digest_size == ret->size);
return g_steal_pointer(&ret);
}
/* Returns the digest of @buf using the hash algorithm @md */
static Buffer *digest_buffer(const EVP_MD *md, const Buffer *buf, GError **err)
{
g_autoptr(EVP_MD_CTX) md_ctx = NULL;
g_autoptr(Buffer) ret = NULL;
g_assert(buf);
md_ctx = digest_ctx_new(md, err);
if (!md_ctx)
return NULL;
if (EVP_DigestUpdate(md_ctx, buf->data, buf->size) != 1) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL,
_("EVP_DigestUpdate failed"));
return NULL;
}
ret = digest_ctx_finalize(md_ctx, err);
if (!ret)
return NULL;
return g_steal_pointer(&ret);
}
/* Returns the SHA256 digest of @buf */
Buffer *sha256_buffer(const Buffer *buf, GError **err)
{
g_autoptr(Buffer) ret = NULL;
ret = digest_buffer(EVP_sha256(), buf, err);
if (!ret)
return NULL;
g_assert(ret->size == SHA256_DIGEST_LENGTH);
return g_steal_pointer(&ret);
}
/* Convert a EVP_PKEY to the key format used in the PV header */
union ecdh_pub_key *evp_pkey_to_ecdh_pub_key(EVP_PKEY *key, GError **err)
{
g_autofree union ecdh_pub_key *ret = g_new0(union ecdh_pub_key, 1);
g_autoptr(BIGNUM) pub_x_big = NULL;
g_autoptr(BIGNUM) pub_y_big = NULL;
g_autoptr(EC_KEY) ec_key = NULL;
const EC_POINT *pub_key;
const EC_GROUP *grp;
ec_key = EVP_PKEY_get1_EC_KEY(key);
if (!ec_key) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL,
_("Key has the wrong type"));
return NULL;
}
pub_key = EC_KEY_get0_public_key(ec_key);
if (!pub_key) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL,
_("Failed to get public key"));
return NULL;
}
grp = EC_KEY_get0_group(ec_key);
if (!grp) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL,
_("Failed to get EC group"));
return NULL;
}
pub_x_big = BN_new();
if (!pub_x_big)
g_abort();
pub_y_big = BN_new();
if (!pub_y_big)
g_abort();
if (EC_POINT_get_affine_coordinates_GFp(grp, pub_key, pub_x_big,
pub_y_big, NULL) != 1) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL,
_("Cannot convert key to internal format"));
return NULL;
}
if (BN_bn2binpad(pub_x_big, ret->x, sizeof(ret->x)) < 0) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL,
_("Cannot convert key to internal format"));
return NULL;
}
if (BN_bn2binpad(pub_y_big, ret->y, sizeof(ret->y)) < 0) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL,
_("Cannot convert key to internal format"));
return NULL;
}
return g_steal_pointer(&ret);
}
static Buffer *derive_key(EVP_PKEY *cust, EVP_PKEY *host, GError **err)
{
g_autoptr(EVP_PKEY_CTX) ctx = NULL;
g_autoptr(Buffer) ret = NULL;
gsize key_size;
ctx = EVP_PKEY_CTX_new(cust, NULL);
if (!ctx)
g_abort();
if (EVP_PKEY_derive_init(ctx) != 1) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL,
_("Key derivation failed"));
return NULL;
}
if (EVP_PKEY_derive_set_peer(ctx, host) != 1) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL,
_("Key derivation failed"));
return NULL;
}
/* Determine buffer length */
if (EVP_PKEY_derive(ctx, NULL, &key_size) != 1) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_DERIVE,
_("Key derivation failed"));
return NULL;
}
ret = buffer_alloc(key_size);
if (EVP_PKEY_derive(ctx, ret->data, &key_size) != 1) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_DERIVE,
_("Key derivation failed"));
return NULL;
}
g_assert(ret->size == key_size);
return g_steal_pointer(&ret);
}
Buffer *compute_exchange_key(EVP_PKEY *cust, EVP_PKEY *host, GError **err)
{
g_autoptr(Buffer) raw = buffer_alloc(70);
g_autoptr(Buffer) ret = NULL;
g_autoptr(Buffer) key = NULL;
guchar *data;
key = derive_key(cust, host, err);
if (!key)
return NULL;
g_assert(key->size == 66);
g_assert(key->size < raw->size);
/* ANSI X.9.63-2011: 66 bytes x with leading 7 bits and
* concatenate 32 bit int '1'
*/
memcpy(raw->data, key->data, key->size);
data = raw->data;
data[66] = 0x00;
data[67] = 0x00;
data[68] = 0x00;
data[69] = 0x01;
ret = sha256_buffer(raw, err);
if (!ret)
return NULL;
return g_steal_pointer(&ret);
}
gint generate_tweak(union tweak *tweak, uint16_t i, GError **err)
{
tweak->cmp_idx.idx = GUINT16_TO_BE(i);
if (RAND_bytes(tweak->cmp_idx.rand, sizeof(tweak->cmp_idx.rand)) != 1) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_RANDOMIZATION,
_("Generating a tweak failed because the required amount of random data is not available"));
return -1;
}
return 0;
}
static Buffer *generate_rand_data(guint size, const gchar *err_msg,
GError **err)
{
g_autoptr(Buffer) buf = buffer_alloc(size);
g_assert(size <= INT_MAX);
if (RAND_bytes(buf->data, (int)size) != 1) {
g_set_error_literal(err, PV_CRYPTO_ERROR,
PV_CRYPTO_ERROR_RANDOMIZATION,
err_msg);
return NULL;
}
return g_steal_pointer(&buf);
}
Buffer *generate_aes_iv(guint size, GError **err)
{
return generate_rand_data(size,
_("Generating a IV failed because the required amount of random data is not available"),
err);
}
Buffer *generate_aes_key(guint size, GError **err)
{
return generate_rand_data(size,
_("Generating a key failed because the required amount of random data is not available"),
err);
}
EVP_PKEY *generate_ec_key(gint nid, GError **err)
{
g_autoptr(EVP_PKEY_CTX) ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
g_autoptr(EVP_PKEY) ret = NULL;
if (!ctx)
g_abort();
if (EVP_PKEY_keygen_init(ctx) != 1) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_KEYGENERATION,
_("EC key could not be auto-generated"));
return NULL;
}
if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid) != 1) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_KEYGENERATION,
_("EC key could not be auto-generated"));
return NULL;
}
if (EVP_PKEY_keygen(ctx, &ret) != 1) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_KEYGENERATION,
_("EC key could not be auto-generated"));
return NULL;
}
return g_steal_pointer(&ret);
}
static gboolean certificate_uses_correct_curve(EVP_PKEY *key, gint nid,
GError **err)
{
g_autoptr(EC_KEY) ec = NULL;
gint rc;
g_assert(key);
if (EVP_PKEY_id(key) != EVP_PKEY_EC) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INVALID_PARM,
_("No EC key found"));
return FALSE;
}
ec = EVP_PKEY_get1_EC_KEY(key);
if (!ec) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INVALID_PARM,
_("No EC key found"));
return FALSE;
}
if (EC_KEY_check_key(ec) != 1) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INVALID_PARM,
_("Invalid EC key"));
return FALSE;
}
rc = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
if (rc != nid) {
/* maybe the NID is unset */
if (rc == 0) {
g_autoptr(EC_GROUP) grp = EC_GROUP_new_by_curve_name(nid);
const EC_POINT *pub = EC_KEY_get0_public_key(ec);
g_autoptr(BN_CTX) ctx = BN_CTX_new();
if (EC_POINT_is_on_curve(grp, pub, ctx) != 1) {
g_set_error_literal(err, PV_CRYPTO_ERROR,
PV_CRYPTO_ERROR_INVALID_PARM,
_("Invalid EC curve"));
return FALSE;
}
} else {
/* NID was set but doesn't match with the expected NID
*/
g_set_error(err, PV_CRYPTO_ERROR,
PV_CRYPTO_ERROR_INVALID_PARM,
_("Wrong NID used: '%d'"),
EC_GROUP_get_curve_name(EC_KEY_get0_group(ec)));
return FALSE;
}
}
return TRUE;
}
static gboolean verify_certificate(X509_STORE *store, X509 *cert, GError **err)
{
g_autoptr(X509_STORE_CTX) csc = X509_STORE_CTX_new();
if (!csc)
g_abort();
if (X509_STORE_CTX_init(csc, store, cert, NULL) != 1) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INIT,
_("Failed to initialize X.509 store"));
return FALSE;
}
if (X509_verify_cert(csc) != 1) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_VERIFICATION,
_("Failed to verify host-key document"));
return FALSE;
}
return TRUE;
}
static X509 *load_certificate(const gchar *path, GError **err)
{
g_autoptr(X509) ret = NULL;
g_autoptr(BIO) bio = BIO_new_file(path, "rb");
if (!bio) {
g_set_error(err, PV_CRYPTO_ERROR,
PV_CRYPTO_ERROR_READ_CERTIFICATE,
_("Failed to read host-key document: '%s'"), path);
return NULL;
}
ret = PEM_read_bio_X509(bio, NULL, 0, NULL);
if (!ret) {
g_set_error(err, PV_CRYPTO_ERROR,
PV_CRYPTO_ERROR_READ_CERTIFICATE,
_("Failed to load host-key document: '%s'"), path);
return NULL;
}
return g_steal_pointer(&ret);
}
EVP_PKEY *read_ec_pubkey_cert(X509_STORE *store, gint nid, const gchar *path,
GError **err)
{
g_autoptr(EVP_PKEY) ret = NULL;
g_autoptr(X509) cert = NULL;
cert = load_certificate(path, err);
if (!cert)
return NULL;
if (store && !verify_certificate(store, cert, err)) {
g_prefix_error(err,
_("Failed to load host-key document: '%s': "),
path);
return NULL;
}
ret = X509_get_pubkey(cert);
if (!ret) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INVALID_PARM,
_("Failed to get public key from host-key document: '%s'"),
path);
return NULL;
}
if (!certificate_uses_correct_curve(ret, nid, err)) {
g_prefix_error(err,
_("Failed to load host-key document: '%s': "),
path);
return NULL;
}
return g_steal_pointer(&ret);
}
static gint __encrypt_decrypt_bio(const struct cipher_parms *parms, BIO *b_in,
BIO *b_out, gsize *size_in, gsize *size_out,
gboolean encrypt, GError **err)
{
gint num_bytes_read, num_bytes_written;
g_autoptr(EVP_CIPHER_CTX) ctx = NULL;
g_autoptr(BIGNUM) tweak_num = NULL;
const EVP_CIPHER *cipher = parms->cipher;
gint cipher_block_size = EVP_CIPHER_block_size(cipher);
guchar in_buf[PAGE_SIZE],
out_buf[PAGE_SIZE + (guint)cipher_block_size];
const Buffer *key = parms->key;
const Buffer *tweak = parms->iv_or_tweak;
g_autofree guchar *tmp_tweak = NULL;
gint out_len, tweak_size;
gsize tmp_size_in = 0, tmp_size_out = 0;
g_assert(cipher_block_size > 0);
g_assert(key);
g_assert(tweak);
g_assert(tweak->size <= INT_MAX);
/* copy the value for leaving the original value untouched */
tmp_tweak = g_malloc0(tweak->size);
memcpy(tmp_tweak, tweak->data, tweak->size);
tweak_size = (int)tweak->size;
tweak_num = BN_bin2bn(tmp_tweak, tweak_size, NULL);
if (!tweak_num) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL,
_("BN_bin2bn failed"));
return -1;
}
ctx = EVP_CIPHER_CTX_new();
if (!ctx)
g_abort();
/* don't set the key or tweak right away as we want to check
* lengths before
*/
if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, encrypt) != 1) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL,
_("EVP_CipherInit_ex failed"));
return -1;
}
/* Now we can set the key and tweak */
if (EVP_CipherInit_ex(ctx, NULL, NULL, key->data, tmp_tweak, encrypt) !=
1) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL,
_("EVP_CipherInit_ex failed"));
return -1;
}
do {
memset(in_buf, 0, sizeof(in_buf));
/* Read in data in 4096 bytes blocks. Update the ciphering
* with each read.
*/
num_bytes_read = BIO_read(b_in, in_buf, (int)PAGE_SIZE);
if (num_bytes_read < 0) {
g_set_error(err, PV_CRYPTO_ERROR,
PV_CRYPTO_ERROR_INTERNAL,
_("Failed to read"));
return -1;
}
tmp_size_in += (guint)num_bytes_read;
/* in case we reached the end and it's not the special
* case of an empty component we can break here
*/
if (num_bytes_read == 0 && tmp_size_in != 0)
break;
if (EVP_CipherUpdate(ctx, out_buf, &out_len, in_buf,
sizeof(in_buf)) != 1) {
g_set_error(err, PV_CRYPTO_ERROR,
PV_CRYPTO_ERROR_INTERNAL,
_("EVP_CipherUpdate failed"));
return -1;
}
g_assert(out_len >= 0);
num_bytes_written = BIO_write(b_out, out_buf, out_len);
if (num_bytes_written < 0) {
g_set_error(err, PV_CRYPTO_ERROR,
PV_CRYPTO_ERROR_INTERNAL,
_("Failed to write"));
return -1;
}
g_assert(num_bytes_written == out_len);
tmp_size_out += (guint)num_bytes_written;
/* Set new tweak value. Please keep in mind that the
* tweaks are stored in big-endian form. Therefore we
* must use the correct OpenSSL functions
*/
if (BN_add_word(tweak_num, PAGE_SIZE) != 1) {
g_set_error(err, PV_CRYPTO_ERROR,
PV_CRYPTO_ERROR_INTERNAL,
_("BN_add_word failed"));
}
g_assert(BN_num_bytes(tweak_num) > 0);
g_assert(BN_num_bytes(tweak_num) <= tweak_size);
if (BN_bn2binpad(tweak_num, tmp_tweak, tweak_size) < 0) {
g_set_error(err, PV_CRYPTO_ERROR,
PV_CRYPTO_ERROR_INTERNAL,
_("BN_bn2binpad failed"));
};
/* set new tweak */
if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, tmp_tweak,
encrypt) != 1) {
g_set_error(err, PV_CRYPTO_ERROR,
PV_CRYPTO_ERROR_INTERNAL,
_("EVP_CipherInit_ex failed"));
return -1;
}
} while (num_bytes_read == PAGE_SIZE);
/* Now cipher the final block and write it out to file */
if (EVP_CipherFinal_ex(ctx, out_buf, &out_len) != 1) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL,
_("EVP_CipherFinal_ex failed"));
return -1;
}
g_assert(out_len >= 0);
num_bytes_written = BIO_write(b_out, out_buf, out_len);
if (num_bytes_written < 0) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL,
_("Failed to write"));
return -1;
}
g_assert(out_len == num_bytes_written);
tmp_size_out += (guint)out_len;
if (BIO_flush(b_out) != 1) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL,
_("Failed to flush"));
return -1;
}
*size_in = tmp_size_in;
*size_out = tmp_size_out;
return 0;
}
static Buffer *__encrypt_decrypt_buffer(const struct cipher_parms *parms,
const Buffer *in, gboolean encrypt,
GError **err)
{
g_autoptr(Buffer) ret = NULL;
g_autoptr(BIO) b_out = NULL;
g_autoptr(BIO) b_in = NULL;
gsize in_size, out_size;
gchar *data = NULL;
long data_size;
g_assert(in->size <= INT_MAX);
b_in = BIO_new_mem_buf(in->data, (int)in->size);
if (!b_in)
g_abort();
b_out = BIO_new(BIO_s_mem());
if (!b_out)
g_abort();
if (__encrypt_decrypt_bio(parms, b_in, b_out, &in_size, &out_size,
encrypt, err) < 0)
return NULL;
data_size = BIO_get_mem_data(b_out, &data);
if (data_size < 0) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL,
_("Could not read buffer"));
return NULL;
}
ret = buffer_alloc((unsigned long)data_size);
memcpy(ret->data, data, ret->size);
return g_steal_pointer(&ret);
}
Buffer *encrypt_buf(const struct cipher_parms *parms, const Buffer *in,
GError **err)
{
return __encrypt_decrypt_buffer(parms, in, TRUE, err);
}
Buffer *decrypt_buf(const struct cipher_parms *parms, const Buffer *in,
GError **err)
{
return __encrypt_decrypt_buffer(parms, in, FALSE, err);
}
static gint __encrypt_decrypt_file(const struct cipher_parms *parms,
const gchar *path_in, const gchar *path_out,
gsize *size_in, gsize *size_out, gboolean encrypt,
GError **err)
{
g_autoptr(BIO) b_out = NULL;
g_autoptr(BIO) b_in = NULL;
b_in = BIO_new_file(path_in, "rb");
if (!b_in) {
g_set_error(err, PV_CRYPTO_ERROR,
PV_CRYPTO_ERROR_READ_CERTIFICATE,
_("Failed to read file '%s'"), path_in);
return -1;
}
b_out = BIO_new_file(path_out, "wb");
if (!b_out) {
g_set_error(err, PV_CRYPTO_ERROR,
PV_CRYPTO_ERROR_READ_CERTIFICATE,
_("Failed to write file '%s'"), path_out);
return -1;
}
if (__encrypt_decrypt_bio(parms, b_in, b_out, size_in, size_out,
encrypt, err) < 0)
return -1;
return 0;
}
gint encrypt_file(const struct cipher_parms *parms, const gchar *path_in,
const gchar *path_out, gsize *in_size, gsize *out_size,
GError **err)
{
return __encrypt_decrypt_file(parms, path_in, path_out, in_size,
out_size, TRUE, err);
}
G_GNUC_UNUSED static gint decrypt_file(const struct cipher_parms *parms,
const gchar *path_in, const gchar *path_out,
gsize *in_size, gsize *out_size,
GError **err)
{
return __encrypt_decrypt_file(parms, path_in, path_out, in_size,
out_size, FALSE, err);
}
/* GCM mode uses (zero-)padding */
static int64_t gcm_encrypt_decrypt(const Buffer *in, const Buffer *aad,
const struct cipher_parms *parms,
Buffer *out, Buffer *tag,
enum PvCryptoMode mode, GError **err)
{
g_autoptr(EVP_CIPHER_CTX) ctx = NULL;
const EVP_CIPHER *cipher = parms->cipher;
const Buffer *iv = parms->iv_or_tweak;
gboolean encrypt = mode == PV_ENCRYPT;
const Buffer *key = parms->key;
int64_t ret = -1;
gint len = -1;
g_assert(cipher);
g_assert(key);
g_assert(iv);
/* Checks for later casts */
g_assert(aad->size <= INT_MAX);
g_assert(in->size <= INT_MAX);
g_assert(tag->size <= INT_MAX);
g_assert(iv->size <= INT_MAX);
g_assert(out->size == in->size);
ctx = EVP_CIPHER_CTX_new();
if (!ctx)
g_abort();
/* First, set the cipher algorithm so we can verify our key/IV lengths
*/
if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, encrypt) != 1) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL,
_("EVP_CIPHER_CTX_new failed"));
return -1;
}
/* Set IV length */
if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, (int)iv->size, NULL) != 1) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL,
_("EVP_CIPHER_CTX_ex failed"));
return -1;
}
/* Initialise key and IV */
if (EVP_CipherInit_ex(ctx, NULL, NULL, key->data, iv->data, encrypt) !=
1) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL,
_("EVP_CipherInit_ex failed"));
return -1;
}
if (aad->size > 0) {
/* Provide any AAD data */
if (EVP_CipherUpdate(ctx, NULL, &len, aad->data,
(int)aad->size) != 1) {
g_set_error(err, PV_CRYPTO_ERROR,
PV_CRYPTO_ERROR_INTERNAL,
_("EVP_CipherUpdate failed"));
return -1;
}
g_assert(len == (int)aad->size);
}
/* Provide data to be en/decrypted */
if (EVP_CipherUpdate(ctx, out->data, &len, in->data, (int)in->size) != 1) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL,
_("EVP_CipherUpdate failed"));
return -1;
}
ret = len;
if (!encrypt) {
/* Set expected tag value */
if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG,
(int)tag->size, tag->data) != 1) {
g_set_error(err, PV_CRYPTO_ERROR,
PV_CRYPTO_ERROR_INTERNAL,
_("Setting the GCM tag failed"));
return -1;
}
}
/* Finalize the en/decryption */
if (EVP_CipherFinal_ex(ctx, (guchar *)out->data + len, &len) != 1) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL,
_("EVP_CipherFinal_ex failed"));
return -1;
}
ret += len;
if (encrypt) {
/* Get the tag */
if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG,
(int)tag->size, tag->data) != 1) {
g_set_error(err, PV_CRYPTO_ERROR,
PV_CRYPTO_ERROR_INTERNAL,
_("Getting the GCM tag failed"));
return -1;
}
}
g_assert(ret == (int)in->size);
return ret;
}
int64_t gcm_encrypt(const Buffer *in, const Buffer *aad,
const struct cipher_parms *parms, Buffer *out, Buffer *tag,
GError **err)
{
return gcm_encrypt_decrypt(in, aad, parms, out, tag, PV_ENCRYPT, err);
}

View File

@@ -0,0 +1,104 @@
/*
* General cryptography helper functions and definitions
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#ifndef PV_UTILS_CRYPTO_H
#define PV_UTILS_CRYPTO_H
#include <glib.h>
#include <openssl/bio.h>
#include <openssl/bn.h>
#include <openssl/ec.h>
#include <openssl/ecdh.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <openssl/sha.h>
#include <openssl/x509.h>
#include <stdint.h>
#include "common.h"
#include "include/pv_crypto_def.h"
#include "lib/zt_common.h"
#include "buffer.h"
#define AES_256_GCM_IV_SIZE 12
#define AES_256_GCM_TAG_SIZE 16
#define AES_256_XTS_TWEAK_SIZE 16
#define AES_256_XTS_KEY_SIZE 64
enum PvCryptoMode {
PV_ENCRYPT,
PV_DECRYPT,
};
typedef GSList HostKeyList;
/* Register auto cleanup functions */
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(BIGNUM, BN_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(BIO, BIO_free_all)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(BN_CTX, BN_CTX_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EC_GROUP, EC_GROUP_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EC_KEY, EC_KEY_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EC_POINT, EC_POINT_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EVP_CIPHER_CTX, EVP_CIPHER_CTX_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EVP_MD_CTX, EVP_MD_CTX_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EVP_PKEY, EVP_PKEY_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EVP_PKEY_CTX, EVP_PKEY_CTX_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509, X509_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_LOOKUP, X509_LOOKUP_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_STORE, X509_STORE_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_STORE_CTX, X509_STORE_CTX_free)
union cmp_index {
struct {
uint16_t idx;
guchar rand[6];
} __packed;
uint64_t data;
};
/* The tweak is always stored in big endian format */
union tweak {
struct {
union cmp_index cmp_idx;
uint64_t page_idx; /* page index */
} __packed;
uint8_t data[AES_256_XTS_TWEAK_SIZE];
};
struct cipher_parms {
const EVP_CIPHER *cipher;
const Buffer *key;
const Buffer *iv_or_tweak;
};
EVP_PKEY *read_ec_pubkey_cert(X509_STORE *store, gint nid, const gchar *path,
GError **err);
Buffer *compute_exchange_key(EVP_PKEY *cust, EVP_PKEY *host, GError **err);
Buffer *generate_aes_key(guint size, GError **err);
Buffer *generate_aes_iv(guint size, GError **err);
EVP_PKEY *generate_ec_key(gint nid, GError **err);
gint generate_tweak(union tweak *tweak, uint16_t i, GError **err);
union ecdh_pub_key *evp_pkey_to_ecdh_pub_key(EVP_PKEY *key, GError **err);
EVP_MD_CTX *digest_ctx_new(const EVP_MD *md, GError **err);
Buffer *digest_ctx_finalize(EVP_MD_CTX *ctx, GError **err);
Buffer *sha256_buffer(const Buffer *buf, GError **err);
int64_t gcm_encrypt(const Buffer *in, const Buffer *aad,
const struct cipher_parms *parms, Buffer *out,
Buffer *tag, GError **err);
gint encrypt_file(const struct cipher_parms *parms, const gchar *in_path,
const gchar *path_out, gsize *in_size, gsize *out_size,
GError **err);
Buffer *encrypt_buf(const struct cipher_parms *parms, const Buffer *in,
GError **err);
G_GNUC_UNUSED Buffer *decrypt_buf(const struct cipher_parms *parms,
const Buffer *in, GError **err);
#endif

View File

@@ -0,0 +1,234 @@
/*
* General file utils
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include <errno.h>
#include <fcntl.h>
#include <glib.h>
#include <glib/gstdio.h>
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "pv/pv_error.h"
#include "align.h"
#include "buffer.h"
#include "common.h"
#include "file_utils.h"
FILE *file_open(const gchar *filename, const gchar *mode, GError **err)
{
FILE *f = fopen(filename, mode);
if (!f) {
g_set_error(err, G_FILE_ERROR,
(gint)g_file_error_from_errno(errno),
_("Failed to open file '%s': %s"), filename,
g_strerror(errno));
return NULL;
}
return f;
}
gint file_size(const gchar *filename, gsize *size, GError **err)
{
GStatBuf st_buf;
g_assert(size);
if (g_stat(filename, &st_buf) != 0) {
g_set_error(err, G_FILE_ERROR,
(gint)g_file_error_from_errno(errno),
_("Failed to get file status '%s': %s"), filename,
g_strerror(errno));
return -1;
}
if (!S_ISREG(st_buf.st_mode)) {
g_set_error(err, G_FILE_ERROR, PV_ERROR_INTERNAL,
_("File '%s' is not a regular file"), filename);
return -1;
}
if (st_buf.st_size < 0) {
g_set_error(err, G_FILE_ERROR, PV_ERROR_INTERNAL,
_("Invalid file size for '%s': %zu"), filename,
st_buf.st_size);
return -1;
}
*size = (gsize)st_buf.st_size;
return 0;
}
/* Returns 0 on success, otherwise -1. Stores the total number of
* elements successfully read in @count_read
*/
gint file_read(FILE *in, void *ptr, gsize size, gsize count,
gsize *count_read, GError **err)
{
gsize tmp_count_read;
tmp_count_read = fread(ptr, size, count, in);
if (count_read)
*count_read = tmp_count_read;
if (ferror(in)) {
g_set_error(err, G_FILE_ERROR, 0, _("Failed to read file"));
return -1;
}
return 0;
}
gint file_write(FILE *out, const void *ptr, gsize size, gsize count,
gsize *count_written, GError **err)
{
gsize tmp_count_written;
tmp_count_written = fwrite(ptr, size, count, out);
if (count_written)
*count_written = tmp_count_written;
if (tmp_count_written != count || ferror(out)) {
g_set_error(err, G_FILE_ERROR, 0, _("Failed to write file"));
return -1;
}
return 0;
}
static gint file_seek(FILE *f, uint64_t offset, GError **err)
{
gint rc;
if (offset > LONG_MAX) {
g_set_error(err, PV_ERROR, 0, _("Offset is too large"));
return -1;
}
rc = fseek(f, (long)offset, SEEK_SET);
if (rc != 0) {
g_set_error(err, G_FILE_ERROR,
(gint)g_file_error_from_errno(errno),
_("Failed to seek: '%s'"), g_strerror(errno));
return -1;
}
return 0;
}
gint seek_and_write_file(FILE *o, const CompFile *ifile, uint64_t offset,
GError **err)
{
gsize bytes_read, bytes_written;
gsize total_bytes_read = 0;
FILE *i = NULL;
gchar buf[4096];
gint ret = -1;
if (file_seek(o, offset, err) < 0)
return -1;
i = file_open(ifile->path, "rb", err);
if (!i)
return -1;
do {
if (file_read(i, buf, 1, sizeof(buf), &bytes_read, err) < 0) {
g_prefix_error(err, _("Failed to read file '%s': "),
ifile->path);
goto err;
}
if (bytes_read == 0)
break;
total_bytes_read += bytes_read;
if (file_write(o, buf, bytes_read, 1, &bytes_written, err) < 0)
goto err;
} while (bytes_written != 0);
if (ifile->size != total_bytes_read) {
g_set_error(err, PV_ERROR, PV_ERROR_INTERNAL,
_("'%s' has changed during the preparation"),
ifile->path);
goto err;
}
ret = 0;
err:
fclose(i);
return ret;
}
gint seek_and_write_buffer(FILE *o, const Buffer *buf, uint64_t offset,
GError **err)
{
if (file_seek(o, offset, err) < 0)
return -1;
if (buffer_write(buf, o, err) < 0)
return -1;
return 0;
}
gint pad_file_right(const gchar *path_out, const gchar *path_in, gsize *size_out,
guint padding, GError **err)
{
FILE *f_in, *f_out = NULL;
guchar buf[padding];
gsize num_bytes_written;
gsize num_bytes_read;
uint64_t size_in = 0;
gint ret = -1;
*size_out = 0;
f_in = file_open(path_in, "rb", err);
if (!f_in)
goto err;
f_out = file_open(path_out, "wb", err);
if (!f_out)
goto err;
do {
memset(buf, 0, sizeof(buf));
if (file_read(f_in, buf, 1, sizeof(buf), &num_bytes_read, err) < 0) {
g_prefix_error(err, _("Failed to read file '%s': "),
path_in);
goto err;
}
size_in += num_bytes_read;
if (file_write(f_out, buf, 1, sizeof(buf), &num_bytes_written, err)) {
g_prefix_error(err, _("Failed to write file '%s': "),
path_out);
goto err;
}
*size_out += num_bytes_written;
} while (num_bytes_read == padding);
g_assert(num_bytes_written == ALIGN(num_bytes_read, padding));
ret = 0;
err:
if (f_out)
fclose(f_out);
if (f_in)
fclose(f_in);
return ret;
}

View File

@@ -0,0 +1,34 @@
/*
* General file utils
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#ifndef PV_FILE_UTILS_H
#define PV_FILE_UTILS_H
#include <glib.h>
#include <stdint.h>
#include <stdio.h>
#include "pv/pv_comp.h"
#include "buffer.h"
FILE *file_open(const gchar *filename, const gchar *mode, GError **err);
gint file_size(const gchar *filename, gsize *size, GError **err);
gint file_read(FILE *in, void *ptr, gsize size, gsize count,
gsize *count_read, GError **err);
gint file_write(FILE *out, const void *ptr, gsize size, gsize count,
gsize *count_written, GError **err);
gint pad_file_right(const gchar *path_out, const gchar *path_in,
gsize *size_out, guint padding, GError **err);
gint seek_and_write_buffer(FILE *out, const Buffer *buf, uint64_t offset,
GError **err);
gint seek_and_write_file(FILE *o, const CompFile *ifile, uint64_t offset,
GError **err);
#endif

View File

@@ -31,12 +31,13 @@ LDLIBS += $(FUSE_LDLIBS) -lpthread -lrt -ldl -lm
OBJECTS = hmcdrvfs.o
libs = $(rootdir)/libutil/libutil.a
all: check_dep hmcdrvfs
$(OBJECTS): Makefile
hmcdrvfs: $(OBJECTS)
hmcdrvfs: $(OBJECTS) $(libs)
install: all install-scripts
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 hmcdrvfs \

View File

@@ -27,6 +27,7 @@
#include <time.h>
#include <unistd.h>
#include "lib/util_libc.h"
#include "lib/zt_common.h"
#define HMCDRV_FUSE_LOGNAME "hmcdrvfs" /* log prefix */
@@ -276,7 +277,7 @@ static void hmcdrv_cache_symlink(struct hmcdrv_fuse_file *fp,
fp->symlnk = malloc(HMCDRV_FUSE_MAXPATH);
if (fp->symlnk != NULL) {
strncpy(fp->symlnk, symlink, HMCDRV_FUSE_MAXPATH);
util_strlcpy(fp->symlnk, symlink, HMCDRV_FUSE_MAXPATH);
fp->symlnk[HMCDRV_FUSE_MAXPATH - 1] = '\0';
}
}
@@ -483,8 +484,7 @@ static ssize_t hmcdrv_ftp_transfer(struct hmcdrv_fuse_file *fp, char *buf,
}
current_offset += retlen;
strncpy(last_ftpcmd, fp->ftpcmd, HMCDRV_FUSE_MAXCMDLEN);
last_ftpcmd[HMCDRV_FUSE_MAXCMDLEN - 1] = '\0';
util_strlcpy(last_ftpcmd, fp->ftpcmd, HMCDRV_FUSE_MAXCMDLEN);
return retlen;
}
@@ -853,13 +853,12 @@ static char *hmcdrv_parse_line(char *line, char *namebuf,
*arrow = '\0';
}
strncpy(namebuf, attr.fname, bufsize);
namebuf[bufsize - 1] = '\0'; /* safety */
util_strlcpy(namebuf, attr.fname, bufsize);
if (arrow == NULL) {
symlink[0] = '\0';
} else {
strncpy(symlink, arrow + 4, HMCDRV_FUSE_MAXPATH);
util_strlcpy(symlink, arrow + 4, HMCDRV_FUSE_MAXPATH);
*arrow = ' '; /* restore */
}
@@ -1148,8 +1147,7 @@ static int hmcdrv_fuse_readlink(const char *path, char *buf, size_t size)
if (!S_ISLNK(fp->st.st_mode)) {
rc = -EINVAL;
} else {
strncpy(buf, fp->symlnk, size);
buf[size - 1] = '\0';
util_strlcpy(buf, fp->symlnk, size);
}
}
}
@@ -1338,7 +1336,7 @@ static int hmcdrv_fuse_main(struct fuse_args *args)
*/
static void hmcdrv_fuse_usage(const char *progname)
{
fprintf(stderr,
fprintf(stdout,
"Usage: %s MOUNTPOINT [OPTIONS]\n\n"
"Use the %s command to read files from a HMC drive DVD.\n"
"\n"
@@ -1450,7 +1448,7 @@ static int hmcdrv_fuse_optproc(void *data, const char *arg,
return 1;
case HMCDRV_FUSE_OPTKEY_VERSION:
fprintf(stderr, HMCDRV_FUSE_LOGHEAD
fprintf(stdout, HMCDRV_FUSE_LOGHEAD
"HMC drive DVD file system, version %s\n"
"Copyright IBM Corp. 2015, 2017\n",
HMCDRV_FUSE_RELEASE);
@@ -1458,6 +1456,16 @@ static int hmcdrv_fuse_optproc(void *data, const char *arg,
case HMCDRV_FUSE_OPTKEY_HELP:
hmcdrv_fuse_usage(outargs->argv[0]);
/*
* Usage output needs to go to stdout to be consistent with
* coding guidelines. FUSE versions before 3.0.0 print help
* output to stderr. Redirect stderr to stdout here to enforce
* consistent behavior.
*/
fflush(stderr);
dup2(STDOUT_FILENO, STDERR_FILENO);
fuse_opt_add_arg(outargs, "-ho");
hmcdrv_fuse_main(outargs);
exit(EXIT_SUCCESS);

View File

@@ -55,8 +55,7 @@ struct l_x_sys_hdr {
static inline void l_sys_hdr__sys_name(struct l_x_sys_hdr *hdr, char *name)
{
memcpy(name, hdr->sys_name, LPAR_NAME_LEN);
ht_ebcdic_to_ascii(name, LPAR_NAME_LEN);
ht_ebcdic_to_ascii(hdr->sys_name, name, LPAR_NAME_LEN);
name[LPAR_NAME_LEN] = 0;
ht_strstrip(name);
}
@@ -176,7 +175,6 @@ static void l_sd_cpu_phys_fill(struct sd_sys *sys,
sd_cpu_state_set(cpu, SD_CPU_STATE_UNKNOWN);
}
sd_cpu_mgm_time_us_set(cpu, cpu_info->mgm_time);
sd_cpu_real_type_set(cpu, cpu_type);
sd_cpu_commit(cpu);
}

View File

@@ -245,8 +245,7 @@ static void l_sd_sys_root_fill(struct sd_sys *sys)
struct sd_sys *guest;
guest_name[NAME_LEN] = 0;
memcpy(guest_name, data->guest_name, NAME_LEN);
ht_ebcdic_to_ascii(guest_name, NAME_LEN);
ht_ebcdic_to_ascii(data->guest_name, guest_name, NAME_LEN);
ht_strstrip(guest_name);
guest = sd_sys_get(sys, guest_name);

View File

@@ -98,9 +98,15 @@ void *ht_realloc(void *old_ptr, size_t size)
/*
* Convert EBCDIC string to ASCII
*/
void ht_ebcdic_to_ascii(char *inout, size_t len)
void ht_ebcdic_to_ascii(char *in, char *out, size_t size)
{
iconv(l_iconv_ebcdic_ascii, &inout, &len, &inout, &len);
size_t size_out = size;
size_t size_in = size;
size_t rc;
rc = iconv(l_iconv_ebcdic_ascii, &in, &size_in, &out, &size_out);
if (rc == (size_t) -1)
ERR_EXIT_ERRNO("Code page translation EBCDIC-ASCII failed");
}
/*

View File

@@ -17,6 +17,7 @@
#include <sys/types.h>
#include "lib/util_base.h"
#include "lib/util_libc.h"
#include "lib/zt_common.h"
#define G0(x) MAX(0, (s64) (x))
@@ -29,7 +30,7 @@ extern char *ht_strstrip(char *str);
extern char *ht_strdup(const char *str);
extern void ht_print_head(const char *sys);
extern void ht_print_help_icon(void);
extern void ht_ebcdic_to_ascii(char *inout, size_t len);
extern void ht_ebcdic_to_ascii(char *in, char *out, size_t len);
extern char *ht_mount_point_get(const char *fs_type);
extern u64 ht_ext_tod_2_us(void *tod_ext);
extern void ht_print_time(void);

View File

@@ -195,7 +195,6 @@ struct sd_cpu {
struct sd_info i;
char id[9];
struct sd_cpu_type *type;
char real_type[CPU_TYPE_ID_LEN];
struct sd_cpu_info d1;
struct sd_cpu_info d2;
struct sd_cpu_info *d_cur;
@@ -228,11 +227,6 @@ static inline void sd_cpu_state_set(struct sd_cpu *cpu, enum sd_cpu_state state)
cpu->state = state;
}
static inline void sd_cpu_real_type_set(struct sd_cpu *cpu, const char *type)
{
strncpy(cpu->real_type, type, sizeof(cpu->real_type));
}
static inline void sd_cpu_cpu_time_us_set(struct sd_cpu *cpu, u64 value)
{
cpu->d_cur->cpu_time_us = value;

View File

@@ -219,7 +219,7 @@ struct sd_cpu *sd_cpu_new(struct sd_sys *parent, const char *id,
cpu = ht_zalloc(sizeof(*cpu));
cpu->i.parent = parent;
strncpy(cpu->id, id, sizeof(cpu->id));
util_strlcpy(cpu->id, id, sizeof(cpu->id));
cpu->type = l_cpu_type_by_id(type);
cpu->d_cur = &cpu->d1;
cpu->cnt = cnt;
@@ -251,7 +251,7 @@ struct sd_sys *sd_sys_new(struct sd_sys *parent, const char *id)
struct sd_sys *sys_new;
sys_new = ht_zalloc(sizeof(*sys_new));
strncpy(sys_new->id, id, sizeof(sys_new->id));
util_strlcpy(sys_new->id, id, sizeof(sys_new->id));
util_list_init(&sys_new->child_list, struct sd_sys, list);
util_list_init(&sys_new->cpu_list, struct sd_cpu, list);

View File

@@ -47,7 +47,7 @@ static void l_mark_key_add(struct table *t, char *str)
struct table_mark_key *key;
key = ht_zalloc(sizeof(*key));
strncpy(key->str, str, sizeof(key->str));
util_strlcpy(key->str, str, sizeof(key->str));
util_list_add_tail(&t->mark_key_list, key);
}
@@ -617,7 +617,7 @@ void table_row_select_key_get(struct table *t, char str[TABLE_STR_MAX])
struct table_row *row;
row = l_selected_row(t);
strncpy(str, row->entries[0].str, TABLE_STR_MAX);
util_strlcpy(str, row->entries[0].str, TABLE_STR_MAX);
}
/*

View File

@@ -157,7 +157,7 @@ static void l_print_line(const char *line)
char line_cpy[TBOX_MAX_STR + 1];
char *ptr_old, *ptr;
strncpy(line_cpy, line, sizeof(line_cpy));
util_strlcpy(line_cpy, line, sizeof(line_cpy));
ptr_old = ptr = line_cpy;
do {
ptr = strchr(ptr, '\\');

Some files were not shown because too many files have changed in this diff Show More