🚨 CVE-2026-17505
The Translate Multilingual sites – TranslatePress plugin for WordPress is vulnerable to Reflected Cross-Site Scripting via the 's' parameter in versions up to, and including, 3.2.5. This is due to the translate_page() function unconditionally replacing the plugin's internal #!trpst# and #!trpen# marker tokens with literal angle brackets across the entire HTML page output after WordPress has already sanitized and escaped user input — allowing the attacker to bypass WordPress's normal HTML escaping by using these tokens, which are not HTML special characters, in the search query. This makes it possible for unauthenticated attackers to inject arbitrary web scripts in pages that execute if they can successfully trick a user into performing an action such as clicking on a specially crafted link.
🎖@cveNotify
The Translate Multilingual sites – TranslatePress plugin for WordPress is vulnerable to Reflected Cross-Site Scripting via the 's' parameter in versions up to, and including, 3.2.5. This is due to the translate_page() function unconditionally replacing the plugin's internal #!trpst# and #!trpen# marker tokens with literal angle brackets across the entire HTML page output after WordPress has already sanitized and escaped user input — allowing the attacker to bypass WordPress's normal HTML escaping by using these tokens, which are not HTML special characters, in the search query. This makes it possible for unauthenticated attackers to inject arbitrary web scripts in pages that execute if they can successfully trick a user into performing an action such as clicking on a specially crafted link.
🎖@cveNotify
🚨 CVE-2026-17532
The Seraphinite Accelerator plugin for WordPress is vulnerable to Reflected Cross-Site Scripting via the 'seraph_accel_prep' parameter in versions up to, and including, 2.29.15. This is due to the CacheExtractPreparePageParams() function using PHP's loose inequality operator (!=) to compare the expected HMAC string against the JSON-decoded 'nonce' value — supplying the JSON boolean true causes any non-empty HMAC string to compare as loosely equal, bypassing the signature check — combined with insufficient output escaping in the _CbContentFinishSkip() function, which concatenates the attacker-controlled 'selfTest' field directly into the HTML response body. This makes it possible for unauthenticated attackers to inject arbitrary web scripts in pages that execute if they can successfully trick a user into performing an action such as clicking on a specially crafted link.
🎖@cveNotify
The Seraphinite Accelerator plugin for WordPress is vulnerable to Reflected Cross-Site Scripting via the 'seraph_accel_prep' parameter in versions up to, and including, 2.29.15. This is due to the CacheExtractPreparePageParams() function using PHP's loose inequality operator (!=) to compare the expected HMAC string against the JSON-decoded 'nonce' value — supplying the JSON boolean true causes any non-empty HMAC string to compare as loosely equal, bypassing the signature check — combined with insufficient output escaping in the _CbContentFinishSkip() function, which concatenates the attacker-controlled 'selfTest' field directly into the HTML response body. This makes it possible for unauthenticated attackers to inject arbitrary web scripts in pages that execute if they can successfully trick a user into performing an action such as clicking on a specially crafted link.
🎖@cveNotify
🚨 CVE-2026-18881
The TableOn – WordPress Posts Table Filterable plugin for WordPress is vulnerable to blind SQL Injection via the `filter_data[comment_count]` parameter of the public `tableon_get_table_data` AJAX action in all versions up to, and including, 1.0.5.1. This is due to insufficient escaping on the user-supplied parameter and lack of sufficient preparation on the existing SQL query — the value is split on `:` and both halves are interpolated directly into a `posts_where` SQL clause without `intval()` casting or `$wpdb->prepare()`. This makes it possible for unauthenticated attackers to append additional SQL queries into the already-existing query that can be used to extract sensitive information from the database (researcher demonstrated extraction of database(), wp_users.user_login, and wp_users.user_pass).
🎖@cveNotify
The TableOn – WordPress Posts Table Filterable plugin for WordPress is vulnerable to blind SQL Injection via the `filter_data[comment_count]` parameter of the public `tableon_get_table_data` AJAX action in all versions up to, and including, 1.0.5.1. This is due to insufficient escaping on the user-supplied parameter and lack of sufficient preparation on the existing SQL query — the value is split on `:` and both halves are interpolated directly into a `posts_where` SQL clause without `intval()` casting or `$wpdb->prepare()`. This makes it possible for unauthenticated attackers to append additional SQL queries into the already-existing query that can be used to extract sensitive information from the database (researcher demonstrated extraction of database(), wp_users.user_login, and wp_users.user_pass).
🎖@cveNotify
🚨 CVE-2026-4431
The Easy Post Submission plugin for WordPress is vulnerable to unauthorized modification of data due to a missing capability check on the `create_post()` function in all versions up to, and including, 2.3.0. This is due to the `rbsm_submit_post` AJAX action being registered for unauthenticated users via `wp_ajax_nopriv_rbsm_submit_post` without any authorization checks when a `postId` parameter is supplied. This makes it possible for unauthenticated attackers to modify the title, content, excerpt, categories, and tags of arbitrary posts, as well as change the post status to draft (effectively unpublishing them) via the 'postId' parameter.
🎖@cveNotify
The Easy Post Submission plugin for WordPress is vulnerable to unauthorized modification of data due to a missing capability check on the `create_post()` function in all versions up to, and including, 2.3.0. This is due to the `rbsm_submit_post` AJAX action being registered for unauthenticated users via `wp_ajax_nopriv_rbsm_submit_post` without any authorization checks when a `postId` parameter is supplied. This makes it possible for unauthenticated attackers to modify the title, content, excerpt, categories, and tags of arbitrary posts, as well as change the post status to draft (effectively unpublishing them) via the 'postId' parameter.
🎖@cveNotify
🚨 CVE-2026-54416
Pluck CMS through 4.7.21 restricts dangerous file uploads in its admin file-management feature using a fixed blacklist in data/inc/files.php ('.php','php3','php4','php5','php6','php7','phtml','.phtm','.pht','.ph3','.ph4','.ph5','.asp','.cgi','.phar'), checked against the last 4-5 characters of the filename. The blacklist omits the '.php8' extension. An authenticated administrator can upload a file named e.g. shell.php8, which is stored unmodified and, on servers running PHP 8.x, is executed as PHP by the web server, resulting in remote code execution.
🎖@cveNotify
Pluck CMS through 4.7.21 restricts dangerous file uploads in its admin file-management feature using a fixed blacklist in data/inc/files.php ('.php','php3','php4','php5','php6','php7','phtml','.phtm','.pht','.ph3','.ph4','.ph5','.asp','.cgi','.phar'), checked against the last 4-5 characters of the filename. The blacklist omits the '.php8' extension. An authenticated administrator can upload a file named e.g. shell.php8, which is stored unmodified and, on servers running PHP 8.x, is executed as PHP by the web server, resulting in remote code execution.
🎖@cveNotify
GitHub
GitHub - pluck-cms/pluck: Central repo for pluck cms
Central repo for pluck cms. Contribute to pluck-cms/pluck development by creating an account on GitHub.
🚨 CVE-2026-55739
Crater isolates data per company_id, and its Invoice/Estimate/Payment/Expense policies enforce both a Bouncer ability check and $user->hasCompany($model->company_id). CustomerPolicy's view/update/delete methods omit the company-ownership check entirely, checking only the blanket ability. Route-model-bound customer lookups and the bulk Customer::deleteCustomers() method are similarly unscoped (self::find($id) with no company filter). Any authenticated user of one company can read, reassign (steal), or delete another company's customer records, with deletion cascading to that customer's invoices and payments.
🎖@cveNotify
Crater isolates data per company_id, and its Invoice/Estimate/Payment/Expense policies enforce both a Bouncer ability check and $user->hasCompany($model->company_id). CustomerPolicy's view/update/delete methods omit the company-ownership check entirely, checking only the blanket ability. Route-model-bound customer lookups and the bulk Customer::deleteCustomers() method are similarly unscoped (self::find($id) with no company filter). Any authenticated user of one company can read, reassign (steal), or delete another company's customer records, with deletion cascading to that customer's invoices and payments.
🎖@cveNotify
GitHub
GitHub - crater-invoice-inc/crater: Open Source Invoicing Solution for Individuals & Businesses
Open Source Invoicing Solution for Individuals & Businesses - crater-invoice-inc/crater
🚨 CVE-2026-55747
The pocketflow-coding-agent cookbook example in The-Pocket/PocketFlow implements a `_path(workdir, p)` helper as a thin os.path.join(workdir, p) wrapper with no canonicalization or containment check, used unguarded by the ReadFile, ListFiles, PatchRead, and PatchApply file-access tools. Because os.path.join returns an absolute `p` unchanged (ignoring workdir) and does not resolve '../' sequences, an agent invocation whose file-tool arguments include an absolute path or a traversal sequence can read or write files outside the configured working directory. Severity reflects that this affects an illustrative cookbook example rather than a core library API; applications that copy this pattern into production are affected.
🎖@cveNotify
The pocketflow-coding-agent cookbook example in The-Pocket/PocketFlow implements a `_path(workdir, p)` helper as a thin os.path.join(workdir, p) wrapper with no canonicalization or containment check, used unguarded by the ReadFile, ListFiles, PatchRead, and PatchApply file-access tools. Because os.path.join returns an absolute `p` unchanged (ignoring workdir) and does not resolve '../' sequences, an agent invocation whose file-tool arguments include an absolute path or a traversal sequence can read or write files outside the configured working directory. Severity reflects that this affects an illustrative cookbook example rather than a core library API; applications that copy this pattern into production are affected.
🎖@cveNotify
GitHub
GitHub - The-Pocket/PocketFlow: Pocket Flow: 100-line LLM framework. Let Agents build Agents!
Pocket Flow: 100-line LLM framework. Let Agents build Agents! - The-Pocket/PocketFlow
🚨 CVE-2026-55996
A denial-of-service vulnerability was identified in multiple TLS listeners in Rancher. Both the cattle-cluster-agent component running in downstream clusters and the Rancher server itself use the dynamiclistener library to serve TLS traffic. Without an effective CN filter configured, dynamiclistener automatically appended to each serving certificate any hostname presented via Server Name Indication (SNI) in incoming TLS requests.
An unauthenticated attacker with network access within the affected cluster could send a large number of TLS requests with distinct hostnames, causing the serving certificate to accumulate an unbounded number of Subject Alternative Names (SANs). Eventually, the certificate grows large enough that TLS handshakes fail with an excessive message size error, causing a denial of service on the affected listeners.
🎖@cveNotify
A denial-of-service vulnerability was identified in multiple TLS listeners in Rancher. Both the cattle-cluster-agent component running in downstream clusters and the Rancher server itself use the dynamiclistener library to serve TLS traffic. Without an effective CN filter configured, dynamiclistener automatically appended to each serving certificate any hostname presented via Server Name Indication (SNI) in incoming TLS requests.
An unauthenticated attacker with network access within the affected cluster could send a large number of TLS requests with distinct hostnames, causing the serving certificate to accumulate an unbounded number of Subject Alternative Names (SANs). Eventually, the certificate grows large enough that TLS handshakes fail with an excessive message size error, causing a denial of service on the affected listeners.
🎖@cveNotify
🚨 CVE-2026-55997
Rancher issues long-lived registration tokens to authenticate nodes and agents joining a downstream cluster. These tokens were stored and exposed in plaintext with no expiration, so a malicious user could obtain one either through the Rancher API, etcd, stored automation, or direct file access on a node, and could use it at any time to register a rogue node into the cluster.
🎖@cveNotify
Rancher issues long-lived registration tokens to authenticate nodes and agents joining a downstream cluster. These tokens were stored and exposed in plaintext with no expiration, so a malicious user could obtain one either through the Rancher API, etcd, stored automation, or direct file access on a node, and could use it at any time to register a rogue node into the cluster.
🎖@cveNotify
🚨 CVE-2026-55998
The endpoint /v3/import/{token}_{clusterId}.yaml retrieves the cluster object before validating the token. When a valid cluster ID references a cluster that has private registry secrets configured, a nil pointer dereference in pkg/systemtemplate/private_registry.go causes the request to return HTTP 502 Bad Gateway. For cluster IDs that do not exist, the endpoint returns HTTP 200. This observable difference in response codes constitutes a reliable enumeration oracle.
🎖@cveNotify
The endpoint /v3/import/{token}_{clusterId}.yaml retrieves the cluster object before validating the token. When a valid cluster ID references a cluster that has private registry secrets configured, a nil pointer dereference in pkg/systemtemplate/private_registry.go causes the request to return HTTP 502 Bad Gateway. For cluster IDs that do not exist, the endpoint returns HTTP 200. This observable difference in response codes constitutes a reliable enumeration oracle.
🎖@cveNotify
🚨 CVE-2026-59675
When API audit logging is enabled, the middleware reads the entire HTTP request body into memory without enforcing a size limit on login endpoints. Because the audit middleware is positioned earlier in the handler chain than Rancher's APIBodyLimitingHandler, the body-size cap (default 1 MiB) is bypassed for requests that pass through the audit copyReqBody path. An unauthenticated attacker can send arbitrarily large request bodies to the public login endpoints, causing the Rancher Manager server process to allocate memory proportional to the supplied body size. With just a few concurrent connections, this can exhaust available memory and terminate the Rancher Manager plane process, making the Rancher API and UI unavailable and interrupting management of all downstream clusters.
🎖@cveNotify
When API audit logging is enabled, the middleware reads the entire HTTP request body into memory without enforcing a size limit on login endpoints. Because the audit middleware is positioned earlier in the handler chain than Rancher's APIBodyLimitingHandler, the body-size cap (default 1 MiB) is bypassed for requests that pass through the audit copyReqBody path. An unauthenticated attacker can send arbitrarily large request bodies to the public login endpoints, causing the Rancher Manager server process to allocate memory proportional to the supplied body size. With just a few concurrent connections, this can exhaust available memory and terminate the Rancher Manager plane process, making the Rancher API and UI unavailable and interrupting management of all downstream clusters.
🎖@cveNotify
🚨 CVE-2026-5108
The Super Progressive Web Apps plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the `superpwa_settings[offline_message_txt]` setting in all versions up to, and including, 2.2.43. This is due to insufficient input sanitization and output escaping. The offline message value is stored without sanitization, passed to the frontend via `wp_localize_script()` without escaping, and rendered using `innerHTML` in the JavaScript snackbar component. This makes it possible for authenticated attackers, with Administrator-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user triggers the offline snackbar.
🎖@cveNotify
The Super Progressive Web Apps plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the `superpwa_settings[offline_message_txt]` setting in all versions up to, and including, 2.2.43. This is due to insufficient input sanitization and output escaping. The offline message value is stored without sanitization, passed to the frontend via `wp_localize_script()` without escaping, and rendered using `innerHTML` in the JavaScript snackbar component. This makes it possible for authenticated attackers, with Administrator-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user triggers the offline snackbar.
🎖@cveNotify
🚨 CVE-2026-5116
The Contact Form 7 – Dynamic Text Extension plugin for WordPress is vulnerable to Stored Cross-Site Scripting in all versions up to, and including, 5.0.5. This is due to insufficient output escaping on form shortcode keys displayed in the admin "Scan Forms for Post Meta and User Data Keys" page. This makes it possible for authenticated attackers, with Editor-level access and above, to inject arbitrary web scripts that execute when an Administrator runs the scan feature.
🎖@cveNotify
The Contact Form 7 – Dynamic Text Extension plugin for WordPress is vulnerable to Stored Cross-Site Scripting in all versions up to, and including, 5.0.5. This is due to insufficient output escaping on form shortcode keys displayed in the admin "Scan Forms for Post Meta and User Data Keys" page. This makes it possible for authenticated attackers, with Editor-level access and above, to inject arbitrary web scripts that execute when an Administrator runs the scan feature.
🎖@cveNotify
🚨 CVE-2026-5581
The Multi Uploader for Gravity Forms plugin for WordPress is vulnerable to unauthorized arbitrary media deletion in all versions up to, and including, 1.1.8. This is due to missing capability checks in the `plupload_ajax_delete_file()` function, which is registered via `wp_ajax_nopriv_gfmu_delete_file`. The nonce intended for CSRF protection is exposed on any public-facing page containing a multi-uploader form field via the `GFMU_options` JavaScript object. This makes it possible for unauthenticated attackers to permanently delete any WordPress media attachment by supplying its attachment ID, potentially leading to complete media library destruction.
🎖@cveNotify
The Multi Uploader for Gravity Forms plugin for WordPress is vulnerable to unauthorized arbitrary media deletion in all versions up to, and including, 1.1.8. This is due to missing capability checks in the `plupload_ajax_delete_file()` function, which is registered via `wp_ajax_nopriv_gfmu_delete_file`. The nonce intended for CSRF protection is exposed on any public-facing page containing a multi-uploader form field via the `GFMU_options` JavaScript object. This makes it possible for unauthenticated attackers to permanently delete any WordPress media attachment by supplying its attachment ID, potentially leading to complete media library destruction.
🎖@cveNotify
🚨 CVE-2026-5651
The Askeet plugin for WordPress is vulnerable to SQL Injection via the 'sql_query' parameter in multiple AJAX actions (askeet_execute_sql_query, askeet_export_all_results) in all versions up to, and including, 3.0. This is due to the askeet_is_safe_query() filter being bypassable using MySQL conditional comments (e.g., /*!UNION*/). The filter strips regular block comments before checking for forbidden SQL keywords, but MySQL interprets conditional comments as executable code. This makes it possible for authenticated attackers, with Administrator-level access and above, to append additional SQL queries into already existing queries that can be used to extract sensitive information from the database.
🎖@cveNotify
The Askeet plugin for WordPress is vulnerable to SQL Injection via the 'sql_query' parameter in multiple AJAX actions (askeet_execute_sql_query, askeet_export_all_results) in all versions up to, and including, 3.0. This is due to the askeet_is_safe_query() filter being bypassable using MySQL conditional comments (e.g., /*!UNION*/). The filter strips regular block comments before checking for forbidden SQL keywords, but MySQL interprets conditional comments as executable code. This makes it possible for authenticated attackers, with Administrator-level access and above, to append additional SQL queries into already existing queries that can be used to extract sensitive information from the database.
🎖@cveNotify
🚨 CVE-2026-61483
** UNSUPPORTED WHEN ASSIGNED ** Uncontrolled Recursion vulnerability in Apache Lucy.
This issue affects Apache Lucy: all versions.
As this project is retired, we do not plan to release a version that fixes this issue. Users are recommended to find an alternative or restrict access to the instance to trusted users.
NOTE: This vulnerability only affects products that are no longer supported by the maintainer.
🎖@cveNotify
** UNSUPPORTED WHEN ASSIGNED ** Uncontrolled Recursion vulnerability in Apache Lucy.
This issue affects Apache Lucy: all versions.
As this project is retired, we do not plan to release a version that fixes this issue. Users are recommended to find an alternative or restrict access to the instance to trusted users.
NOTE: This vulnerability only affects products that are no longer supported by the maintainer.
🎖@cveNotify
🚨 CVE-2026-61484
** UNSUPPORTED WHEN ASSIGNED ** Deserialization of Untrusted Data vulnerability in Apache Lucy.
This issue affects Apache Lucy: all versions.
As this project is retired, we do not plan to release a version that fixes this issue. Users are recommended to find an alternative or restrict access to the instance to trusted users.
NOTE: This vulnerability only affects products that are no longer supported by the maintainer.
🎖@cveNotify
** UNSUPPORTED WHEN ASSIGNED ** Deserialization of Untrusted Data vulnerability in Apache Lucy.
This issue affects Apache Lucy: all versions.
As this project is retired, we do not plan to release a version that fixes this issue. Users are recommended to find an alternative or restrict access to the instance to trusted users.
NOTE: This vulnerability only affects products that are no longer supported by the maintainer.
🎖@cveNotify
🚨 CVE-2026-61485
** UNSUPPORTED WHEN ASSIGNED ** Memory Allocation with Excessive Size Value vulnerability in Apache Lucy.
This issue affects Apache Lucy: all versions.
As this project is retired, we do not plan to release a version that fixes this issue. Users are recommended to find an alternative or restrict access to the instance to trusted users.
NOTE: This vulnerability only affects products that are no longer supported by the maintainer.
🎖@cveNotify
** UNSUPPORTED WHEN ASSIGNED ** Memory Allocation with Excessive Size Value vulnerability in Apache Lucy.
This issue affects Apache Lucy: all versions.
As this project is retired, we do not plan to release a version that fixes this issue. Users are recommended to find an alternative or restrict access to the instance to trusted users.
NOTE: This vulnerability only affects products that are no longer supported by the maintainer.
🎖@cveNotify
🚨 CVE-2026-61486
** UNSUPPORTED WHEN ASSIGNED ** Stack-based Buffer Overflow vulnerability in Apache Lucy.
This issue affects Apache Lucy: all versions.
As this project is retired, we do not plan to release a version that fixes this issue. Users are recommended to find an alternative or restrict access to the instance to trusted users.
NOTE: This vulnerability only affects products that are no longer supported by the maintainer.
🎖@cveNotify
** UNSUPPORTED WHEN ASSIGNED ** Stack-based Buffer Overflow vulnerability in Apache Lucy.
This issue affects Apache Lucy: all versions.
As this project is retired, we do not plan to release a version that fixes this issue. Users are recommended to find an alternative or restrict access to the instance to trusted users.
NOTE: This vulnerability only affects products that are no longer supported by the maintainer.
🎖@cveNotify
🚨 CVE-2026-64566
In the Linux kernel, the following vulnerability has been resolved:
xfrm: iptfs: propagate SKBFL_SHARED_FRAG in iptfs_skb_add_frags()
When iptfs_skb_add_frags() copies frag references from the source
frag walk into a new SKB, it increments the page reference count via
__skb_frag_ref() but does not propagate SKBFL_SHARED_FRAG to the
destination SKB's skb_shinfo->flags.
If the source SKB carries shared frags (e.g. from a page-pool backed
receive path), the new inner SKB will appear to ESP as having privately
owned frags. A subsequent esp_input() call for a nested transport-mode
SA then takes the no-COW fast path and decrypts in place, writing over
pages that are still referenced by the outer IPTFS SKB. This causes
kernel-visible memory corruption and can trigger a panic.
All other frag-transfer helpers in the kernel (skb_try_coalesce,
skb_gro_receive, __pskb_copy_fclone, skb_shift, skb_segment) correctly
propagate SKBFL_SHARED_FRAG; align iptfs_skb_add_frags() with this
convention by setting the flag inside the loop immediately after
__skb_frag_ref() and nr_frags++, so every exit path that attaches a frag
unconditionally propagates SKBFL_SHARED_FRAG.
🎖@cveNotify
In the Linux kernel, the following vulnerability has been resolved:
xfrm: iptfs: propagate SKBFL_SHARED_FRAG in iptfs_skb_add_frags()
When iptfs_skb_add_frags() copies frag references from the source
frag walk into a new SKB, it increments the page reference count via
__skb_frag_ref() but does not propagate SKBFL_SHARED_FRAG to the
destination SKB's skb_shinfo->flags.
If the source SKB carries shared frags (e.g. from a page-pool backed
receive path), the new inner SKB will appear to ESP as having privately
owned frags. A subsequent esp_input() call for a nested transport-mode
SA then takes the no-COW fast path and decrypts in place, writing over
pages that are still referenced by the outer IPTFS SKB. This causes
kernel-visible memory corruption and can trigger a panic.
All other frag-transfer helpers in the kernel (skb_try_coalesce,
skb_gro_receive, __pskb_copy_fclone, skb_shift, skb_segment) correctly
propagate SKBFL_SHARED_FRAG; align iptfs_skb_add_frags() with this
convention by setting the flag inside the loop immediately after
__skb_frag_ref() and nr_frags++, so every exit path that attaches a frag
unconditionally propagates SKBFL_SHARED_FRAG.
🎖@cveNotify
🚨 CVE-2026-64567
In the Linux kernel, the following vulnerability has been resolved:
btrfs: reject free space cache with more entries than pages
When loading a v1 free space cache, __load_free_space_cache() takes
num_entries and num_bitmaps straight from the on-disk
btrfs_free_space_header. That header is stored in the tree_root under a key
with type 0, which the tree-checker has no case for, so neither count is
validated before the load trusts it.
The load loops num_entries times and maps the next page whenever the current
one runs out, going through io_ctl_check_crc() -> io_ctl_map_page(), which
does io_ctl->pages[io_ctl->index++]. But pages[] is allocated in
io_ctl_init() from the cache inode's i_size, not from num_entries:
num_pages = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);
io_ctl->pages = kcalloc(num_pages, sizeof(struct page *), GFP_NOFS);
So if num_entries claims more records than the pages can hold, io_ctl->index
runs off the end of pages[]. The write side never hits this because
io_ctl_add_entry() and io_ctl_add_bitmap() both stop once
io_ctl->index >= io_ctl->num_pages; the read side just never had the same
check.
To trigger it, take a clean cache (num_entries = <N> here), set num_entries
in the header to 0x10000, and fix up the leaf checksum so it still passes
the tree-checker. The cache inode has i_size = 65536, so num_pages is 16 and
pages[] is a 16-pointer (kmalloc-128) array. The load now tries to read
65536 entries, io_ctl->index walks up to 16, and pages[16] is read past the
array:
BUG: KASAN: slab-out-of-bounds in io_ctl_check_crc (fs/btrfs/free-space-cache.c:420 fs/btrfs/free-space-cache.c:565)
Read of size 8 at addr ffff88800c833a80 by task kworker/u8:3/58
io_ctl_check_crc (fs/btrfs/free-space-cache.c:420 fs/btrfs/free-space-cache.c:565)
__load_free_space_cache (fs/btrfs/free-space-cache.c:655 fs/btrfs/free-space-cache.c:820)
load_free_space_cache (fs/btrfs/free-space-cache.c:1017)
caching_thread (fs/btrfs/block-group.c:880)
btrfs_work_helper (fs/btrfs/async-thread.c:312)
process_one_work
worker_thread
kthread
ret_from_fork
free-space-cache.c:420 is io_ctl_map_page(), inlined into io_ctl_check_crc()
at line 565, which is why that is the frame KASAN names. The out-of-bounds
slot is then treated as a struct page and handed to crc32c(), so the bad
read turns into a GP fault.
Add the missing check to io_ctl_check_crc(), which is where both the entry
loop and the bitmap loop end up. When num_entries is too large the load now
fails like any corrupt cache: __load_free_space_cache() drops it and rebuilds
the free space from the extent tree, so a valid cache is never rejected.
🎖@cveNotify
In the Linux kernel, the following vulnerability has been resolved:
btrfs: reject free space cache with more entries than pages
When loading a v1 free space cache, __load_free_space_cache() takes
num_entries and num_bitmaps straight from the on-disk
btrfs_free_space_header. That header is stored in the tree_root under a key
with type 0, which the tree-checker has no case for, so neither count is
validated before the load trusts it.
The load loops num_entries times and maps the next page whenever the current
one runs out, going through io_ctl_check_crc() -> io_ctl_map_page(), which
does io_ctl->pages[io_ctl->index++]. But pages[] is allocated in
io_ctl_init() from the cache inode's i_size, not from num_entries:
num_pages = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);
io_ctl->pages = kcalloc(num_pages, sizeof(struct page *), GFP_NOFS);
So if num_entries claims more records than the pages can hold, io_ctl->index
runs off the end of pages[]. The write side never hits this because
io_ctl_add_entry() and io_ctl_add_bitmap() both stop once
io_ctl->index >= io_ctl->num_pages; the read side just never had the same
check.
To trigger it, take a clean cache (num_entries = <N> here), set num_entries
in the header to 0x10000, and fix up the leaf checksum so it still passes
the tree-checker. The cache inode has i_size = 65536, so num_pages is 16 and
pages[] is a 16-pointer (kmalloc-128) array. The load now tries to read
65536 entries, io_ctl->index walks up to 16, and pages[16] is read past the
array:
BUG: KASAN: slab-out-of-bounds in io_ctl_check_crc (fs/btrfs/free-space-cache.c:420 fs/btrfs/free-space-cache.c:565)
Read of size 8 at addr ffff88800c833a80 by task kworker/u8:3/58
io_ctl_check_crc (fs/btrfs/free-space-cache.c:420 fs/btrfs/free-space-cache.c:565)
__load_free_space_cache (fs/btrfs/free-space-cache.c:655 fs/btrfs/free-space-cache.c:820)
load_free_space_cache (fs/btrfs/free-space-cache.c:1017)
caching_thread (fs/btrfs/block-group.c:880)
btrfs_work_helper (fs/btrfs/async-thread.c:312)
process_one_work
worker_thread
kthread
ret_from_fork
free-space-cache.c:420 is io_ctl_map_page(), inlined into io_ctl_check_crc()
at line 565, which is why that is the frame KASAN names. The out-of-bounds
slot is then treated as a struct page and handed to crc32c(), so the bad
read turns into a GP fault.
Add the missing check to io_ctl_check_crc(), which is where both the entry
loop and the bitmap loop end up. When num_entries is too large the load now
fails like any corrupt cache: __load_free_space_cache() drops it and rebuilds
the free space from the extent tree, so a valid cache is never rejected.
🎖@cveNotify