File: | build-scan/../src/random-seed/random-seed.c |
Warning: | line 60, column 17 Potential leak of memory pointed to by 'buf' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* SPDX-License-Identifier: LGPL-2.1+ */ | |||
2 | ||||
3 | #include <errno(*__errno_location ()).h> | |||
4 | #include <fcntl.h> | |||
5 | #include <string.h> | |||
6 | #include <sys/stat.h> | |||
7 | #include <unistd.h> | |||
8 | ||||
9 | #include "alloc-util.h" | |||
10 | #include "fd-util.h" | |||
11 | #include "io-util.h" | |||
12 | #include "log.h" | |||
13 | #include "mkdir.h" | |||
14 | #include "string-util.h" | |||
15 | #include "util.h" | |||
16 | ||||
17 | #define POOL_SIZE_MIN1024 1024 | |||
18 | ||||
19 | int main(int argc, char *argv[]) { | |||
20 | _cleanup_close___attribute__((cleanup(closep))) int seed_fd = -1, random_fd = -1; | |||
21 | _cleanup_free___attribute__((cleanup(freep))) void* buf = NULL((void*)0); | |||
22 | size_t buf_size = 0; | |||
23 | ssize_t k; | |||
24 | int r, open_rw_error; | |||
25 | FILE *f; | |||
26 | bool_Bool refresh_seed_file = true1; | |||
27 | ||||
28 | if (argc != 2) { | |||
| ||||
29 | log_error("This program requires one argument.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/random-seed/random-seed.c", 29, __func__, "This program requires one argument." ) : -abs(_e); }); | |||
30 | return EXIT_FAILURE1; | |||
31 | } | |||
32 | ||||
33 | log_set_target(LOG_TARGET_AUTO); | |||
34 | log_parse_environment()log_parse_environment_realm(LOG_REALM_SYSTEMD); | |||
35 | log_open(); | |||
36 | ||||
37 | umask(0022); | |||
38 | ||||
39 | /* Read pool size, if possible */ | |||
40 | f = fopen("/proc/sys/kernel/random/poolsize", "re"); | |||
41 | if (f) { | |||
42 | if (fscanf(f, "%zu", &buf_size) > 0) | |||
43 | /* poolsize is in bits on 2.6, but we want bytes */ | |||
44 | buf_size /= 8; | |||
45 | ||||
46 | fclose(f); | |||
47 | } | |||
48 | ||||
49 | if (buf_size
| |||
50 | buf_size = POOL_SIZE_MIN1024; | |||
51 | ||||
52 | buf = malloc(buf_size); | |||
53 | if (!buf) { | |||
54 | r = log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/random-seed/random-seed.c" , 54, __func__); | |||
55 | goto finish; | |||
56 | } | |||
57 | ||||
58 | r = mkdir_parents_label(RANDOM_SEED"/var/lib/systemd/random-seed", 0755); | |||
59 | if (r < 0) { | |||
60 | log_error_errno(r, "Failed to create directory " RANDOM_SEED_DIR ": %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/random-seed/random-seed.c", 60, __func__, "Failed to create directory " "/var/lib/systemd" ": %m") : -abs(_e); }); | |||
| ||||
61 | goto finish; | |||
62 | } | |||
63 | ||||
64 | /* When we load the seed we read it and write it to the device | |||
65 | * and then immediately update the saved seed with new data, | |||
66 | * to make sure the next boot gets seeded differently. */ | |||
67 | ||||
68 | if (streq(argv[1], "load")(strcmp((argv[1]),("load")) == 0)) { | |||
69 | ||||
70 | seed_fd = open(RANDOM_SEED"/var/lib/systemd/random-seed", O_RDWR02|O_CLOEXEC02000000|O_NOCTTY0400|O_CREAT0100, 0600); | |||
71 | open_rw_error = -errno(*__errno_location ()); | |||
72 | if (seed_fd < 0) { | |||
73 | refresh_seed_file = false0; | |||
74 | ||||
75 | seed_fd = open(RANDOM_SEED"/var/lib/systemd/random-seed", O_RDONLY00|O_CLOEXEC02000000|O_NOCTTY0400); | |||
76 | if (seed_fd < 0) { | |||
77 | bool_Bool missing = errno(*__errno_location ()) == ENOENT2; | |||
78 | ||||
79 | log_full_errno(missing ? LOG_DEBUG : LOG_ERR,({ int _level = ((missing ? 7 : 3)), _e = ((open_rw_error)), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/random-seed/random-seed.c", 80, __func__ , "Failed to open " "/var/lib/systemd/random-seed" " for writing: %m" ) : -abs(_e); }) | |||
80 | open_rw_error, "Failed to open " RANDOM_SEED " for writing: %m")({ int _level = ((missing ? 7 : 3)), _e = ((open_rw_error)), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/random-seed/random-seed.c", 80, __func__ , "Failed to open " "/var/lib/systemd/random-seed" " for writing: %m" ) : -abs(_e); }); | |||
81 | r = log_full_errno(missing ? LOG_DEBUG : LOG_ERR,({ int _level = ((missing ? 7 : 3)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm (_realm) >= ((_level) & 0x07)) ? log_internal_realm((( _realm) << 10 | (_level)), _e, "../src/random-seed/random-seed.c" , 82, __func__, "Failed to open " "/var/lib/systemd/random-seed" " for reading: %m") : -abs(_e); }) | |||
82 | errno, "Failed to open " RANDOM_SEED " for reading: %m")({ int _level = ((missing ? 7 : 3)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm (_realm) >= ((_level) & 0x07)) ? log_internal_realm((( _realm) << 10 | (_level)), _e, "../src/random-seed/random-seed.c" , 82, __func__, "Failed to open " "/var/lib/systemd/random-seed" " for reading: %m") : -abs(_e); }); | |||
83 | if (missing) | |||
84 | r = 0; | |||
85 | ||||
86 | goto finish; | |||
87 | } | |||
88 | } | |||
89 | ||||
90 | random_fd = open("/dev/urandom", O_RDWR02|O_CLOEXEC02000000|O_NOCTTY0400, 0600); | |||
91 | if (random_fd < 0) { | |||
92 | random_fd = open("/dev/urandom", O_WRONLY01|O_CLOEXEC02000000|O_NOCTTY0400, 0600); | |||
93 | if (random_fd < 0) { | |||
94 | r = log_error_errno(errno, "Failed to open /dev/urandom: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/random-seed/random-seed.c", 94, __func__ , "Failed to open /dev/urandom: %m") : -abs(_e); }); | |||
95 | goto finish; | |||
96 | } | |||
97 | } | |||
98 | ||||
99 | k = loop_read(seed_fd, buf, buf_size, false0); | |||
100 | if (k < 0) | |||
101 | r = log_error_errno(k, "Failed to read seed from " RANDOM_SEED ": %m")({ int _level = ((3)), _e = ((k)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/random-seed/random-seed.c", 101, __func__, "Failed to read seed from " "/var/lib/systemd/random-seed" ": %m") : -abs(_e); }); | |||
102 | else if (k == 0) { | |||
103 | r = 0; | |||
104 | log_debug("Seed file " RANDOM_SEED " not yet initialized, proceeding.")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/random-seed/random-seed.c", 104, __func__, "Seed file " "/var/lib/systemd/random-seed" " not yet initialized, proceeding." ) : -abs(_e); }); | |||
105 | } else { | |||
106 | (void) lseek(seed_fd, 0, SEEK_SET0); | |||
107 | ||||
108 | r = loop_write(random_fd, buf, (size_t) k, false0); | |||
109 | if (r < 0) | |||
110 | log_error_errno(r, "Failed to write seed to /dev/urandom: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/random-seed/random-seed.c", 110, __func__, "Failed to write seed to /dev/urandom: %m" ) : -abs(_e); }); | |||
111 | } | |||
112 | ||||
113 | } else if (streq(argv[1], "save")(strcmp((argv[1]),("save")) == 0)) { | |||
114 | ||||
115 | seed_fd = open(RANDOM_SEED"/var/lib/systemd/random-seed", O_WRONLY01|O_CLOEXEC02000000|O_NOCTTY0400|O_CREAT0100, 0600); | |||
116 | if (seed_fd < 0) { | |||
117 | r = log_error_errno(errno, "Failed to open " RANDOM_SEED ": %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/random-seed/random-seed.c", 117, __func__, "Failed to open " "/var/lib/systemd/random-seed" ": %m" ) : -abs(_e); }); | |||
118 | goto finish; | |||
119 | } | |||
120 | ||||
121 | random_fd = open("/dev/urandom", O_RDONLY00|O_CLOEXEC02000000|O_NOCTTY0400); | |||
122 | if (random_fd < 0) { | |||
123 | r = log_error_errno(errno, "Failed to open /dev/urandom: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/random-seed/random-seed.c", 123, __func__, "Failed to open /dev/urandom: %m") : -abs(_e); }); | |||
124 | goto finish; | |||
125 | } | |||
126 | ||||
127 | } else { | |||
128 | log_error("Unknown verb '%s'.", argv[1])({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/random-seed/random-seed.c", 128, __func__, "Unknown verb '%s'." , argv[1]) : -abs(_e); }); | |||
129 | r = -EINVAL22; | |||
130 | goto finish; | |||
131 | } | |||
132 | ||||
133 | if (refresh_seed_file) { | |||
134 | ||||
135 | /* This is just a safety measure. Given that we are root and | |||
136 | * most likely created the file ourselves the mode and owner | |||
137 | * should be correct anyway. */ | |||
138 | (void) fchmod(seed_fd, 0600); | |||
139 | (void) fchown(seed_fd, 0, 0); | |||
140 | ||||
141 | k = loop_read(random_fd, buf, buf_size, false0); | |||
142 | if (k < 0) { | |||
143 | r = log_error_errno(k, "Failed to read new seed from /dev/urandom: %m")({ int _level = ((3)), _e = ((k)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/random-seed/random-seed.c", 143, __func__, "Failed to read new seed from /dev/urandom: %m" ) : -abs(_e); }); | |||
144 | goto finish; | |||
145 | } | |||
146 | if (k == 0) { | |||
147 | log_error("Got EOF while reading from /dev/urandom.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/random-seed/random-seed.c", 147, __func__, "Got EOF while reading from /dev/urandom." ) : -abs(_e); }); | |||
148 | r = -EIO5; | |||
149 | goto finish; | |||
150 | } | |||
151 | ||||
152 | r = loop_write(seed_fd, buf, (size_t) k, false0); | |||
153 | if (r < 0) | |||
154 | log_error_errno(r, "Failed to write new random seed file: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/random-seed/random-seed.c", 154, __func__, "Failed to write new random seed file: %m" ) : -abs(_e); }); | |||
155 | } | |||
156 | ||||
157 | finish: | |||
158 | return r < 0 ? EXIT_FAILURE1 : EXIT_SUCCESS0; | |||
159 | } |