VYPR
Unrated severityNVD Advisory· Published May 28, 2026

CVE-2026-46149

CVE-2026-46149

Description

In the Linux kernel, the following vulnerability has been resolved:

scsi: target: configfs: Bound snprintf() return in tg_pt_gp_members_show()

target_tg_pt_gp_members_show() formats LUN paths with snprintf() into a 256-byte stack buffer, then will memcpy() cur_len bytes from that buffer. snprintf() returns the length the output would have had, which can exceed the buffer size when the fabric WWN is long because iSCSI IQN names can be up to 223 bytes. The check at the memcpy() site only guards the destination page write, not the source read, so memcpy() will read past the stack buffer and copy adjacent stack contents to the sysfs reader, which when CONFIG_FORTIFY_SOURCE is enabled, fortify_panic() will be triggered.

Commit 27e06650a5ea ("scsi: target: target_core_configfs: Add length check to avoid buffer overflow") added the same bound to the target_lu_gp_members_show() but the tg_pt_gp variant was missed so resolve that here.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

A stack buffer over-read in the Linux kernel's SCSI target configfs handler can leak adjacent memory contents when processing long iSCSI IQN names.

Vulnerability

In the Linux kernel's SCSI target subsystem, the function target_tg_pt_gp_members_show() in drivers/target/target_core_configfs.c writes formatted LUN paths into a 256-byte stack buffer using snprintf(). The snprintf() return value reflects the output size that would have been written, which can exceed the buffer size when the fabric WWN is long — iSCSI IQN names can reach 223 bytes. The code then calls memcpy() using that potentially oversized length (cur_len), copying past the stack buffer and exposing adjacent stack contents to sysfs readers. This flaw was introduced when a similar fix for target_lu_gp_members_show() (commit 27e06650a5ea) omitted the same bounds check for the port group variant [1].

Exploitation

An attacker with write access to the target configfs hierarchy can create or modify a target port group (tg_pt_gp) and assign it a long fabric WWN (for example, a 223-byte iSCSI IQN) through the /sys/kernel/config/target/ interface. When a user or process reads the members attribute of that port group via target_tg_pt_gp_members_show(), the kernel will execute an out-of-bounds memcpy() from the stack buffer. No elevated privileges beyond local configfs access are needed; the attack is local, requires no user interaction for the reading step (the read triggers the bug), and the overflow is deterministic given a sufficiently long WWN [1].

Impact

On kernels with CONFIG_FORTIFY_SOURCE enabled, the out-of-bounds read triggers a fortify_panic() kernel panic, causing a denial of service (system crash). On kernels without that protection, the memcpy() silently copies adjacent kernel stack memory into the output buffer returned to the sysfs reader, leading to an information disclosure of up to several hundred bytes of potentially sensitive stack data (e.g., function pointers, kernel addresses, or credentials). The attacker gains the ability to read arbitrary kernel stack memory from a local unprivileged context, bypassing KASLR or leaking information useful for further privilege escalation [1].

Mitigation

The fix is commit 72cc5ea7ef32bb5fa38bf0dd2e56fcd73aa8c89e in the Linux kernel stable tree, which adds a bounds check on the snprintf() return value so that cur_len never exceeds the stack buffer size. This commit is included in the applicable stable kernel releases (e.g., 6.x.y updates). Since this is a kernel bug fixed in a released patch, users should update to the latest stable kernel version that contains the commit. No KEV listing exists; no workaround is available other than reducing the length of fabric WWNs to under 256 bytes or applying the kernel patch [1].

AI Insight generated on May 28, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected products

2

Patches

10
72cc5ea7ef32

scsi: target: configfs: Bound snprintf() return in tg_pt_gp_members_show()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitGreg Kroah-HartmanApr 11, 2026Fixed in 6.12.88via kernel-cna
1 file changed · +1 2
  • drivers/target/target_core_configfs.c+1 2 modified
    diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
    index 5af0c64d6a55af..e347ed75d7551d 100644
    --- a/drivers/target/target_core_configfs.c
    +++ b/drivers/target/target_core_configfs.c
    @@ -3172,7 +3172,7 @@ static ssize_t target_tg_pt_gp_members_show(struct config_item *item,
     			config_item_name(&lun->lun_group.cg_item));
     		cur_len++; /* Extra byte for NULL terminator */
     
    -		if ((cur_len + len) > PAGE_SIZE) {
    +		if (cur_len > TG_PT_GROUP_NAME_BUF || (cur_len + len) > PAGE_SIZE) {
     			pr_warn("Ran out of lu_gp_show_attr"
     				"_members buffer\n");
     			break;
    -- 
    cgit 1.3-korg
    
    
    
1f678d13e939

scsi: target: configfs: Bound snprintf() return in tg_pt_gp_members_show()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitGreg Kroah-HartmanApr 11, 2026Fixed in 6.6.140via kernel-cna
1 file changed · +1 2
  • drivers/target/target_core_configfs.c+1 2 modified
    diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
    index a52a4ac735e10a..74a71c8d7ac1ee 100644
    --- a/drivers/target/target_core_configfs.c
    +++ b/drivers/target/target_core_configfs.c
    @@ -3134,7 +3134,7 @@ static ssize_t target_tg_pt_gp_members_show(struct config_item *item,
     			config_item_name(&lun->lun_group.cg_item));
     		cur_len++; /* Extra byte for NULL terminator */
     
    -		if ((cur_len + len) > PAGE_SIZE) {
    +		if (cur_len > TG_PT_GROUP_NAME_BUF || (cur_len + len) > PAGE_SIZE) {
     			pr_warn("Ran out of lu_gp_show_attr"
     				"_members buffer\n");
     			break;
    -- 
    cgit 1.3-korg
    
    
    
00d91bfdce50

scsi: target: configfs: Bound snprintf() return in tg_pt_gp_members_show()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitGreg Kroah-HartmanApr 11, 2026Fixed in 6.18.30via kernel-cna
1 file changed · +1 2
  • drivers/target/target_core_configfs.c+1 2 modified
    diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
    index a2bd2e81d2c68a..7e101344e27e08 100644
    --- a/drivers/target/target_core_configfs.c
    +++ b/drivers/target/target_core_configfs.c
    @@ -3170,7 +3170,7 @@ static ssize_t target_tg_pt_gp_members_show(struct config_item *item,
     			config_item_name(&lun->lun_group.cg_item));
     		cur_len++; /* Extra byte for NULL terminator */
     
    -		if ((cur_len + len) > PAGE_SIZE) {
    +		if (cur_len > TG_PT_GROUP_NAME_BUF || (cur_len + len) > PAGE_SIZE) {
     			pr_warn("Ran out of lu_gp_show_attr"
     				"_members buffer\n");
     			break;
    -- 
    cgit 1.3-korg
    
    
    
e501154f9d82

scsi: target: configfs: Bound snprintf() return in tg_pt_gp_members_show()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitGreg Kroah-HartmanApr 11, 2026Fixed in 7.0.7via kernel-cna
1 file changed · +1 2
  • drivers/target/target_core_configfs.c+1 2 modified
    diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
    index a1c91d4515bc56..84124b222a999d 100644
    --- a/drivers/target/target_core_configfs.c
    +++ b/drivers/target/target_core_configfs.c
    @@ -3227,7 +3227,7 @@ static ssize_t target_tg_pt_gp_members_show(struct config_item *item,
     			config_item_name(&lun->lun_group.cg_item));
     		cur_len++; /* Extra byte for NULL terminator */
     
    -		if ((cur_len + len) > PAGE_SIZE) {
    +		if (cur_len > TG_PT_GROUP_NAME_BUF || (cur_len + len) > PAGE_SIZE) {
     			pr_warn("Ran out of lu_gp_show_attr"
     				"_members buffer\n");
     			break;
    -- 
    cgit 1.3-korg
    
    
    
772a896a56e0

scsi: target: configfs: Bound snprintf() return in tg_pt_gp_members_show()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitGreg Kroah-HartmanApr 11, 2026Fixed in 7.1-rc3via kernel-cna
1 file changed · +1 2
  • drivers/target/target_core_configfs.c+1 2 modified
    diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
    index d93773b3227c3e..2b19a956007b73 100644
    --- a/drivers/target/target_core_configfs.c
    +++ b/drivers/target/target_core_configfs.c
    @@ -3249,7 +3249,7 @@ static ssize_t target_tg_pt_gp_members_show(struct config_item *item,
     			config_item_name(&lun->lun_group.cg_item));
     		cur_len++; /* Extra byte for NULL terminator */
     
    -		if ((cur_len + len) > PAGE_SIZE) {
    +		if (cur_len > TG_PT_GROUP_NAME_BUF || (cur_len + len) > PAGE_SIZE) {
     			pr_warn("Ran out of lu_gp_show_attr"
     				"_members buffer\n");
     			break;
    -- 
    cgit 1.3-korg
    
    
    
1f678d13e939

scsi: target: configfs: Bound snprintf() return in tg_pt_gp_members_show()

1 file changed · +1 2
  • drivers/target/target_core_configfs.c+1 2 modified
    diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
    index a52a4ac735e10a..74a71c8d7ac1ee 100644
    --- a/drivers/target/target_core_configfs.c
    +++ b/drivers/target/target_core_configfs.c
    @@ -3134,7 +3134,7 @@ static ssize_t target_tg_pt_gp_members_show(struct config_item *item,
     			config_item_name(&lun->lun_group.cg_item));
     		cur_len++; /* Extra byte for NULL terminator */
     
    -		if ((cur_len + len) > PAGE_SIZE) {
    +		if (cur_len > TG_PT_GROUP_NAME_BUF || (cur_len + len) > PAGE_SIZE) {
     			pr_warn("Ran out of lu_gp_show_attr"
     				"_members buffer\n");
     			break;
    -- 
    cgit 1.3-korg
    
    
    
00d91bfdce50

scsi: target: configfs: Bound snprintf() return in tg_pt_gp_members_show()

1 file changed · +1 2
  • drivers/target/target_core_configfs.c+1 2 modified
    diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
    index a2bd2e81d2c68a..7e101344e27e08 100644
    --- a/drivers/target/target_core_configfs.c
    +++ b/drivers/target/target_core_configfs.c
    @@ -3170,7 +3170,7 @@ static ssize_t target_tg_pt_gp_members_show(struct config_item *item,
     			config_item_name(&lun->lun_group.cg_item));
     		cur_len++; /* Extra byte for NULL terminator */
     
    -		if ((cur_len + len) > PAGE_SIZE) {
    +		if (cur_len > TG_PT_GROUP_NAME_BUF || (cur_len + len) > PAGE_SIZE) {
     			pr_warn("Ran out of lu_gp_show_attr"
     				"_members buffer\n");
     			break;
    -- 
    cgit 1.3-korg
    
    
    
72cc5ea7ef32

scsi: target: configfs: Bound snprintf() return in tg_pt_gp_members_show()

1 file changed · +1 2
  • drivers/target/target_core_configfs.c+1 2 modified
    diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
    index 5af0c64d6a55af..e347ed75d7551d 100644
    --- a/drivers/target/target_core_configfs.c
    +++ b/drivers/target/target_core_configfs.c
    @@ -3172,7 +3172,7 @@ static ssize_t target_tg_pt_gp_members_show(struct config_item *item,
     			config_item_name(&lun->lun_group.cg_item));
     		cur_len++; /* Extra byte for NULL terminator */
     
    -		if ((cur_len + len) > PAGE_SIZE) {
    +		if (cur_len > TG_PT_GROUP_NAME_BUF || (cur_len + len) > PAGE_SIZE) {
     			pr_warn("Ran out of lu_gp_show_attr"
     				"_members buffer\n");
     			break;
    -- 
    cgit 1.3-korg
    
    
    
772a896a56e0

scsi: target: configfs: Bound snprintf() return in tg_pt_gp_members_show()

1 file changed · +1 2
  • drivers/target/target_core_configfs.c+1 2 modified
    diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
    index d93773b3227c3e..2b19a956007b73 100644
    --- a/drivers/target/target_core_configfs.c
    +++ b/drivers/target/target_core_configfs.c
    @@ -3249,7 +3249,7 @@ static ssize_t target_tg_pt_gp_members_show(struct config_item *item,
     			config_item_name(&lun->lun_group.cg_item));
     		cur_len++; /* Extra byte for NULL terminator */
     
    -		if ((cur_len + len) > PAGE_SIZE) {
    +		if (cur_len > TG_PT_GROUP_NAME_BUF || (cur_len + len) > PAGE_SIZE) {
     			pr_warn("Ran out of lu_gp_show_attr"
     				"_members buffer\n");
     			break;
    -- 
    cgit 1.3-korg
    
    
    
e501154f9d82

scsi: target: configfs: Bound snprintf() return in tg_pt_gp_members_show()

1 file changed · +1 2
  • drivers/target/target_core_configfs.c+1 2 modified
    diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
    index a1c91d4515bc56..84124b222a999d 100644
    --- a/drivers/target/target_core_configfs.c
    +++ b/drivers/target/target_core_configfs.c
    @@ -3227,7 +3227,7 @@ static ssize_t target_tg_pt_gp_members_show(struct config_item *item,
     			config_item_name(&lun->lun_group.cg_item));
     		cur_len++; /* Extra byte for NULL terminator */
     
    -		if ((cur_len + len) > PAGE_SIZE) {
    +		if (cur_len > TG_PT_GROUP_NAME_BUF || (cur_len + len) > PAGE_SIZE) {
     			pr_warn("Ran out of lu_gp_show_attr"
     				"_members buffer\n");
     			break;
    -- 
    cgit 1.3-korg
    
    
    

Vulnerability mechanics

Root cause

"Missing bounds check on snprintf() return value allows out-of-bounds stack buffer read in target_tg_pt_gp_members_show()."

Attack vector

An attacker who can configure a long fabric WWN (e.g., an iSCSI IQN name up to 223 bytes) can cause `snprintf()` to return a value larger than the 256-byte stack buffer `TG_PT_GROUP_NAME_BUF`. The subsequent `memcpy()` reads `cur_len` bytes from that buffer, reading past its end and copying adjacent stack contents to the sysfs reader. When `CONFIG_FORTIFY_SOURCE` is enabled, this triggers a `fortify_panic()`; otherwise it leaks kernel stack memory. The attack requires the ability to create or influence a target port group with a sufficiently long WWN, which is a privileged operation on the SCSI target subsystem.

Affected code

The vulnerable function is `target_tg_pt_gp_members_show()` in `drivers/target/target_core_configfs.c` [patch_id=2898273]. It formats LUN paths via `snprintf()` into a 256-byte stack buffer (`TG_PT_GROUP_NAME_BUF`), then `memcpy()`s `cur_len` bytes from that buffer. The original bounds check only verified the destination page write (`(cur_len + len) > PAGE_SIZE`), not whether `cur_len` exceeded the stack buffer size.

What the fix does

The patch adds a second condition to the existing bounds check: `cur_len > TG_PT_GROUP_NAME_BUF` [patch_id=2898273]. This ensures that before `memcpy()` is called, the code verifies that the formatted length does not exceed the stack buffer size. If it does, the loop breaks with a warning, preventing the out-of-bounds read. The same fix was previously applied to the analogous `target_lu_gp_members_show()` function in commit 27e06650a5ea but was missed for the `tg_pt_gp` variant.

Preconditions

  • configAttacker must be able to configure a long fabric WWN (e.g., iSCSI IQN up to 223 bytes) on the SCSI target subsystem
  • configThe kernel must have CONFIG_FORTIFY_SOURCE enabled to trigger a panic; without it, the bug causes a stack memory leak
  • authA local user with privileges to create/modify target port groups is required

Generated on May 28, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.