diff --git a/src/fuzz/fuzz-udev-rules.c b/src/fuzz/fuzz-udev-rules.c index dbdcda329e..42f0fa0b91 100644 --- a/src/fuzz/fuzz-udev-rules.c +++ b/src/fuzz/fuzz-udev-rules.c @@ -99,9 +99,9 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { if (size != 0) assert_se(fwrite(data, size, 1, f) == 1); assert_se(fclose(f) == 0); - rules = udev_rules_new(RESOLVE_NAME_EARLY); + + assert_se(udev_rules_new(&rules, RESOLVE_NAME_EARLY) == 0); assert_se(cleanup_fake_filesystems(runtime_dir) >= 0); - return 0; } diff --git a/src/test/test-udev.c b/src/test/test-udev.c index 281dbb51f2..9165fad73a 100644 --- a/src/test/test-udev.c +++ b/src/test/test-udev.c @@ -87,7 +87,7 @@ static int run(int argc, char *argv[]) { action = argv[1]; devpath = argv[2]; - rules = udev_rules_new(RESOLVE_NAME_EARLY); + assert_se(udev_rules_new(&rules, RESOLVE_NAME_EARLY) == 0); const char *syspath = strjoina("/sys", devpath); r = device_new_from_synthetic_event(&dev, syspath, action); diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index a9fa04dbf0..4e516d7fc7 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -1512,17 +1512,17 @@ static int parse_file(struct udev_rules *rules, const char *filename) { return 0; } -struct udev_rules *udev_rules_new(ResolveNameTiming resolve_name_timing) { - struct udev_rules *rules; - struct token end_token; - char **files, **f; +int udev_rules_new(struct udev_rules **ret_rules, ResolveNameTiming resolve_name_timing) { + _cleanup_(udev_rules_freep) struct udev_rules *rules = NULL; + _cleanup_strv_free_ char **files = NULL; + char **f; int r; assert(resolve_name_timing >= 0 && resolve_name_timing < _RESOLVE_NAME_TIMING_MAX); rules = new(struct udev_rules, 1); if (!rules) - return NULL; + return -ENOMEM; *rules = (struct udev_rules) { .resolve_name_timing = resolve_name_timing, @@ -1531,20 +1531,18 @@ struct udev_rules *udev_rules_new(ResolveNameTiming resolve_name_timing) { /* init token array and string buffer */ rules->tokens = malloc_multiply(PREALLOC_TOKEN, sizeof(struct token)); if (!rules->tokens) - return udev_rules_free(rules); + return -ENOMEM; rules->token_max = PREALLOC_TOKEN; rules->strbuf = strbuf_new(); if (!rules->strbuf) - return udev_rules_free(rules); + return -ENOMEM; udev_rules_check_timestamp(rules); r = conf_files_list_strv(&files, ".rules", NULL, 0, rules_dirs); - if (r < 0) { - log_error_errno(r, "Failed to enumerate rules files: %m"); - return udev_rules_free(rules); - } + if (r < 0) + return log_error_errno(r, "Failed to enumerate rules files: %m"); /* * The offset value in the rules strct is limited; add all @@ -1556,10 +1554,7 @@ struct udev_rules *udev_rules_new(ResolveNameTiming resolve_name_timing) { STRV_FOREACH(f, files) parse_file(rules, *f); - strv_free(files); - - memzero(&end_token, sizeof(struct token)); - end_token.type = TK_END; + struct token end_token = { .type = TK_END }; add_token(rules, &end_token); log_debug("Rules contain %zu bytes tokens (%u * %zu bytes), %zu bytes strings", rules->token_max * sizeof(struct token), rules->token_max, sizeof(struct token), rules->strbuf->len); @@ -1579,7 +1574,8 @@ struct udev_rules *udev_rules_new(ResolveNameTiming resolve_name_timing) { rules->gids_max = 0; dump_rules(rules); - return rules; + *ret_rules = TAKE_PTR(rules); + return 0; } struct udev_rules *udev_rules_free(struct udev_rules *rules) { diff --git a/src/udev/udev.h b/src/udev/udev.h index 27b335fd44..67e05e132f 100644 --- a/src/udev/udev.h +++ b/src/udev/udev.h @@ -47,8 +47,9 @@ struct udev_event { /* udev-rules.c */ struct udev_rules; -struct udev_rules *udev_rules_new(ResolveNameTiming resolve_name_timing); +int udev_rules_new(struct udev_rules **ret_rules, ResolveNameTiming resolve_name_timing); struct udev_rules *udev_rules_free(struct udev_rules *rules); + bool udev_rules_check_timestamp(struct udev_rules *rules); int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event, usec_t timeout_usec, diff --git a/src/udev/udevadm-test.c b/src/udev/udevadm-test.c index 005553cbb6..d649525dd3 100644 --- a/src/udev/udevadm-test.c +++ b/src/udev/udevadm-test.c @@ -110,10 +110,9 @@ int test_main(int argc, char *argv[], void *userdata) { udev_builtin_init(); - rules = udev_rules_new(arg_resolve_name_timing); - if (!rules) { - log_error("Failed to read udev rules."); - r = -ENOMEM; + r = udev_rules_new(&rules, arg_resolve_name_timing); + if (r < 0) { + log_error_errno(r, "Failed to read udev rules: %m"); goto out; } diff --git a/src/udev/udevd.c b/src/udev/udevd.c index fa85f6e263..44973a34b6 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c @@ -890,9 +890,11 @@ static void event_queue_start(Manager *manager) { udev_builtin_init(); if (!manager->rules) { - manager->rules = udev_rules_new(arg_resolve_name_timing); - if (!manager->rules) + r = udev_rules_new(&manager->rules, arg_resolve_name_timing); + if (r < 0) { + log_warning_errno(r, "Failed to read udev rules: %m"); return; + } } LIST_FOREACH(event, event, manager->events) { @@ -1608,9 +1610,9 @@ static int manager_new(Manager **ret, int fd_ctrl, int fd_uevent, const char *cg udev_builtin_init(); - manager->rules = udev_rules_new(arg_resolve_name_timing); + r = udev_rules_new(&manager->rules, arg_resolve_name_timing); if (!manager->rules) - return log_error_errno(SYNTHETIC_ERRNO(ENOMEM), "Failed to read udev rules"); + return log_error_errno(r, "Failed to read udev rules: %m"); manager->ctrl = udev_ctrl_new_from_fd(fd_ctrl); if (!manager->ctrl)