mirror of
https://github.com/systemd/systemd
synced 2024-10-04 15:21:01 +00:00
Merge pull request #32810 from poettering/smbios11-analyze
analyze: add new verb "smbios11" for listing passed smbios type #11 strings
This commit is contained in:
commit
df51530709
2
TODO
2
TODO
|
@ -179,8 +179,6 @@ Features:
|
|||
* insert the new pidfs inode number as a third field into PidRef, so that
|
||||
PidRef are reasonably serializable without having to pass around fds.
|
||||
|
||||
* systemd-analyze smbios11 to dump smbios type 11 vendor strings
|
||||
|
||||
* move documentation about our common env vars (SYSTEMD_LOG_LEVEL,
|
||||
SYSTEMD_PAGER, …) into a man page of its own, and just link it from our
|
||||
various man pages that so far embed the whole list again and again, in an
|
||||
|
|
|
@ -186,6 +186,11 @@
|
|||
<arg choice="plain">architectures</arg>
|
||||
<arg choice="opt" rep="repeat"><replaceable>NAME</replaceable></arg>
|
||||
</cmdsynopsis>
|
||||
<cmdsynopsis>
|
||||
<command>systemd-analyze</command>
|
||||
<arg choice="opt" rep="repeat">OPTIONS</arg>
|
||||
<arg choice="plain">smbios11</arg>
|
||||
</cmdsynopsis>
|
||||
</refsynopsisdiv>
|
||||
|
||||
<refsect1>
|
||||
|
@ -979,6 +984,26 @@ x86-64 native</programlisting>
|
|||
</example>
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<title><command>systemd-analyze smbios11</command></title>
|
||||
|
||||
<para>Shows a list of SMBIOS Type #11 strings passed to the system. Also see
|
||||
<citerefentry><refentrytitle>smbios-type-11</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
|
||||
|
||||
<example>
|
||||
<title>Example output</title>
|
||||
<programlisting>$ systemd-analyze smbios11
|
||||
io.systemd.stub.kernel-cmdline-extra=console=ttyS0
|
||||
io.systemd.credential.binary:ssh.ephemeral-authorized_keys-all=c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSURGd20xbFp4WlRGclJteG9ZQlozOTYzcE1uYlJCaDMwM1MxVXhLSUM2NmYgbGVubmFydEB6ZXRhCg==
|
||||
io.systemd.credential:vmm.notify_socket=vsock-stream:2:254570042
|
||||
|
||||
3 SMBIOS Type #11 strings passed.
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v257"/>
|
||||
</refsect2>
|
||||
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
|
|
73
src/analyze/analyze-smbios11.c
Normal file
73
src/analyze/analyze-smbios11.c
Normal file
|
@ -0,0 +1,73 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "analyze.h"
|
||||
#include "analyze-smbios11.h"
|
||||
#include "escape.h"
|
||||
#include "smbios11.h"
|
||||
#include "virt.h"
|
||||
|
||||
int verb_smbios11(int argc, char *argv[], void *userdata) {
|
||||
unsigned n = 0;
|
||||
int r;
|
||||
|
||||
for (unsigned i = 0;; i++) {
|
||||
_cleanup_free_ char *data = NULL;
|
||||
bool written = false;
|
||||
size_t size;
|
||||
|
||||
r = read_smbios11_field(i, SIZE_MAX, &data, &size);
|
||||
if (r == -ENOENT) /* Reached the end */
|
||||
break;
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to read SMBIOS Type #11 string %u: %m", i);
|
||||
bool incomplete = r == 0;
|
||||
|
||||
size_t left, skip;
|
||||
const char *p;
|
||||
for (p = data, left = size; left > 0; p += skip, left -= skip) {
|
||||
const char *nul;
|
||||
|
||||
nul = memchr(p, 0, left);
|
||||
if (nul)
|
||||
skip = (nul - p) + 1;
|
||||
else {
|
||||
nul = p + left;
|
||||
skip = left;
|
||||
}
|
||||
|
||||
if (nul - p == 0) /* Skip empty strings */
|
||||
continue;
|
||||
|
||||
_cleanup_free_ char *escaped = NULL;
|
||||
escaped = cescape_length(p, nul - p);
|
||||
if (!escaped)
|
||||
return log_oom();
|
||||
|
||||
if (written)
|
||||
fputc('\n', stdout);
|
||||
|
||||
fputs(escaped, stdout);
|
||||
written = true;
|
||||
n++;
|
||||
}
|
||||
|
||||
if (written) {
|
||||
if (incomplete)
|
||||
fputs(special_glyph(SPECIAL_GLYPH_ELLIPSIS), stdout);
|
||||
|
||||
fputc('\n', stdout);
|
||||
}
|
||||
|
||||
if (i == UINT_MAX) /* Prevent overflow */
|
||||
break;
|
||||
}
|
||||
|
||||
if (!arg_quiet) {
|
||||
if (n == 0)
|
||||
log_info("No SMBIOS Type #11 strings passed.");
|
||||
else
|
||||
log_info("\n%u SMBIOS Type #11 strings passed.", n);
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
4
src/analyze/analyze-smbios11.h
Normal file
4
src/analyze/analyze-smbios11.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
int verb_smbios11(int argc, char *argv[], void *userdata);
|
|
@ -34,6 +34,7 @@
|
|||
#include "analyze-plot.h"
|
||||
#include "analyze-security.h"
|
||||
#include "analyze-service-watchdogs.h"
|
||||
#include "analyze-smbios11.h"
|
||||
#include "analyze-srk.h"
|
||||
#include "analyze-syscall-filter.h"
|
||||
#include "analyze-time.h"
|
||||
|
@ -241,6 +242,7 @@ static int help(int argc, char *argv[], void *userdata) {
|
|||
" image-policy POLICY... Analyze image policy string\n"
|
||||
" pcrs [PCR...] Show TPM2 PCRs and their names\n"
|
||||
" srk [>FILE] Write TPM2 SRK (to FILE)\n"
|
||||
" smbios11 List strings passed via SMBIOS Type #11\n"
|
||||
"\nOptions:\n"
|
||||
" --recursive-errors=MODE Control which units are verified\n"
|
||||
" --offline=BOOL Perform a security review on unit file(s)\n"
|
||||
|
@ -657,6 +659,7 @@ static int run(int argc, char *argv[]) {
|
|||
{ "pcrs", VERB_ANY, VERB_ANY, 0, verb_pcrs },
|
||||
{ "srk", VERB_ANY, 1, 0, verb_srk },
|
||||
{ "architectures", VERB_ANY, VERB_ANY, 0, verb_architectures },
|
||||
{ "smbios11", VERB_ANY, 1, 0, verb_smbios11 },
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ systemd_analyze_sources = files(
|
|||
'analyze-plot.c',
|
||||
'analyze-security.c',
|
||||
'analyze-service-watchdogs.c',
|
||||
'analyze-smbios11.c',
|
||||
'analyze-srk.c',
|
||||
'analyze-syscall-filter.c',
|
||||
'analyze-time.c',
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "path-util.h"
|
||||
#include "proc-cmdline.h"
|
||||
#include "recurse-dir.h"
|
||||
#include "smbios11.h"
|
||||
#include "strv.h"
|
||||
#include "virt.h"
|
||||
|
||||
|
@ -578,38 +579,17 @@ static int import_credentials_smbios(ImportCredentialContext *c) {
|
|||
return 0;
|
||||
|
||||
for (unsigned i = 0;; i++) {
|
||||
struct dmi_field_header {
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
uint16_t handle;
|
||||
uint8_t count;
|
||||
char contents[];
|
||||
} _packed_ *dmi_field_header;
|
||||
_cleanup_free_ char *p = NULL;
|
||||
_cleanup_free_ void *data = NULL;
|
||||
_cleanup_free_ char *data = NULL;
|
||||
size_t size;
|
||||
|
||||
assert_cc(offsetof(struct dmi_field_header, contents) == 5);
|
||||
|
||||
if (asprintf(&p, "/sys/firmware/dmi/entries/11-%u/raw", i) < 0)
|
||||
return log_oom();
|
||||
|
||||
r = read_virtual_file(p, sizeof(dmi_field_header) + CREDENTIALS_TOTAL_SIZE_MAX, (char**) &data, &size);
|
||||
r = read_smbios11_field(i, CREDENTIALS_TOTAL_SIZE_MAX, &data, &size);
|
||||
if (r < 0) {
|
||||
/* Once we reach ENOENT there are no more DMI Type 11 fields around. */
|
||||
log_full_errno(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, r, "Failed to open '%s', ignoring: %m", p);
|
||||
log_full_errno(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, r, "Failed to read SMBIOS type #11 object %u, ignoring: %m", i);
|
||||
break;
|
||||
}
|
||||
|
||||
if (size < offsetof(struct dmi_field_header, contents))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "DMI field header of '%s' too short.", p);
|
||||
|
||||
dmi_field_header = data;
|
||||
if (dmi_field_header->type != 11 ||
|
||||
dmi_field_header->length != offsetof(struct dmi_field_header, contents))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "Invalid DMI field header.");
|
||||
|
||||
r = parse_smbios_strings(c, dmi_field_header->contents, size - offsetof(struct dmi_field_header, contents));
|
||||
r = parse_smbios_strings(c, data, size);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
|
|
@ -157,6 +157,7 @@ shared_sources = files(
|
|||
'service-util.c',
|
||||
'sleep-config.c',
|
||||
'smack-util.c',
|
||||
'smbios11.c',
|
||||
'socket-label.c',
|
||||
'socket-netlink.c',
|
||||
'spawn-ask-password-agent.c',
|
||||
|
|
61
src/shared/smbios11.c
Normal file
61
src/shared/smbios11.c
Normal file
|
@ -0,0 +1,61 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "fileio.h"
|
||||
#include "macro.h"
|
||||
#include "smbios11.h"
|
||||
#include "virt.h"
|
||||
|
||||
int read_smbios11_field(unsigned i, size_t max_size, char **ret_data, size_t *ret_size) {
|
||||
_cleanup_free_ char *p = NULL, *contents = NULL;
|
||||
_cleanup_free_ void *data = NULL;
|
||||
size_t size, contents_size;
|
||||
int r;
|
||||
|
||||
assert(ret_data);
|
||||
assert(ret_size);
|
||||
|
||||
/* Parses DMI OEM strings fields (SMBIOS type 11), as settable with qemu's -smbios type=11,value=… switch. */
|
||||
|
||||
if (detect_container() > 0) /* don't access /sys/ in a container */
|
||||
return -ENOENT;
|
||||
|
||||
if (asprintf(&p, "/sys/firmware/dmi/entries/11-%u/raw", i) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
struct dmi_field_header {
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
uint16_t handle;
|
||||
uint8_t count;
|
||||
char contents[];
|
||||
} _packed_ *dmi_field_header;
|
||||
|
||||
assert_cc(offsetof(struct dmi_field_header, contents) == 5);
|
||||
|
||||
r = read_virtual_file(
|
||||
p,
|
||||
max_size >= SIZE_MAX - offsetof(struct dmi_field_header, contents) ? SIZE_MAX :
|
||||
sizeof(dmi_field_header) + max_size,
|
||||
(char**) &data, &size);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (size < offsetof(struct dmi_field_header, contents))
|
||||
return -EBADMSG;
|
||||
|
||||
dmi_field_header = data;
|
||||
if (dmi_field_header->type != 11 ||
|
||||
dmi_field_header->length != offsetof(struct dmi_field_header, contents))
|
||||
return -EBADMSG;
|
||||
|
||||
contents_size = size - offsetof(struct dmi_field_header, contents);
|
||||
contents = memdup_suffix0(dmi_field_header->contents, contents_size);
|
||||
if (!contents)
|
||||
return -ENOMEM;
|
||||
|
||||
*ret_data = TAKE_PTR(contents);
|
||||
*ret_size = contents_size;
|
||||
|
||||
return r; /* NB! read_virtual_file() returns 0 on incomplete reads, and 1 in complete reads */
|
||||
}
|
6
src/shared/smbios11.h
Normal file
6
src/shared/smbios11.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
int read_smbios11_field(unsigned i, size_t max_size, char **ret_data, size_t *ret_size);
|
|
@ -947,6 +947,9 @@ systemd-analyze architectures x86-64
|
|||
systemd-analyze architectures native
|
||||
systemd-analyze architectures uname
|
||||
|
||||
systemd-analyze smbios11
|
||||
systemd-analyze smbios11 -q
|
||||
|
||||
systemd-analyze log-level info
|
||||
|
||||
touch /testok
|
||||
|
|
Loading…
Reference in a new issue