Skip to content

Commit c790632

Browse files
keszybzbluca
authored andcommitted
coredump: do not crash if we failed to acquire exe path
The COREDUMP_EXE attribute is "optional", i.e. we continue to process the crash even if we didn't acquire it. The coredump generation code assumed that it is always available: #5 endswith at ../src/fundamental/string-util-fundamental.c:41 [ endswith() is called with NULL here, and an assertion fails. ] #6 submit_coredump at ../src/coredump/coredump.c:823 #7 process_socket at ../src/coredump/coredump.c:1038 #8 run at ../src/coredump/coredump.c:1413 We use the exe path for loop detection, and also (ultimately) pass it to dwfl_core_file_report(). The latter seems to be fine will NULL, so let's just change our code to look at COMM, which should be more reliable anyway. Fixes https://bugzilla.redhat.com/show_bug.cgi?id=2036517.
1 parent 73dfeb0 commit c790632

File tree

1 file changed

+22
-17
lines changed

1 file changed

+22
-17
lines changed

src/coredump/coredump.c

+22-17
Original file line numberDiff line numberDiff line change
@@ -812,16 +812,19 @@ static int submit_coredump(
812812
return log_error_errno(r, "Failed to drop privileges: %m");
813813

814814
/* Try to get a stack trace if we can */
815-
if (coredump_size > arg_process_size_max) {
815+
if (coredump_size > arg_process_size_max)
816816
log_debug("Not generating stack trace: core size %"PRIu64" is greater "
817817
"than %"PRIu64" (the configured maximum)",
818818
coredump_size, arg_process_size_max);
819-
} else if (coredump_fd >= 0)
819+
else if (coredump_fd >= 0) {
820+
bool skip = startswith(context->meta[META_COMM], "systemd-coredum"); /* COMM is 16 bytes usually */
821+
820822
(void) parse_elf_object(coredump_fd,
821823
context->meta[META_EXE],
822-
/* fork_disable_dump= */endswith(context->meta[META_EXE], "systemd-coredump"), /* avoid loops */
824+
/* fork_disable_dump= */ skip, /* avoid loops */
823825
&stacktrace,
824826
&json_metadata);
827+
}
825828

826829
log:
827830
core_message = strjoina("Process ", context->meta[META_ARGV_PID],
@@ -856,21 +859,24 @@ static int submit_coredump(
856859
(void) iovw_put_string_field(iovw, "COREDUMP_PACKAGE_JSON=", formatted_json);
857860
}
858861

859-
JSON_VARIANT_OBJECT_FOREACH(module_name, module_json, json_metadata) {
860-
JsonVariant *package_name, *package_version;
862+
/* In the unlikely scenario that context->meta[META_EXE] is not available,
863+
* let's avoid guessing the module name and skip the loop. */
864+
if (context->meta[META_EXE])
865+
JSON_VARIANT_OBJECT_FOREACH(module_name, module_json, json_metadata) {
866+
JsonVariant *t;
861867

862-
/* We only add structured fields for the 'main' ELF module */
863-
if (!path_equal_filename(module_name, context->meta[META_EXE]))
864-
continue;
868+
/* We only add structured fields for the 'main' ELF module, and only if we can identify it. */
869+
if (!path_equal_filename(module_name, context->meta[META_EXE]))
870+
continue;
865871

866-
package_name = json_variant_by_key(module_json, "name");
867-
if (package_name)
868-
(void) iovw_put_string_field(iovw, "COREDUMP_PACKAGE_NAME=", json_variant_string(package_name));
872+
t = json_variant_by_key(module_json, "name");
873+
if (t)
874+
(void) iovw_put_string_field(iovw, "COREDUMP_PACKAGE_NAME=", json_variant_string(t));
869875

870-
package_version = json_variant_by_key(module_json, "version");
871-
if (package_version)
872-
(void) iovw_put_string_field(iovw, "COREDUMP_PACKAGE_VERSION=", json_variant_string(package_version));
873-
}
876+
t = json_variant_by_key(module_json, "version");
877+
if (t)
878+
(void) iovw_put_string_field(iovw, "COREDUMP_PACKAGE_VERSION=", json_variant_string(t));
879+
}
874880

875881
/* Optionally store the entire coredump in the journal */
876882
if (arg_storage == COREDUMP_STORAGE_JOURNAL && coredump_fd >= 0) {
@@ -1180,7 +1186,7 @@ static int gather_pid_metadata(struct iovec_wrapper *iovw, Context *context) {
11801186
if (r < 0)
11811187
return r;
11821188

1183-
/* The following are optional but we used them if present */
1189+
/* The following are optional, but we use them if present. */
11841190
r = get_process_exe(pid, &t);
11851191
if (r >= 0)
11861192
r = iovw_put_string_field_free(iovw, "COREDUMP_EXE=", t);
@@ -1190,7 +1196,6 @@ static int gather_pid_metadata(struct iovec_wrapper *iovw, Context *context) {
11901196
if (cg_pid_get_unit(pid, &t) >= 0)
11911197
(void) iovw_put_string_field_free(iovw, "COREDUMP_UNIT=", t);
11921198

1193-
/* The next are optional */
11941199
if (cg_pid_get_user_unit(pid, &t) >= 0)
11951200
(void) iovw_put_string_field_free(iovw, "COREDUMP_USER_UNIT=", t);
11961201

0 commit comments

Comments
 (0)