diff options
-rw-r--r-- | man/systemd.resource-control.xml | 17 | ||||
-rw-r--r-- | man/systemd.unit.xml | 16 | ||||
-rw-r--r-- | src/ask-password/ask-password.c | 2 | ||||
-rw-r--r-- | src/basic/strv.c | 9 | ||||
-rw-r--r-- | src/basic/strv.h | 4 | ||||
-rw-r--r-- | src/basic/util.c | 19 | ||||
-rw-r--r-- | src/basic/util.h | 7 | ||||
-rw-r--r-- | src/core/dbus-execute.c | 34 | ||||
-rw-r--r-- | src/core/dbus-unit.c | 2 | ||||
-rw-r--r-- | src/core/load-fragment.c | 1 | ||||
-rw-r--r-- | src/core/manager.c | 4 | ||||
-rw-r--r-- | src/core/service.c | 2 | ||||
-rw-r--r-- | src/cryptsetup/cryptsetup.c | 47 | ||||
-rw-r--r-- | src/firstboot/firstboot.c | 20 | ||||
-rw-r--r-- | src/journal/journal-vacuum.c | 3 | ||||
-rw-r--r-- | src/journal/journald-server.c | 4 | ||||
-rw-r--r-- | src/reply-password/reply-password.c | 19 | ||||
-rw-r--r-- | src/shared/ask-password-api.c | 17 | ||||
-rw-r--r-- | src/timesync/timesyncd.c | 8 | ||||
-rw-r--r-- | src/tty-ask-password-agent/tty-ask-password-agent.c | 97 |
20 files changed, 204 insertions, 128 deletions
diff --git a/man/systemd.resource-control.xml b/man/systemd.resource-control.xml index 98f4d75ddb..9c5366a2b0 100644 --- a/man/systemd.resource-control.xml +++ b/man/systemd.resource-control.xml @@ -412,6 +412,23 @@ </varlistentry> <varlistentry> + <term><varname>NetClass=</varname></term> + <listitem><para>Configures a network class number to assign to the + unit. This value will be set to the + <literal>net_cls.class_id</literal> property of the + <literal>net_cls</literal> cgroup of the unit. The directive + accepts a numerical value (for fixed number assignment) and the keyword + <literal>auto</literal> (for dynamic allocation). Network traffic of + all processes inside the unit will have the network class ID assigned + by the kernel. Also see + the kernel docs for + <ulink url="https://www.kernel.org/doc/Documentation/cgroups/net_cls.txt">net_cls controller</ulink> + and + <citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>. + </para></listitem> + </varlistentry> + + <varlistentry> <term><varname>Slice=</varname></term> <listitem> diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index 8985b6b940..33f1309268 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -1045,22 +1045,6 @@ units.</para></listitem> </varlistentry> - <varlistentry> - <term><varname>NetClass=</varname></term> - <listitem><para>Configures a network class number to assign to the - unit. This value will be set to the - <literal>net_cls.class_id</literal> property of the - <literal>net_cls</literal> cgroup of the unit. The directive - accepts a numerical value (for fixed number assignment) and the keyword - <literal>auto</literal> (for dynamic allocation). Network traffic of - all processes inside the unit will have the network class ID assigned - by the kernel. Also see - the kernel docs for - <ulink url="https://www.kernel.org/doc/Documentation/cgroups/net_cls.txt">net_cls controller</ulink> - and - <citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>. - </para></listitem> - </varlistentry> </variablelist> </refsect1> diff --git a/src/ask-password/ask-password.c b/src/ask-password/ask-password.c index 1a69d15908..a544866000 100644 --- a/src/ask-password/ask-password.c +++ b/src/ask-password/ask-password.c @@ -144,7 +144,7 @@ static int parse_argv(int argc, char *argv[]) { } int main(int argc, char *argv[]) { - _cleanup_strv_free_ char **l = NULL; + _cleanup_strv_free_erase_ char **l = NULL; usec_t timeout; char **p; int r; diff --git a/src/basic/strv.c b/src/basic/strv.c index b66c176487..501d022cb9 100644 --- a/src/basic/strv.c +++ b/src/basic/strv.c @@ -86,6 +86,15 @@ char **strv_free(char **l) { return NULL; } +char **strv_free_erase(char **l) { + char **i; + + STRV_FOREACH(i, l) + string_erase(*i); + + return strv_free(l); +} + char **strv_copy(char * const *l) { char **r, **k; diff --git a/src/basic/strv.h b/src/basic/strv.h index e49f443835..a5dc696a87 100644 --- a/src/basic/strv.h +++ b/src/basic/strv.h @@ -35,6 +35,10 @@ char **strv_free(char **l); DEFINE_TRIVIAL_CLEANUP_FUNC(char**, strv_free); #define _cleanup_strv_free_ _cleanup_(strv_freep) +char **strv_free_erase(char **l); +DEFINE_TRIVIAL_CLEANUP_FUNC(char**, strv_free_erase); +#define _cleanup_strv_free_erase_ _cleanup_(strv_free_erasep) + void strv_clear(char **l); char **strv_copy(char * const *l); diff --git a/src/basic/util.c b/src/basic/util.c index 460e74061a..3e90456dd3 100644 --- a/src/basic/util.c +++ b/src/basic/util.c @@ -6829,3 +6829,22 @@ bool fdname_is_valid(const char *s) { bool oom_score_adjust_is_valid(int oa) { return oa >= OOM_SCORE_ADJ_MIN && oa <= OOM_SCORE_ADJ_MAX; } + +void string_erase(char *x) { + + if (!x) + return; + + /* A delicious drop of snake-oil! To be called on memory where + * we stored passphrases or so, after we used them. */ + + memory_erase(x, strlen(x)); +} + +char *string_free_erase(char *s) { + if (!s) + return NULL; + + string_erase(s); + return mfree(s); +} diff --git a/src/basic/util.h b/src/basic/util.h index ac74650ff6..ff39eae715 100644 --- a/src/basic/util.h +++ b/src/basic/util.h @@ -949,3 +949,10 @@ int version(void); bool fdname_is_valid(const char *s); bool oom_score_adjust_is_valid(int oa); + +#define memory_erase(p, l) memset((p), 'x', (l)) +void string_erase(char *x); + +char *string_free_erase(char *s); +DEFINE_TRIVIAL_CLEANUP_FUNC(char *, string_free_erase); +#define _cleanup_string_free_erase_ _cleanup_(string_free_erasep) diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c index b71e5ad300..a286149b53 100644 --- a/src/core/dbus-execute.c +++ b/src/core/dbus-execute.c @@ -1208,8 +1208,9 @@ int bus_exec_context_set_transient_property( _cleanup_free_ char *joined = NULL; _cleanup_fclose_ FILE *f = NULL; + _cleanup_free_ char **l = NULL; size_t size = 0; - bool empty_array = true; + char **i; r = sd_bus_message_enter_container(message, 'a', "(sb)"); if (r < 0) @@ -1219,18 +1220,13 @@ int bus_exec_context_set_transient_property( if (!f) return -ENOMEM; - if (mode != UNIT_CHECK) { - char **buf; - STRV_FOREACH(buf, c->environment_files) - fprintf(f, "EnvironmentFile=%s\n", *buf); - } + STRV_FOREACH(i, c->environment_files) + fprintf(f, "EnvironmentFile=%s\n", *i); while ((r = sd_bus_message_enter_container(message, 'r', "sb")) > 0) { const char *path; int b; - empty_array = false; - r = sd_bus_message_read(message, "sb", &path, &b); if (r < 0) return r; @@ -1247,12 +1243,12 @@ int bus_exec_context_set_transient_property( char *buf = NULL; buf = strjoin(b ? "-" : "", path, NULL); - if (buf == NULL) + if (!buf) return -ENOMEM; fprintf(f, "EnvironmentFile=%s\n", buf); - r = strv_consume(&c->environment_files, buf); + r = strv_consume(&l, buf); if (r < 0) return r; } @@ -1260,14 +1256,22 @@ int bus_exec_context_set_transient_property( if (r < 0) return r; - fflush(f); + r = fflush_and_check(f); + if (r < 0) + return r; - if (mode != UNIT_CHECK) - if (empty_array) { - strv_clear(c->environment_files); + if (mode != UNIT_CHECK) { + if (strv_isempty(l)) { + c->environment_files = strv_free(c->environment_files); unit_write_drop_in_private(u, mode, name, "EnvironmentFile=\n"); - } else + } else { + r = strv_extend_strv(&c->environment_files, l, true); + if (r < 0) + return r; + unit_write_drop_in_private(u, mode, name, joined); + } + } r = sd_bus_message_exit_container(message); if (r < 0) diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c index cd88a87340..52daf11610 100644 --- a/src/core/dbus-unit.c +++ b/src/core/dbus-unit.c @@ -679,7 +679,7 @@ const sd_bus_vtable bus_unit_vtable[] = { SD_BUS_PROPERTY("Asserts", "a(sbbsi)", property_get_conditions, offsetof(Unit, asserts), 0), SD_BUS_PROPERTY("LoadError", "(ss)", property_get_load_error, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("Transient", "b", bus_property_get_bool, offsetof(Unit, transient), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("NetClass", "u", bus_property_get_unsigned, offsetof(Unit, cgroup_netclass_id), 0), + SD_BUS_PROPERTY("NetClass", "u", NULL, offsetof(Unit, cgroup_netclass_id), 0), SD_BUS_METHOD("Start", "s", "o", method_start, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("Stop", "s", "o", method_stop, SD_BUS_VTABLE_UNPRIVILEGED), diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index b1d4c6b57d..ba39df6877 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -2742,6 +2742,7 @@ int config_parse_tasks_max( return 0; } + c->tasks_max = u; return 0; } diff --git a/src/core/manager.c b/src/core/manager.c index b2d56e88a7..6ae836148d 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -2952,9 +2952,9 @@ void manager_set_show_status(Manager *m, ShowStatus mode) { m->show_status = mode; if (mode > 0) - touch("/run/systemd/show-status"); + (void) touch("/run/systemd/show-status"); else - unlink("/run/systemd/show-status"); + (void) unlink("/run/systemd/show-status"); } static bool manager_get_show_status(Manager *m, StatusType type) { diff --git a/src/core/service.c b/src/core/service.c index 1e4f707bf4..c77d4dc796 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -1215,7 +1215,7 @@ static int service_spawn( if (is_control && UNIT(s)->cgroup_path) { path = strjoina(UNIT(s)->cgroup_path, "/control"); - cg_create(SYSTEMD_CGROUP_CONTROLLER, path); + (void) cg_create(SYSTEMD_CGROUP_CONTROLLER, path); } else path = UNIT(s)->cgroup_path; diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c index cc03ad3ca8..ecc1273eec 100644 --- a/src/cryptsetup/cryptsetup.c +++ b/src/cryptsetup/cryptsetup.c @@ -312,15 +312,16 @@ static char *disk_mount_point(const char *label) { return NULL; } -static int get_password(const char *vol, const char *src, usec_t until, bool accept_cached, char ***passwords) { +static int get_password(const char *vol, const char *src, usec_t until, bool accept_cached, char ***ret) { _cleanup_free_ char *description = NULL, *name_buffer = NULL, *mount_point = NULL, *maj_min = NULL, *text = NULL, *escaped_name = NULL; + _cleanup_strv_free_erase_ char **passwords = NULL; const char *name = NULL; char **p, *id; int r = 0; assert(vol); assert(src); - assert(passwords); + assert(ret); description = disk_description(src); mount_point = disk_mount_point(vol); @@ -360,14 +361,16 @@ static int get_password(const char *vol, const char *src, usec_t until, bool acc id = strjoina("cryptsetup:", escaped_name); - r = ask_password_auto(text, "drive-harddisk", id, "cryptsetup", until, ASK_PASSWORD_PUSH_CACHE|(accept_cached ? ASK_PASSWORD_ACCEPT_CACHED : 0), passwords); + r = ask_password_auto(text, "drive-harddisk", id, "cryptsetup", until, + ASK_PASSWORD_PUSH_CACHE | (accept_cached*ASK_PASSWORD_ACCEPT_CACHED), + &passwords); if (r < 0) return log_error_errno(r, "Failed to query password: %m"); if (arg_verify) { - _cleanup_strv_free_ char **passwords2 = NULL; + _cleanup_strv_free_erase_ char **passwords2 = NULL; - assert(strv_length(*passwords) == 1); + assert(strv_length(passwords) == 1); if (asprintf(&text, "Please enter passphrase for disk %s! (verification)", name) < 0) return log_oom(); @@ -380,22 +383,23 @@ static int get_password(const char *vol, const char *src, usec_t until, bool acc assert(strv_length(passwords2) == 1); - if (!streq(*passwords[0], passwords2[0])) { + if (!streq(passwords[0], passwords2[0])) { log_warning("Passwords did not match, retrying."); return -EAGAIN; } } - strv_uniq(*passwords); + strv_uniq(passwords); - STRV_FOREACH(p, *passwords) { + STRV_FOREACH(p, passwords) { char *c; if (strlen(*p)+1 >= arg_key_size) continue; /* Pad password if necessary */ - if (!(c = new(char, arg_key_size))) + c = new(char, arg_key_size); + if (!c) return log_oom(); strncpy(c, *p, arg_key_size); @@ -403,14 +407,19 @@ static int get_password(const char *vol, const char *src, usec_t until, bool acc *p = c; } + *ret = passwords; + passwords = NULL; + return 0; } -static int attach_tcrypt(struct crypt_device *cd, - const char *name, - const char *key_file, - char **passwords, - uint32_t flags) { +static int attach_tcrypt( + struct crypt_device *cd, + const char *name, + const char *key_file, + char **passwords, + uint32_t flags) { + int r = 0; _cleanup_free_ char *passphrase = NULL; struct crypt_params_tcrypt params = { @@ -520,8 +529,7 @@ static int attach_luks_or_plain(struct crypt_device *cd, * it just configures encryption * parameters when used for plain * mode. */ - r = crypt_format(cd, CRYPT_PLAIN, cipher, cipher_mode, - NULL, NULL, arg_keyfile_size, ¶ms); + r = crypt_format(cd, CRYPT_PLAIN, cipher, cipher_mode, NULL, NULL, arg_keyfile_size, ¶ms); /* hash == NULL implies the user passed "plain" */ pass_volume_key = (params.hash == NULL); @@ -537,9 +545,7 @@ static int attach_luks_or_plain(struct crypt_device *cd, crypt_get_device_name(cd)); if (key_file) { - r = crypt_activate_by_keyfile_offset(cd, name, arg_key_slot, - key_file, arg_keyfile_size, - arg_keyfile_offset, flags); + r = crypt_activate_by_keyfile_offset(cd, name, arg_key_slot, key_file, arg_keyfile_size, arg_keyfile_offset, flags); if (r < 0) { log_error_errno(r, "Failed to activate with key file '%s': %m", key_file); return -EAGAIN; @@ -631,7 +637,6 @@ int main(int argc, char *argv[]) { k = crypt_init(&cd, arg_header); } else k = crypt_init(&cd, argv[3]); - if (k) { log_error_errno(k, "crypt_init() failed: %m"); goto finish; @@ -669,7 +674,7 @@ int main(int argc, char *argv[]) { } for (tries = 0; arg_tries == 0 || tries < arg_tries; tries++) { - _cleanup_strv_free_ char **passwords = NULL; + _cleanup_strv_free_erase_ char **passwords = NULL; if (!key_file) { k = get_password(argv[2], argv[3], until, tries == 0 && !arg_verify, &passwords); diff --git a/src/firstboot/firstboot.c b/src/firstboot/firstboot.c index 1562ccf0d7..82ebb91788 100644 --- a/src/firstboot/firstboot.c +++ b/src/firstboot/firstboot.c @@ -51,15 +51,6 @@ static bool arg_copy_locale = false; static bool arg_copy_timezone = false; static bool arg_copy_root_password = false; -static void clear_string(char *x) { - - if (!x) - return; - - /* A delicious drop of snake-oil! */ - memset(x, 'x', strlen(x)); -} - static bool press_any_key(void) { char k = 0; bool need_nl = true; @@ -464,7 +455,7 @@ static int prompt_root_password(void) { msg2 = strjoina(draw_special_char(DRAW_TRIANGULAR_BULLET), " Please enter new root password again: "); for (;;) { - _cleanup_free_ char *a = NULL, *b = NULL; + _cleanup_string_free_erase_ char *a = NULL, *b = NULL; r = ask_password_tty(msg1, NULL, 0, 0, NULL, &a); if (r < 0) @@ -476,19 +467,14 @@ static int prompt_root_password(void) { } r = ask_password_tty(msg2, NULL, 0, 0, NULL, &b); - if (r < 0) { - clear_string(a); + if (r < 0) return log_error_errno(r, "Failed to query root password: %m"); - } if (!streq(a, b)) { log_error("Entered passwords did not match, please try again."); - clear_string(a); - clear_string(b); continue; } - clear_string(b); arg_root_password = a; a = NULL; break; @@ -881,7 +867,7 @@ finish: free(arg_locale_messages); free(arg_timezone); free(arg_hostname); - clear_string(arg_root_password); + string_erase(arg_root_password); free(arg_root_password); return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; diff --git a/src/journal/journal-vacuum.c b/src/journal/journal-vacuum.c index a394066cb4..c7ecd360b9 100644 --- a/src/journal/journal-vacuum.c +++ b/src/journal/journal-vacuum.c @@ -217,13 +217,11 @@ int journal_directory_vacuum( de->d_name[q-8-16-1-16-1] = 0; if (sd_id128_from_string(de->d_name + q-8-16-1-16-1-32, &seqnum_id) < 0) { - free(p); n_active_files++; continue; } if (sscanf(de->d_name + q-8-16-1-16, "%16llx-%16llx.journal", &seqnum, &realtime) != 2) { - free(p); n_active_files++; continue; } @@ -253,7 +251,6 @@ int journal_directory_vacuum( } if (sscanf(de->d_name + q-1-8-16-1-16, "%16llx-%16llx.journal~", &realtime, &tmp) != 2) { - free(p); n_active_files ++; continue; } diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 2d2a215f5d..140d40667e 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -930,7 +930,7 @@ finish: static int system_journal_open(Server *s, bool flush_requested) { const char *fn; - int r; + int r = 0; if (!s->system_journal && (s->storage == STORAGE_PERSISTENT || s->storage == STORAGE_AUTO) && @@ -1231,7 +1231,7 @@ static int dispatch_sigusr1(sd_event_source *es, const struct signalfd_siginfo * server_sync(s); server_vacuum(s, false, false); - touch("/run/systemd/journal/flushed"); + (void) touch("/run/systemd/journal/flushed"); return 0; } diff --git a/src/reply-password/reply-password.c b/src/reply-password/reply-password.c index d0d61b98ed..534cf729b9 100644 --- a/src/reply-password/reply-password.c +++ b/src/reply-password/reply-password.c @@ -50,9 +50,10 @@ static int send_on_socket(int fd, const char *socket_name, const void *packet, s } int main(int argc, char *argv[]) { - int fd = -1, r = EXIT_FAILURE; + _cleanup_close_ int fd = -1; char packet[LINE_MAX]; size_t length; + int r; log_set_target(LOG_TARGET_AUTO); log_parse_environment(); @@ -60,14 +61,14 @@ int main(int argc, char *argv[]) { if (argc != 3) { log_error("Wrong number of arguments."); - goto finish; + return EXIT_FAILURE; } if (streq(argv[1], "1")) { packet[0] = '+'; if (!fgets(packet+1, sizeof(packet)-1, stdin)) { - log_error_errno(errno, "Failed to read password: %m"); + r = log_error_errno(errno, "Failed to read password: %m"); goto finish; } @@ -78,22 +79,20 @@ int main(int argc, char *argv[]) { length = 1; } else { log_error("Invalid first argument %s", argv[1]); + r = -EINVAL; goto finish; } fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); if (fd < 0) { - log_error_errno(errno, "socket() failed: %m"); + r = log_error_errno(errno, "socket() failed: %m"); goto finish; } - if (send_on_socket(fd, argv[2], packet, length) < 0) - goto finish; - - r = EXIT_SUCCESS; + r = send_on_socket(fd, argv[2], packet, length); finish: - safe_close(fd); + memory_erase(packet, sizeof(packet)); - return r; + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; } diff --git a/src/shared/ask-password-api.c b/src/shared/ask-password-api.c index f8cf11b297..ddf42f11e1 100644 --- a/src/shared/ask-password-api.c +++ b/src/shared/ask-password-api.c @@ -78,6 +78,7 @@ static int retrieve_key(key_serial_t serial, char ***ret) { if (n < m) break; + memory_erase(p, n); free(p); m *= 2; } @@ -86,12 +87,14 @@ static int retrieve_key(key_serial_t serial, char ***ret) { if (!l) return -ENOMEM; + memory_erase(p, n); + *ret = l; return 0; } static int add_to_keyring(const char *keyname, AskPasswordFlags flags, char **passwords) { - _cleanup_strv_free_ char **l = NULL; + _cleanup_strv_free_erase_ char **l = NULL; _cleanup_free_ char *p = NULL; key_serial_t serial; size_t n; @@ -124,6 +127,7 @@ static int add_to_keyring(const char *keyname, AskPasswordFlags flags, char **pa assert(p[n-1] == 0); serial = add_key("user", keyname, p, n-1, KEY_SPEC_USER_KEYRING); + memory_erase(p, n); if (serial == -1) return -errno; @@ -361,9 +365,12 @@ int ask_password_tty( dirty = true; } + + c = 'x'; } x = strndup(passphrase, p); + memory_erase(passphrase, p); if (!x) { r = -ENOMEM; goto finish; @@ -620,6 +627,7 @@ int ask_password_agent( l = strv_new("", NULL); else l = strv_parse_nulstr(passphrase+1, n-1); + memory_erase(passphrase, n); if (!l) { r = -ENOMEM; goto finish; @@ -688,9 +696,12 @@ int ask_password_auto( if (r < 0) return r; - r = strv_consume(&l, s); - if (r < 0) + r = strv_push(&l, s); + if (r < 0) { + string_erase(s); + free(s); return -ENOMEM; + } *ret = l; return 0; diff --git a/src/timesync/timesyncd.c b/src/timesync/timesyncd.c index 3cb7d435cd..722b349b81 100644 --- a/src/timesync/timesyncd.c +++ b/src/timesync/timesyncd.c @@ -57,12 +57,12 @@ static int load_clock_timestamp(uid_t uid, gid_t gid) { /* Try to fix the access mode, so that we can still touch the file after dropping priviliges */ - fchmod(fd, 0644); - fchown(fd, uid, gid); + (void) fchmod(fd, 0644); + (void) fchown(fd, uid, gid); } else /* create stamp file with the compiled-in date */ - touch_file("/var/lib/systemd/clock", true, min, uid, gid, 0644); + (void) touch_file("/var/lib/systemd/clock", true, min, uid, gid, 0644); ct = now(CLOCK_REALTIME); if (ct < min) { @@ -150,7 +150,7 @@ int main(int argc, char *argv[]) { /* if we got an authoritative time, store it in the file system */ if (m->sync) - touch("/var/lib/systemd/clock"); + (void) touch("/var/lib/systemd/clock"); sd_event_get_exit_code(m->event, &r); diff --git a/src/tty-ask-password-agent/tty-ask-password-agent.c b/src/tty-ask-password-agent/tty-ask-password-agent.c index 53986babae..8423364046 100644 --- a/src/tty-ask-password-agent/tty-ask-password-agent.c +++ b/src/tty-ask-password-agent/tty-ask-password-agent.c @@ -120,23 +120,30 @@ static int ask_password_plymouth( y = now(CLOCK_MONOTONIC); - if (y > until) - return -ETIME; + if (y > until) { + r = -ETIME; + goto finish; + } sleep_for = (int) ((until - y) / USEC_PER_MSEC); } - if (flag_file && access(flag_file, F_OK) < 0) - return -errno; + if (flag_file && access(flag_file, F_OK) < 0) { + r = -errno; + goto finish; + } j = poll(pollfd, notify >= 0 ? 2 : 1, sleep_for); if (j < 0) { if (errno == EINTR) continue; - return -errno; - } else if (j == 0) - return -ETIME; + r = -errno; + goto finish; + } else if (j == 0) { + r = -ETIME; + goto finish; + } if (notify >= 0 && pollfd[POLL_INOTIFY].revents != 0) flush_fd(notify); @@ -149,9 +156,12 @@ static int ask_password_plymouth( if (errno == EINTR || errno == EAGAIN) continue; - return -errno; - } else if (k == 0) - return -EIO; + r = -errno; + goto finish; + } else if (k == 0) { + r = -EIO; + goto finish; + } p += k; @@ -166,12 +176,14 @@ static int ask_password_plymouth( * with a normal password request */ packet = mfree(packet); - if (asprintf(&packet, "*\002%c%s%n", (int) (strlen(message) + 1), message, &n) < 0) - return -ENOMEM; + if (asprintf(&packet, "*\002%c%s%n", (int) (strlen(message) + 1), message, &n) < 0) { + r = -ENOMEM; + goto finish; + } r = loop_write(fd, packet, n+1, true); if (r < 0) - return r; + goto finish; flags &= ~ASK_PASSWORD_ACCEPT_CACHED; p = 0; @@ -179,7 +191,8 @@ static int ask_password_plymouth( } /* No password, because UI not shown */ - return -ENOENT; + r = -ENOENT; + goto finish; } else if (buffer[0] == 2 || buffer[0] == 9) { uint32_t size; @@ -191,32 +204,43 @@ static int ask_password_plymouth( memcpy(&size, buffer+1, sizeof(size)); size = le32toh(size); - if (size + 5 > sizeof(buffer)) - return -EIO; + if (size + 5 > sizeof(buffer)) { + r = -EIO; + goto finish; + } if (p-5 < size) continue; l = strv_parse_nulstr(buffer + 5, size); - if (!l) - return -ENOMEM; + if (!l) { + r = -ENOMEM; + goto finish; + } *ret = l; break; - } else + } else { /* Unknown packet */ - return -EIO; + r = -EIO; + goto finish; + } } - return 0; + r = 0; + +finish: + memory_erase(buffer, sizeof(buffer)); + return r; } static int parse_password(const char *filename, char **wall) { _cleanup_free_ char *socket_name = NULL, *message = NULL, *packet = NULL; + bool accept_cached = false, echo = false; + size_t packet_length = 0; uint64_t not_after = 0; unsigned pid = 0; - bool accept_cached = false, echo = false; const ConfigTableItem items[] = { { "Ask", "Socket", config_parse_string, 0, &socket_name }, @@ -270,7 +294,6 @@ static int parse_password(const char *filename, char **wall) { } else { union sockaddr_union sa = {}; - size_t packet_length = 0; _cleanup_close_ int socket_fd = -1; assert(arg_action == ACTION_QUERY || @@ -284,7 +307,7 @@ static int parse_password(const char *filename, char **wall) { } if (arg_plymouth) { - _cleanup_strv_free_ char **passwords = NULL; + _cleanup_strv_free_erase_ char **passwords = NULL; r = ask_password_plymouth(message, not_after, accept_cached ? ASK_PASSWORD_ACCEPT_CACHED : 0, filename, &passwords); if (r >= 0) { @@ -308,7 +331,7 @@ static int parse_password(const char *filename, char **wall) { } } else { - _cleanup_free_ char *password = NULL; + _cleanup_string_free_erase_ char *password = NULL; int tty_fd = -1; if (arg_console) { @@ -340,26 +363,36 @@ static int parse_password(const char *filename, char **wall) { } } - if (IN_SET(r, -ETIME, -ENOENT)) + if (IN_SET(r, -ETIME, -ENOENT)) { /* If the query went away, that's OK */ - return 0; - - if (r < 0) - return log_error_errno(r, "Failed to query password: %m"); + r = 0; + goto finish; + } + if (r < 0) { + log_error_errno(r, "Failed to query password: %m"); + goto finish; + } socket_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0); - if (socket_fd < 0) - return log_error_errno(errno, "socket(): %m"); + if (socket_fd < 0) { + r = log_error_errno(errno, "socket(): %m"); + goto finish; + } sa.un.sun_family = AF_UNIX; strncpy(sa.un.sun_path, socket_name, sizeof(sa.un.sun_path)); r = sendto(socket_fd, packet, packet_length, MSG_NOSIGNAL, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(socket_name)); + memory_erase(packet, packet_length); if (r < 0) return log_error_errno(errno, "Failed to send: %m"); } return 0; + +finish: + memory_erase(packet, packet_length); + return r; } static int wall_tty_block(void) { |