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

systemd / systemd / 14872145375

06 May 2025 09:07PM UTC coverage: 72.232% (+0.02%) from 72.214%
14872145375

push

github

DaanDeMeyer
string-table: annotate _to_string and _from_string with _const_ and _pure_, respectively

Follow-up for c94f6ab1b

297286 of 411572 relevant lines covered (72.23%)

695615.99 hits per line

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

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

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

7
#include "alloc-util.h"
8
#include "argv-util.h"
9
#include "cryptsetup-util.h"
10
#include "fileio.h"
11
#include "hexdecoct.h"
12
#include "integrity-util.h"
13
#include "log.h"
14
#include "main-func.h"
15
#include "memory-util.h"
16
#include "parse-util.h"
17
#include "path-util.h"
18
#include "pretty-print.h"
19
#include "process-util.h"
20
#include "string-util.h"
21
#include "terminal-util.h"
22
#include "verbs.h"
23

24
static uint32_t arg_activate_flags;
25
static int arg_percent;
26
static usec_t arg_commit_time;
27
static char *arg_existing_data_device;
28
static char *arg_integrity_algorithm;
29

30
STATIC_DESTRUCTOR_REGISTER(arg_existing_data_device, freep);
20✔
31
STATIC_DESTRUCTOR_REGISTER(arg_integrity_algorithm, freep);
20✔
32

33
static int help(void) {
×
34
        _cleanup_free_ char *link = NULL;
×
35
        int r;
×
36

37
        r = terminal_urlify_man("systemd-integritysetup@.service", "8", &link);
×
38
        if (r < 0)
×
39
                return log_oom();
×
40

41
        printf("%s attach VOLUME DEVICE [HMAC_KEY_FILE|-] [OPTIONS]\n"
×
42
               "%s detach VOLUME\n\n"
43
               "Attach or detach an integrity protected block device.\n"
44
               "\nSee the %s for details.\n",
45
               program_invocation_short_name,
46
               program_invocation_short_name,
47
               link);
48

49
        return 0;
50
}
51

52
static int load_key_file(
×
53
                const char *key_file,
54
                void **ret_key_file_contents,
55
                size_t *ret_key_file_size) {
56
        int r;
×
57
        _cleanup_(erase_and_freep) char *tmp_key_file_contents = NULL;
×
58
        size_t tmp_key_file_size;
×
59

60
        if (!path_is_absolute(key_file))
×
61
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "key file not absolute path: %s", key_file);
×
62

63
        r = read_full_file_full(
×
64
                        AT_FDCWD, key_file, UINT64_MAX, DM_MAX_KEY_SIZE,
65
                        READ_FULL_FILE_SECURE|READ_FULL_FILE_WARN_WORLD_READABLE|READ_FULL_FILE_CONNECT_SOCKET|READ_FULL_FILE_FAIL_WHEN_LARGER,
66
                        NULL,
67
                        &tmp_key_file_contents, &tmp_key_file_size);
68
        if (r < 0)
×
69
                return log_error_errno(r, "Failed to process key file: %m");
×
70

71
        if (ret_key_file_contents && ret_key_file_size) {
×
72
                *ret_key_file_contents = TAKE_PTR(tmp_key_file_contents);
×
73
                *ret_key_file_size = tmp_key_file_size;
×
74
        }
75

76
        return 0;
77
}
78

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

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

98
        /* attach name device optional_key_file optional_options */
99

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

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

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

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

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

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

127
        cryptsetup_enable_logging(cd);
10✔
128

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

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

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

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

155
        return 0;
156
}
157

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

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

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

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

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

177
        cryptsetup_enable_logging(cd);
10✔
178

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

183
        return 0;
184
}
185

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

190
        log_setup();
20✔
191

192
        cryptsetup_enable_logging(NULL);
20✔
193

194
        umask(0022);
20✔
195

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

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

205
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