From 6d3db278fe8465d8bef4e215e2b0d20b12f8602b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 18 Oct 2018 13:30:20 +0200 Subject: [PATCH 01/14] clock-util: excorcise fgets() --- src/basic/clock-util.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/basic/clock-util.c b/src/basic/clock-util.c index 8555cc7952..b77e780bed 100644 --- a/src/basic/clock-util.c +++ b/src/basic/clock-util.c @@ -10,8 +10,11 @@ #include #include +#include "alloc-util.h" #include "clock-util.h" +#include "def.h" #include "fd-util.h" +#include "fileio.h" #include "macro.h" #include "string-util.h" #include "util.h" @@ -54,6 +57,7 @@ int clock_set_hwclock(const struct tm *tm) { int clock_is_localtime(const char* adjtime_path) { _cleanup_fclose_ FILE *f; + int r; if (!adjtime_path) adjtime_path = "/etc/adjtime"; @@ -67,24 +71,30 @@ int clock_is_localtime(const char* adjtime_path) { */ f = fopen(adjtime_path, "re"); if (f) { - char line[LINE_MAX]; - bool b; + _cleanup_free_ char *line = NULL; + unsigned i; - b = fgets(line, sizeof(line), f) && - fgets(line, sizeof(line), f) && - fgets(line, sizeof(line), f); - if (!b) - /* less than three lines -> default to UTC */ - return 0; + for (i = 0; i < 2; i++) { /* skip the first two lines */ + r = read_line(f, LONG_LINE_MAX, NULL); + if (r < 0) + return r; + if (r == 0) + return false; /* less than three lines → default to UTC */ + } + + r = read_line(f, LONG_LINE_MAX, &line); + if (r < 0) + return r; + if (r == 0) + return false; /* less than three lines → default to UTC */ - truncate_nl(line); return streq(line, "LOCAL"); } else if (errno != ENOENT) return -errno; - /* adjtime not present -> default to UTC */ - return 0; + /* adjtime not present → default to UTC */ + return false; } int clock_set_timezone(int *min) { From 715bcf361dea9ec058ab91705aaedaa7d6de7709 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 18 Oct 2018 13:32:05 +0200 Subject: [PATCH 02/14] terminal-util: excorcise fgets() --- src/basic/terminal-util.c | 46 ++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/src/basic/terminal-util.c b/src/basic/terminal-util.c index c2aa75c6a8..ba3b9524c6 100644 --- a/src/basic/terminal-util.c +++ b/src/basic/terminal-util.c @@ -81,14 +81,16 @@ int chvt(int vt) { } int read_one_char(FILE *f, char *ret, usec_t t, bool *need_nl) { - struct termios old_termios, new_termios; - char c, line[LINE_MAX]; + _cleanup_free_ char *line = NULL; + struct termios old_termios; + int r; assert(f); assert(ret); + /* If this is a terminal, then switch canonical mode off, so that we can read a single character */ if (tcgetattr(fileno(f), &old_termios) >= 0) { - new_termios = old_termios; + struct termios new_termios = old_termios; new_termios.c_lflag &= ~ICANON; new_termios.c_cc[VMIN] = 1; @@ -124,11 +126,13 @@ int read_one_char(FILE *f, char *ret, usec_t t, bool *need_nl) { return -ETIMEDOUT; } - errno = 0; - if (!fgets(line, sizeof(line), f)) - return errno > 0 ? -errno : -EIO; + /* If this is not a terminal, then read a full line instead */ - truncate_nl(line); + r = read_line(f, 16, &line); /* longer than necessary, to eat up UTF-8 chars/vt100 key sequences */ + if (r < 0) + return r; + if (r == 0) + return -EIO; if (strlen(line) != 1) return -EBADMSG; @@ -196,11 +200,13 @@ int ask_char(char *ret, const char *replies, const char *fmt, ...) { } int ask_string(char **ret, const char *text, ...) { + int r; + assert(ret); assert(text); for (;;) { - char line[LINE_MAX]; + _cleanup_free_ char *line = NULL; va_list ap; if (colors_enabled()) @@ -215,24 +221,14 @@ int ask_string(char **ret, const char *text, ...) { fflush(stdout); - errno = 0; - if (!fgets(line, sizeof(line), stdin)) - return errno > 0 ? -errno : -EIO; + r = read_line(stdin, LONG_LINE_MAX, &line); + if (r < 0) + return r; + if (r == 0) + return -EIO; - if (!endswith(line, "\n")) - putchar('\n'); - else { - char *s; - - if (isempty(line)) - continue; - - truncate_nl(line); - s = strdup(line); - if (!s) - return -ENOMEM; - - *ret = s; + if (!isempty(line)) { + *ret = TAKE_PTR(line); return 0; } } From d3f9790c81727cec2bf012a27381feecc40db85e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 18 Oct 2018 13:32:34 +0200 Subject: [PATCH 03/14] terminal-util: use fgetc() carefully instead of fread() --- src/basic/terminal-util.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/basic/terminal-util.c b/src/basic/terminal-util.c index ba3b9524c6..ea0ba442ff 100644 --- a/src/basic/terminal-util.c +++ b/src/basic/terminal-util.c @@ -97,21 +97,26 @@ int read_one_char(FILE *f, char *ret, usec_t t, bool *need_nl) { new_termios.c_cc[VTIME] = 0; if (tcsetattr(fileno(f), TCSADRAIN, &new_termios) >= 0) { - size_t k; + int c; if (t != USEC_INFINITY) { if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0) { - tcsetattr(fileno(f), TCSADRAIN, &old_termios); + (void) tcsetattr(fileno(f), TCSADRAIN, &old_termios); return -ETIMEDOUT; } } - k = fread(&c, 1, 1, f); + errno = 0; + c = fgetc(f); + if (c == EOF) + r = ferror(f) && errno > 0 ? -errno : -EIO; + else + r = 0; - tcsetattr(fileno(f), TCSADRAIN, &old_termios); + (void) tcsetattr(fileno(f), TCSADRAIN, &old_termios); - if (k <= 0) - return -EIO; + if (r < 0) + return r; if (need_nl) *need_nl = c != '\n'; From 7452c3ff525d23baf6dc723ad3342d289a3d5932 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 18 Oct 2018 13:33:00 +0200 Subject: [PATCH 04/14] binfmt: validate rule file name before using it --- src/binfmt/binfmt.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/binfmt/binfmt.c b/src/binfmt/binfmt.c index 55f700c089..0e5ca1a7e8 100644 --- a/src/binfmt/binfmt.c +++ b/src/binfmt/binfmt.c @@ -15,6 +15,7 @@ #include "fileio.h" #include "log.h" #include "pager.h" +#include "path-util.h" #include "string-util.h" #include "strv.h" #include "terminal-util.h" @@ -27,6 +28,7 @@ static int delete_rule(const char *rule) { _cleanup_free_ char *x = NULL, *fn = NULL; char *e; + assert(rule); assert(rule[0]); x = strdup(rule); @@ -36,6 +38,11 @@ static int delete_rule(const char *rule) { e = strchrnul(x+1, x[0]); *e = 0; + if (!filename_is_valid(x + 1)) { + log_error("Rule file name '%s' is not valid, refusing.", x+1); + return -EINVAL; + } + fn = strappend("/proc/sys/fs/binfmt_misc/", x+1); if (!fn) return log_oom(); @@ -46,7 +53,7 @@ static int delete_rule(const char *rule) { static int apply_rule(const char *rule) { int r; - delete_rule(rule); + (void) delete_rule(rule); r = write_string_file("/proc/sys/fs/binfmt_misc/register", rule, 0); if (r < 0) From 741d2cb533cb939fe57f5a59f011961b407cf7f2 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 18 Oct 2018 13:33:19 +0200 Subject: [PATCH 05/14] binfmt: fgets() excorcism Also, let's not claim we ignored errors when we don't. --- src/binfmt/binfmt.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/binfmt/binfmt.c b/src/binfmt/binfmt.c index 0e5ca1a7e8..fb8cf13f23 100644 --- a/src/binfmt/binfmt.c +++ b/src/binfmt/binfmt.c @@ -73,25 +73,25 @@ static int apply_file(const char *path, bool ignore_enoent) { if (ignore_enoent && r == -ENOENT) return 0; - return log_error_errno(r, "Failed to open file '%s', ignoring: %m", path); + return log_error_errno(r, "Failed to open file '%s': %m", path); } log_debug("apply: %s", path); for (;;) { - char l[LINE_MAX], *p; + _cleanup_free_ char *line = NULL; + char *p; int k; - if (!fgets(l, sizeof(l), f)) { - if (feof(f)) - break; + k = read_line(f, LONG_LINE_MAX, &line); + if (k < 0) + return log_error_errno(k, "Failed to read file '%s': %m", path); + if (k == 0) + break; - return log_error_errno(errno, "Failed to read file '%s', ignoring: %m", path); - } - - p = strstrip(l); - if (!*p) + p = strstrip(line); + if (isempty(p)) continue; - if (strchr(COMMENTS "\n", *p)) + if (strchr(COMMENTS, p[0])) continue; k = apply_rule(p); From 717e419b35d8a1144a579fb38999d6847f948b98 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 18 Oct 2018 13:34:12 +0200 Subject: [PATCH 06/14] cgtop: fgets() excorcism --- src/cgtop/cgtop.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/cgtop/cgtop.c b/src/cgtop/cgtop.c index 1976d99597..e4123e5f07 100644 --- a/src/cgtop/cgtop.c +++ b/src/cgtop/cgtop.c @@ -343,10 +343,14 @@ static int process( } for (;;) { - char line[LINE_MAX], *l; + _cleanup_free_ char *line = NULL; uint64_t k, *q; + char *l; - if (!fgets(line, sizeof(line), f)) + r = read_line(f, LONG_LINE_MAX, &line); + if (r < 0) + return r; + if (r == 0) break; /* Trim and skip the device */ From b42674a1681617f0a8bef6a2f3c17e22c048d854 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 18 Oct 2018 13:34:40 +0200 Subject: [PATCH 07/14] cryptsetup-generator: fgets() excorcism --- src/cryptsetup/cryptsetup-generator.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c index cada032bb9..c3a4509030 100644 --- a/src/cryptsetup/cryptsetup-generator.c +++ b/src/cryptsetup/cryptsetup-generator.c @@ -4,6 +4,7 @@ #include #include "alloc-util.h" +#include "def.h" #include "dropin.h" #include "fd-util.h" #include "fileio.h" @@ -443,9 +444,10 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat } static int add_crypttab_devices(void) { - struct stat st; - unsigned crypttab_line = 0; _cleanup_fclose_ FILE *f = NULL; + unsigned crypttab_line = 0; + struct stat st; + int r; if (!arg_read_crypttab) return 0; @@ -465,18 +467,21 @@ static int add_crypttab_devices(void) { } for (;;) { - int r, k; - char line[LINE_MAX], *l, *uuid; + _cleanup_free_ char *line = NULL, *name = NULL, *device = NULL, *keyfile = NULL, *options = NULL; crypto_device *d = NULL; - _cleanup_free_ char *name = NULL, *device = NULL, *keyfile = NULL, *options = NULL; + char *l, *uuid; + int k; - if (!fgets(line, sizeof(line), f)) + r = read_line(f, LONG_LINE_MAX, &line); + if (r < 0) + return log_error_errno(r, "Failed to read /etc/crypttab: %m"); + if (r == 0) break; crypttab_line++; l = strstrip(line); - if (IN_SET(*l, 0, '#')) + if (IN_SET(l[0], 0, '#')) continue; k = sscanf(l, "%ms %ms %ms %ms", &name, &device, &keyfile, &options); From df2b06d1c21ef7d997c71767b3b6aaad9aecc270 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 18 Oct 2018 13:39:29 +0200 Subject: [PATCH 08/14] catalog: fgets() excorcism --- src/journal/catalog.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/journal/catalog.c b/src/journal/catalog.c index c59bf52d74..82c35d1d09 100644 --- a/src/journal/catalog.c +++ b/src/journal/catalog.c @@ -13,6 +13,7 @@ #include "alloc-util.h" #include "catalog.h" #include "conf-files.h" +#include "def.h" #include "fd-util.h" #include "fileio.h" #include "hashmap.h" @@ -267,26 +268,23 @@ int catalog_import_file(Hashmap *h, const char *path) { log_debug("File %s has language %s.", path, deflang); for (;;) { - char line[LINE_MAX]; + _cleanup_free_ char *line = NULL; size_t line_len; - if (!fgets(line, sizeof(line), f)) { - if (feof(f)) - break; - - return log_error_errno(errno, "Failed to read file %s: %m", path); - } + r = read_line(f, LONG_LINE_MAX, &line); + if (r < 0) + return log_error_errno(r, "Failed to read file %s: %m", path); + if (r == 0) + break; n++; - truncate_nl(line); - - if (line[0] == 0) { + if (isempty(line)) { empty_line = true; continue; } - if (strchr(COMMENTS "\n", line[0])) + if (strchr(COMMENTS, line[0])) continue; if (empty_line && From 32d621e4db5b4bb83ace8bf8cfedb72e75ff3a70 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 18 Oct 2018 13:39:41 +0200 Subject: [PATCH 09/14] hwdb: fgets() excorcism --- src/libsystemd/sd-hwdb/hwdb-util.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/libsystemd/sd-hwdb/hwdb-util.c b/src/libsystemd/sd-hwdb/hwdb-util.c index bfb3ae0e9c..140ea6b591 100644 --- a/src/libsystemd/sd-hwdb/hwdb-util.c +++ b/src/libsystemd/sd-hwdb/hwdb-util.c @@ -5,6 +5,7 @@ #include "alloc-util.h" #include "conf-files.h" +#include "def.h" #include "fd-util.h" #include "fileio.h" #include "fs-util.h" @@ -472,7 +473,6 @@ static int import_file(struct trie *trie, const char *filename, uint16_t file_pr HW_DATA, } state = HW_NONE; _cleanup_fclose_ FILE *f = NULL; - char line[LINE_MAX]; _cleanup_strv_free_ char **match_list = NULL; uint32_t line_number = 0; char *match = NULL; @@ -482,10 +482,17 @@ static int import_file(struct trie *trie, const char *filename, uint16_t file_pr if (!f) return -errno; - while (fgets(line, sizeof(line), f)) { + for (;;) { + _cleanup_free_ char *line = NULL; size_t len; char *pos; + r = read_line(f, LONG_LINE_MAX, &line); + if (r < 0) + return r; + if (r == 0) + break; + ++line_number; /* comment line */ From 1d47b56995b7e9c0af836118bc51bed3945ceaf5 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 18 Oct 2018 13:40:03 +0200 Subject: [PATCH 10/14] keymap-util: fgets() excorcism --- src/locale/keymap-util.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/locale/keymap-util.c b/src/locale/keymap-util.c index 6538da3b6f..69fcb3543c 100644 --- a/src/locale/keymap-util.c +++ b/src/locale/keymap-util.c @@ -199,7 +199,6 @@ int vconsole_read_data(Context *c, sd_bus_message *m) { int x11_read_data(Context *c, sd_bus_message *m) { _cleanup_fclose_ FILE *f = NULL; bool in_section = false; - char line[LINE_MAX]; struct stat st; usec_t t; int r; @@ -234,12 +233,17 @@ int x11_read_data(Context *c, sd_bus_message *m) { if (!f) return -errno; - while (fgets(line, sizeof(line), f)) { + for (;;) { + _cleanup_free_ char *line = NULL; char *l; - char_array_0(line); - l = strstrip(line); + r = read_line(f, LONG_LINE_MAX, &line); + if (r < 0) + return r; + if (r == 0) + break; + l = strstrip(line); if (IN_SET(l[0], 0, '#')) continue; @@ -470,19 +474,16 @@ static int read_next_mapping(const char* filename, assert(a); for (;;) { - char line[LINE_MAX]; + _cleanup_free_ char *line = NULL; + size_t length; char *l, **b; int r; - size_t length; - errno = 0; - if (!fgets(line, sizeof(line), f)) { - - if (ferror(f)) - return errno > 0 ? -errno : -EIO; - - return 0; - } + r = read_line(f, LONG_LINE_MAX, &line); + if (r < 0) + return r; + if (r == 0) + break; (*n)++; @@ -505,6 +506,8 @@ static int read_next_mapping(const char* filename, *a = b; return 1; } + + return 0; } int vconsole_convert_to_x11(Context *c) { From a889e206a7434afe28039a1698e5ecf6a3fb7a9b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 18 Oct 2018 13:40:21 +0200 Subject: [PATCH 11/14] modules-load: fgets() excorcism --- src/modules-load/modules-load.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/modules-load/modules-load.c b/src/modules-load/modules-load.c index bd4513b823..01d909ff19 100644 --- a/src/modules-load/modules-load.c +++ b/src/modules-load/modules-load.c @@ -72,25 +72,25 @@ static int apply_file(struct kmod_ctx *ctx, const char *path, bool ignore_enoent if (ignore_enoent && r == -ENOENT) return 0; - return log_error_errno(r, "Failed to open %s, ignoring: %m", path); + return log_error_errno(r, "Failed to open %s: %m", path); } log_debug("apply: %s", path); for (;;) { - char line[LINE_MAX], *l; + _cleanup_free_ char *line = NULL; + char *l; int k; - if (!fgets(line, sizeof(line), f)) { - if (feof(f)) - break; - - return log_error_errno(errno, "Failed to read file '%s', ignoring: %m", path); - } + r = read_line(f, LONG_LINE_MAX, &line); + if (r < 0) + return log_error_errno(errno, "Failed to read file '%s': %m", path); + if (r == 0) + break; l = strstrip(line); - if (!*l) + if (isempty(l)) continue; - if (strchr(COMMENTS "\n", *l)) + if (strchr(COMMENTS, *l)) continue; k = module_load_and_warn(ctx, l, true); From 1fd2786161feba4276a81c3468cfbfb118f56517 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 18 Oct 2018 13:40:39 +0200 Subject: [PATCH 12/14] reply-password: fgets() excorcism --- src/reply-password/reply-password.c | 37 ++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/src/reply-password/reply-password.c b/src/reply-password/reply-password.c index 84176184af..5794dfd535 100644 --- a/src/reply-password/reply-password.c +++ b/src/reply-password/reply-password.c @@ -6,7 +6,10 @@ #include #include +#include "alloc-util.h" +#include "def.h" #include "fd-util.h" +#include "fileio.h" #include "log.h" #include "macro.h" #include "socket-util.h" @@ -32,8 +35,8 @@ static int send_on_socket(int fd, const char *socket_name, const void *packet, s } int main(int argc, char *argv[]) { + _cleanup_free_ char *packet = NULL; _cleanup_close_ int fd = -1; - char packet[LINE_MAX]; size_t length; int r; @@ -47,18 +50,36 @@ int main(int argc, char *argv[]) { } if (streq(argv[1], "1")) { + _cleanup_string_free_erase_ char *line = NULL; - packet[0] = '+'; - if (!fgets(packet+1, sizeof(packet)-1, stdin)) { - r = log_error_errno(errno, "Failed to read password: %m"); + r = read_line(stdin, LONG_LINE_MAX, &line); + if (r < 0) { + log_error_errno(r, "Failed to read password: %m"); + goto finish; + } + if (r == 0) { + log_error("Got EOF while reading password."); + r = -EIO; goto finish; } - truncate_nl(packet+1); - length = 1 + strlen(packet+1) + 1; + packet = strjoin("+", line); + if (!packet) { + r = log_oom(); + goto finish; + } + + length = 1 + strlen(line) + 1; + } else if (streq(argv[1], "0")) { - packet[0] = '-'; + packet = strdup("-"); + if (!packet) { + r = log_oom(); + goto finish; + } + length = 1; + } else { log_error("Invalid first argument %s", argv[1]); r = -EINVAL; @@ -74,7 +95,7 @@ int main(int argc, char *argv[]) { r = send_on_socket(fd, argv[2], packet, length); finish: - explicit_bzero(packet, sizeof(packet)); + explicit_bzero(packet, length); return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; } From 9c6f9786c5f2acfc1cedebe82976ab78ee7fd6fc Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 18 Oct 2018 13:40:55 +0200 Subject: [PATCH 13/14] condition: fgets() excorcism --- src/shared/condition.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/shared/condition.c b/src/shared/condition.c index d0b17fe7ff..2acf36d468 100644 --- a/src/shared/condition.c +++ b/src/shared/condition.c @@ -384,10 +384,9 @@ static int condition_test_security(Condition *c) { } static int condition_test_capability(Condition *c) { + unsigned long long capabilities = (unsigned long long) -1; _cleanup_fclose_ FILE *f = NULL; - int value; - char line[LINE_MAX]; - unsigned long long capabilities = -1; + int value, r; assert(c); assert(c->parameter); @@ -405,11 +404,21 @@ static int condition_test_capability(Condition *c) { if (!f) return -errno; - while (fgets(line, sizeof(line), f)) { - truncate_nl(line); + for (;;) { + _cleanup_free_ char *line = NULL; + const char *p; + + r = read_line(f, LONG_LINE_MAX, &line); + if (r < 0) + return r; + if (r == 0) + break; + + p = startswith(line, "CapBnd:"); + if (p) { + if (sscanf(line+7, "%llx", &capabilities) != 1) + return -EIO; - if (startswith(line, "CapBnd:")) { - (void) sscanf(line+7, "%llx", &capabilities); break; } } From fae0f8a047cf0e99b763ef79848cbaf603525b8b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 18 Oct 2018 13:41:09 +0200 Subject: [PATCH 14/14] udev-rules: fgets() excorcism --- src/udev/udev-rules.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index 752e17f2ae..f834028dec 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -15,9 +15,11 @@ #include "alloc-util.h" #include "conf-files.h" +#include "def.h" #include "dirent-util.h" #include "escape.h" #include "fd-util.h" +#include "fileio.h" #include "fs-util.h" #include "glob-util.h" #include "path-util.h" @@ -613,15 +615,25 @@ static int import_property_from_string(struct udev_device *dev, char *line) { } static int import_file_into_properties(struct udev_device *dev, const char *filename) { - FILE *f; - char line[UTIL_LINE_SIZE]; + _cleanup_fclose_ FILE *f = NULL; + int r; f = fopen(filename, "re"); - if (f == NULL) - return -1; - while (fgets(line, sizeof(line), f) != NULL) - import_property_from_string(dev, line); - fclose(f); + if (!f) + return -errno; + + for (;;) { + _cleanup_free_ char *line = NULL; + + r = read_line(f, LONG_LINE_MAX, &line); + if (r < 0) + return r; + if (r == 0) + break; + + (void) import_property_from_string(dev, line); + } + return 0; } @@ -646,7 +658,7 @@ static int import_program_into_properties(struct udev_event *event, pos[0] = '\0'; pos = &pos[1]; } - import_property_from_string(event->dev, line); + (void) import_property_from_string(event->dev, line); line = pos; } return 0; @@ -1429,8 +1441,8 @@ static int parse_file(struct udev_rules *rules, const char *filename) { if (!f) { if (errno == ENOENT) return 0; - else - return -errno; + + return -errno; } if (null_or_empty_fd(fileno(f))) {