{"id":"CVE-2026-12364","aliases":["EUVD-2026-58750","GHSA-h7rf-g9mg-g23f"],"status":"published","title":"Missing user-space pointer validation in logging syscall z_log_msg_static_create allows kernel memory disclosure and denial of service","description":"The user-space system-call verifier z_vrfy_z_log_msg_static_create() in subsys/logging/log_msg.c was a pure pass-through: it forwarded the caller-supplied source, desc, package, and data arguments directly to the kernel-mode implementation z_impl_z_log_msg_static_create() without performing any of the mandatory K_SYSCALL_* checks. Because z_log_msg_static_create() is declared __syscall, under CONFIG_USERSPACE any unprivileged user-mode thread can invoke it directly with fully attacker-controlled arguments.\n\nThe kernel-mode handler dereferences each of these untrusted values: frontend_runtime_filtering() reads through the source pointer as a struct log_source_dynamic_data, cbprintf_package_copy() reads desc.package_len bytes from the package pointer, and z_log_msg_finalize() performs a memcpy() of desc.data_len bytes from the data pointer. With no verification, a user thread can supply arbitrary kernel addresses and arbitrary lengths, and the kernel will read from them.\n\nThe impact is a kernel-mode denial of service (the kernel faults dereferencing an attacker-chosen pointer) and, where a log backend output is observable to the attacker, disclosure of arbitrary kernel memory copied into the emitted log message — a confidentiality breach across the user/kernel boundary that the userspace sandbox is meant to enforce. The reads do not corrupt kernel memory, so there is no out-of-bounds write primitive.\n\nThe fix adds the required validation to the verifier: it bounds desc.package_len against Z_LOG_MSG_MAX_PACKAGE, rejects non-NULL/length mismatches, and applies K_SYSCALL_MEMORY_READ() to package, data, and (when runtime filtering with a frontend is enabled) source, so any out-of-bounds or kernel pointer now raises K_OOPS instead of being honored.","severity":{"version":"3.1","score":8.4,"vector":"CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:H","level":"high","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-10","score":0.00159,"percentile":0.05091,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":false},"cwes":["CWE-822"],"published":"2026-08-14T17:52:04Z","modified":"2026-11-04T04:59:30Z","products":[{"vendor":"zephyrproject","product":"zephyr"},{"vendor":"zephyrproject-rtos","product":"zephyr"}],"references":[{"url":"https://github.com/zephyrproject-rtos/zephyr/commit/77aa26d8b940f39778154f02563caf15d02efdac","tags":["patch","fix"]},{"url":"https://github.com/zephyrproject-rtos/zephyr/security/advisories/GHSA-h7rf-g9mg-g23f","tags":["advisory"]},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/12xxx/CVE-2026-12364.json","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-12364","tags":["advisory"]},{"url":"https://github.com/zephyrproject-rtos/zephyr","tags":["package"]}],"sources":{"cve":[{"id":"CVE-2026-12364","title":"Missing user-space pointer validation in logging syscall z_log_msg_static_create allows kernel memory disclosure and denial of service","description":"The user-space system-call verifier z_vrfy_z_log_msg_static_create() in subsys/logging/log_msg.c was a pure pass-through: it forwarded the caller-supplied source, desc, package, and data arguments directly to the kernel-mode implementation z_impl_z_log_msg_static_create() without performing any of the mandatory K_SYSCALL_* checks. Because z_log_msg_static_create() is declared __syscall, under CONFIG_USERSPACE any unprivileged user-mode thread can invoke it directly with fully attacker-controlled arguments.\n\nThe kernel-mode handler dereferences each of these untrusted values: frontend_runtime_filtering() reads through the source pointer as a struct log_source_dynamic_data, cbprintf_package_copy() reads desc.package_len bytes from the package pointer, and z_log_msg_finalize() performs a memcpy() of desc.data_len bytes from the data pointer. With no verification, a user thread can supply arbitrary kernel addresses and arbitrary lengths, and the kernel will read from them.\n\nThe impact is a kernel-mode denial of service (the kernel faults dereferencing an attacker-chosen pointer) and, where a log backend output is observable to the attacker, disclosure of arbitrary kernel memory copied into the emitted log message — a confidentiality breach across the user/kernel boundary that the userspace sandbox is meant to enforce. The reads do not corrupt kernel memory, so there is no out-of-bounds write primitive.\n\nThe fix adds the required validation to the verifier: it bounds desc.package_len against Z_LOG_MSG_MAX_PACKAGE, rejects non-NULL/length mismatches, and applies K_SYSCALL_MEMORY_READ() to package, data, and (when runtime filtering with a frontend is enabled) source, so any out-of-bounds or kernel pointer now raises K_OOPS instead of being honored.","status":"published","published":"2026-08-14T17:52:04.799Z","modified":"2026-11-04T04:59:30.788Z","cvss":[{"version":"3.1","score":8.4,"vector":"CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:H","level":"high","assessor":"cna"}],"cwes":["CWE-822"],"updated_at":"2026-11-04T05:21:48.223566Z"}],"euvd":[{"id":"EUVD-2026-58750","description":"The user-space system-call verifier z_vrfy_z_log_msg_static_create() in subsys/logging/log_msg.c was a pure pass-through: it forwarded the caller-supplied source, desc, package, and data arguments directly to the kernel-mode implementation z_impl_z_log_msg_static_create() without performing any of the mandatory K_SYSCALL_* checks. Because z_log_msg_static_create() is declared __syscall, under CONFIG_USERSPACE any unprivileged user-mode thread can invoke it directly with fully attacker-controlled arguments.\n\nThe kernel-mode handler dereferences each of these untrusted values: frontend_runtime_filtering() reads through the source pointer as a struct log_source_dynamic_data, cbprintf_package_copy() reads desc.package_len bytes from the package pointer, and z_log_msg_finalize() performs a memcpy() of desc.data_len bytes from the data pointer. With no verification, a user thread can supply arbitrary kernel addresses and arbitrary lengths, and the kernel will read from them.\n\nThe impact is a kernel-mode denial of service (the kernel faults dereferencing an attacker-chosen pointer) and, where a log backend output is observable to the attacker, disclosure of arbitrary kernel memory copied into the emitted log message — a confidentiality breach across the user/kernel boundary that the userspace sandbox is meant to enforce. The reads do not corrupt kernel memory, so there is no out-of-bounds write primitive.\n\nThe fix adds the required validation to the verifier: it bounds desc.package_len against Z_LOG_MSG_MAX_PACKAGE, rejects non-NULL/length mismatches, and applies K_SYSCALL_MEMORY_READ() to package, data, and (when runtime filtering with a frontend is enabled) source, so any out-of-bounds or kernel pointer now raises K_OOPS instead of being honored.","status":"published","published":"2026-08-14T17:52:04Z","modified":"2026-11-04T04:59:30Z","cvss":[{"version":"3.1","score":8.4,"vector":"CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:H","level":"high"}],"updated_at":"2026-11-04T07:00:56.720215Z"}],"nvd":[{"id":"CVE-2026-12364","description":"The user-space system-call verifier z_vrfy_z_log_msg_static_create() in subsys/logging/log_msg.c was a pure pass-through: it forwarded the caller-supplied source, desc, package, and data arguments directly to the kernel-mode implementation z_impl_z_log_msg_static_create() without performing any of the mandatory K_SYSCALL_* checks. Because z_log_msg_static_create() is declared __syscall, under CONFIG_USERSPACE any unprivileged user-mode thread can invoke it directly with fully attacker-controlled arguments.\n\nThe kernel-mode handler dereferences each of these untrusted values: frontend_runtime_filtering() reads through the source pointer as a struct log_source_dynamic_data, cbprintf_package_copy() reads desc.package_len bytes from the package pointer, and z_log_msg_finalize() performs a memcpy() of desc.data_len bytes from the data pointer. With no verification, a user thread can supply arbitrary kernel addresses and arbitrary lengths, and the kernel will read from them.\n\nThe impact is a kernel-mode denial of service (the kernel faults dereferencing an attacker-chosen pointer) and, where a log backend output is observable to the attacker, disclosure of arbitrary kernel memory copied into the emitted log message — a confidentiality breach across the user/kernel boundary that the userspace sandbox is meant to enforce. The reads do not corrupt kernel memory, so there is no out-of-bounds write primitive.\n\nThe fix adds the required validation to the verifier: it bounds desc.package_len against Z_LOG_MSG_MAX_PACKAGE, rejects non-NULL/length mismatches, and applies K_SYSCALL_MEMORY_READ() to package, data, and (when runtime filtering with a frontend is enabled) source, so any out-of-bounds or kernel pointer now raises K_OOPS instead of being honored.","status":"published","published":"2026-08-14T18:17:21.82Z","modified":"2026-11-04T05:18:39.043Z","cvss":[{"version":"3.1","score":8.4,"vector":"CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:H","level":"high","assessor":"secondary"}],"cwes":["CWE-822"],"updated_at":"2026-11-04T06:53:20.502063Z"}],"osv":[{"id":"CVE-2026-12364","title":"Missing user-space pointer validation in logging syscall z_log_msg_static_create allows kernel memory disclosure and denial of service","description":"The user-space system-call verifier z_vrfy_z_log_msg_static_create() in subsys/logging/log_msg.c was a pure pass-through: it forwarded the caller-supplied source, desc, package, and data arguments directly to the kernel-mode implementation z_impl_z_log_msg_static_create() without performing any of the mandatory K_SYSCALL_* checks. Because z_log_msg_static_create() is declared __syscall, under CONFIG_USERSPACE any unprivileged user-mode thread can invoke it directly with fully attacker-controlled arguments.\n\nThe kernel-mode handler dereferences each of these untrusted values: frontend_runtime_filtering() reads through the source pointer as a struct log_source_dynamic_data, cbprintf_package_copy() reads desc.package_len bytes from the package pointer, and z_log_msg_finalize() performs a memcpy() of desc.data_len bytes from the data pointer. With no verification, a user thread can supply arbitrary kernel addresses and arbitrary lengths, and the kernel will read from them.\n\nThe impact is a kernel-mode denial of service (the kernel faults dereferencing an attacker-chosen pointer) and, where a log backend output is observable to the attacker, disclosure of arbitrary kernel memory copied into the emitted log message — a confidentiality breach across the user/kernel boundary that the userspace sandbox is meant to enforce. The reads do not corrupt kernel memory, so there is no out-of-bounds write primitive.\n\nThe fix adds the required validation to the verifier: it bounds desc.package_len against Z_LOG_MSG_MAX_PACKAGE, rejects non-NULL/length mismatches, and applies K_SYSCALL_MEMORY_READ() to package, data, and (when runtime filtering with a frontend is enabled) source, so any out-of-bounds or kernel pointer now raises K_OOPS instead of being honored.","status":"published","published":"2026-08-14T17:52:04.799Z","modified":"2026-11-05T08:03:59.834480079Z","cvss":[{"version":"3.1","score":8.4,"vector":"CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:H","level":"high"}],"cwes":["CWE-822"],"updated_at":"2026-11-05T09:08:14.330889Z"}]}}
