• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

systemd / systemd / 19381060735

14 Nov 2025 10:54PM UTC coverage: 72.37% (-0.02%) from 72.393%
19381060735

push

github

web-flow
5 TPM tweaks (#39712)

Fixes: #38939
Fixes: #39150

60 of 78 new or added lines in 3 files covered. (76.92%)

2631 existing lines in 50 files now uncovered.

307287 of 424606 relevant lines covered (72.37%)

1234902.43 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

62.5
/src/integritysetup/integritysetup.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include <stdio.h>
4
#include <sys/stat.h>
5

6
#include "alloc-util.h"
7
#include "argv-util.h"
8
#include "cryptsetup-util.h"
9
#include "fileio.h"
10
#include "integrity-util.h"
11
#include "log.h"
12
#include "main-func.h"
13
#include "path-util.h"
14
#include "pretty-print.h"
15
#include "string-util.h"
16
#include "time-util.h"
17
#include "verbs.h"
18

19
static uint32_t arg_activate_flags;
20
static int arg_percent;
21
static usec_t arg_commit_time;
22
static char *arg_existing_data_device;
23
static char *arg_integrity_algorithm;
24

25
STATIC_DESTRUCTOR_REGISTER(arg_existing_data_device, freep);
20✔
26
STATIC_DESTRUCTOR_REGISTER(arg_integrity_algorithm, freep);
20✔
27

28
static int help(void) {
×
29
        _cleanup_free_ char *link = NULL;
×
30
        int r;
×
31

32
        r = terminal_urlify_man("systemd-integritysetup@.service", "8", &link);
×
33
        if (r < 0)
×
34
                return log_oom();
×
35

36
        printf("%s attach VOLUME DEVICE [HMAC_KEY_FILE|-] [OPTIONS]\n"
×
37
               "%s detach VOLUME\n\n"
38
               "Attach or detach an integrity protected block device.\n"
39
               "\nSee the %s for details.\n",
40
               program_invocation_short_name,
41
               program_invocation_short_name,
42
               link);
43

44
        return 0;
45
}
46

47
static int load_key_file(
×
48
                const char *key_file,
49
                void **ret_key_file_contents,
50
                size_t *ret_key_file_size) {
51
        int r;
×
52
        _cleanup_(erase_and_freep) char *tmp_key_file_contents = NULL;
×
53
        size_t tmp_key_file_size;
×
54

55
        if (!path_is_absolute(key_file))
×
56
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "key file not absolute path: %s", key_file);
×
57

58
        r = read_full_file_full(
×
59
                        AT_FDCWD, key_file, UINT64_MAX, DM_MAX_KEY_SIZE,
60
                        READ_FULL_FILE_SECURE|READ_FULL_FILE_WARN_WORLD_READABLE|READ_FULL_FILE_CONNECT_SOCKET|READ_FULL_FILE_FAIL_WHEN_LARGER,
61
                        NULL,
62
                        &tmp_key_file_contents, &tmp_key_file_size);
63
        if (r < 0)
×
64
                return log_error_errno(r, "Failed to process key file: %m");
×
65

66
        if (ret_key_file_contents && ret_key_file_size) {
×
67
                *ret_key_file_contents = TAKE_PTR(tmp_key_file_contents);
×
68
                *ret_key_file_size = tmp_key_file_size;
×
69
        }
70

71
        return 0;
72
}
73

74
static const char *integrity_algorithm_select(const void *key_file_buf) {
10✔
75
        /*  To keep a bit of sanity for end users, the subset of integrity
76
            algorithms we support will match what is used in integritysetup */
77
        if (arg_integrity_algorithm) {
10✔
78
                if (streq("hmac-sha256", arg_integrity_algorithm))
10✔
79
                        return DM_HMAC_256;
80
                if (streq("hmac-sha512", arg_integrity_algorithm))
10✔
81
                        return DM_HMAC_512;
82
                if (streq("phmac-sha256", arg_integrity_algorithm))
10✔
83
                        return DM_PHMAC_256;
84
                if (streq("phmac-sha512", arg_integrity_algorithm))
10✔
85
                        return DM_PHMAC_512;
86
                return arg_integrity_algorithm;
10✔
UNCOV
87
        } else if (key_file_buf)
×
UNCOV
88
                return DM_HMAC_256;
×
89
        return "crc32c";
90
}
91

92
static int verb_attach(int argc, char *argv[], void *userdata) {
10✔
93
        _cleanup_(crypt_freep) struct crypt_device *cd = NULL;
10✔
94
        crypt_status_info status;
10✔
95
        _cleanup_(erase_and_freep) void *key_buf = NULL;
10✔
96
        size_t key_buf_size = 0;
10✔
97
        int r;
10✔
98

99
        /* attach name device optional_key_file optional_options */
100

101
        assert(argc >= 3 && argc <= 5);
10✔
102

103
        const char *volume = argv[1],
10✔
104
                *device = argv[2],
10✔
105
                *key_file = mangle_none(argc > 3 ? argv[3] : NULL),
10✔
106
                *options = mangle_none(argc > 4 ? argv[4] : NULL);
10✔
107

108
        if (!filename_is_valid(volume))
10✔
UNCOV
109
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Volume name '%s' is not valid.", volume);
×
110

111
        if (key_file) {
10✔
UNCOV
112
                r = load_key_file(key_file, &key_buf, &key_buf_size);
×
UNCOV
113
                if (r < 0)
×
114
                        return r;
115
        }
116

117
        if (options) {
10✔
118
                r = parse_integrity_options(options, &arg_activate_flags, &arg_percent,
10✔
119
                                            &arg_commit_time, &arg_existing_data_device, &arg_integrity_algorithm);
120
                if (r < 0)
10✔
121
                        return r;
122
        }
123

124
        r = crypt_init(&cd, device);
10✔
125
        if (r < 0)
10✔
126
                return log_error_errno(r, "Failed to open integrity device %s: %m", device);
×
127

128
        cryptsetup_enable_logging(cd);
10✔
129

130
        status = crypt_status(cd, volume);
10✔
131
        if (IN_SET(status, CRYPT_ACTIVE, CRYPT_BUSY)) {
10✔
UNCOV
132
                log_info("Volume %s already active.", volume);
×
UNCOV
133
                return 0;
×
134
        }
135

136
        r = crypt_load(cd,
20✔
137
                       CRYPT_INTEGRITY,
138
                       &(struct crypt_params_integrity) {
10✔
139
                               .journal_watermark = arg_percent,
140
                               .journal_commit_time = DIV_ROUND_UP(arg_commit_time, USEC_PER_SEC),
10✔
141
                               .integrity = integrity_algorithm_select(key_buf),
10✔
142
                       });
143
        if (r < 0)
10✔
UNCOV
144
                return log_error_errno(r, "Failed to load integrity superblock: %m");
×
145

146
        if (!isempty(arg_existing_data_device)) {
10✔
147
                r = crypt_set_data_device(cd, arg_existing_data_device);
5✔
148
                if (r < 0)
5✔
UNCOV
149
                        return log_error_errno(r, "Failed to add separate data device: %m");
×
150
        }
151

152
        r = crypt_activate_by_volume_key(cd, volume, key_buf, key_buf_size, arg_activate_flags);
10✔
153
        if (r < 0)
10✔
UNCOV
154
                return log_error_errno(r, "Failed to set up integrity device: %m");
×
155

156
        return 0;
157
}
158

159
static int verb_detach(int argc, char *argv[], void *userdata) {
10✔
160
        _cleanup_(crypt_freep) struct crypt_device *cd = NULL;
10✔
161
        int r;
10✔
162

163
        assert(argc == 2);
10✔
164

165
        const char *volume = argv[1];
10✔
166

167
        if (!filename_is_valid(volume))
10✔
UNCOV
168
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Volume name '%s' is not valid.", volume);
×
169

170
        r = crypt_init_by_name(&cd, volume);
10✔
171
        if (r == -ENODEV) {
10✔
UNCOV
172
                log_info("Volume %s already inactive.", volume);
×
UNCOV
173
                return 0;
×
174
        }
175
        if (r < 0)
10✔
176
                return log_error_errno(r, "crypt_init_by_name() failed: %m");
×
177

178
        cryptsetup_enable_logging(cd);
10✔
179

180
        r = crypt_deactivate(cd, volume);
10✔
181
        if (r < 0)
10✔
UNCOV
182
                return log_error_errno(r, "Failed to deactivate: %m");
×
183

184
        return 0;
185
}
186

187
static int run(int argc, char *argv[]) {
20✔
188
        if (argv_looks_like_help(argc, argv))
20✔
UNCOV
189
                return help();
×
190

191
        log_setup();
20✔
192

193
        cryptsetup_enable_logging(NULL);
20✔
194

195
        umask(0022);
20✔
196

197
        static const Verb verbs[] = {
20✔
198
                { "attach", 3, 5, 0, verb_attach },
199
                { "detach", 2, 2, 0, verb_detach },
200
                {}
201
        };
202

203
        return dispatch_verb(argc, argv, verbs, NULL);
20✔
204
}
205

206
DEFINE_MAIN_FUNCTION(run);
20✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc