CVE-2026-46264
Description
Linux kernel vulnerability in drm/xe/pf allows for kobject use-after-free during sysfs initialization, potentially leading to crashes.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Linux kernel vulnerability in drm/xe/pf allows for kobject use-after-free during sysfs initialization, potentially leading to crashes.
Vulnerability
A use-after-free vulnerability exists in the Linux kernel's drm/xe/pf subsystem during sysfs initialization. If devm_add_action_or_reset() fails, a cleanup action is immediately executed on a kobject that has not yet been fully initialized. This can lead to errors such as calling kobject_put() on an uninitialized kobject or a refcount underflow, affecting versions of the kernel where this issue was present before the fix. [1]
Exploitation
An attacker would need to trigger a specific error condition during the initialization of the drm/xe/pf sysfs entries. This typically requires kernel-level access or a specific hardware configuration that leads to the devm_add_action_or_reset() function failing, causing the subsequent incorrect kobject handling. The exact steps to trigger this failure are not detailed in the available references. [1]
Impact
Successful exploitation of this vulnerability can lead to kernel instability and crashes due to the use-after-free condition and refcount underflow. This could manifest as system hangs or unexpected reboots, potentially leading to denial of service. The precise impact on confidentiality or integrity is not specified beyond system instability. [1]
Mitigation
This vulnerability has been fixed in the Linux kernel by separating kobject_init() and kobject_add() calls and registering the cleanup action only after the kobject is initialized. The fix was cherry-picked from commit 98b16727f07e26a5d4de84d88805ce7ffcfdd324. Specific patched kernel versions are not listed, but users should update to the latest stable kernel that includes this commit. [1]
AI Insight generated on Jun 3, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
1Patches
56ae479b1919edrm/xe/pf: Fix sysfs initialization
1 file changed · +26 −29
drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c+26 −29 modifieddiff --git a/drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c b/drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c index c0b767ac735cf..d1c1f6c295664 100644 --- a/drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c +++ b/drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c @@ -349,18 +349,33 @@ static const struct attribute_group *xe_sriov_vf_attr_groups[] = { /* no user serviceable parts below */ -static struct kobject *create_xe_sriov_kobj(struct xe_device *xe, unsigned int vfid) +static void action_put_kobject(void *arg) +{ + struct kobject *kobj = arg; + + kobject_put(kobj); +} + +static struct kobject *create_xe_sriov_kobj(struct xe_device *xe, unsigned int vfid, + const struct kobj_type *ktype) { struct xe_sriov_kobj *vkobj; + int err; xe_sriov_pf_assert_vfid(xe, vfid); vkobj = kzalloc(sizeof(*vkobj), GFP_KERNEL); if (!vkobj) - return NULL; + return ERR_PTR(-ENOMEM); vkobj->xe = xe; vkobj->vfid = vfid; + kobject_init(&vkobj->base, ktype); + + err = devm_add_action_or_reset(xe->drm.dev, action_put_kobject, &vkobj->base); + if (err) + return ERR_PTR(err); + return &vkobj->base; } @@ -471,28 +486,17 @@ static void pf_sysfs_note(struct xe_device *xe, int err, const char *what) xe_sriov_dbg(xe, "Failed to setup sysfs %s (%pe)\n", what, ERR_PTR(err)); } -static void action_put_kobject(void *arg) -{ - struct kobject *kobj = arg; - - kobject_put(kobj); -} - static int pf_setup_root(struct xe_device *xe) { struct kobject *parent = &xe->drm.dev->kobj; struct kobject *root; int err; - root = create_xe_sriov_kobj(xe, PFID); - if (!root) - return pf_sysfs_error(xe, -ENOMEM, "root obj"); - - err = devm_add_action_or_reset(xe->drm.dev, action_put_kobject, root); - if (err) - return pf_sysfs_error(xe, err, "root action"); + root = create_xe_sriov_kobj(xe, PFID, &xe_sriov_dev_ktype); + if (IS_ERR(root)) + return pf_sysfs_error(xe, PTR_ERR(root), "root obj"); - err = kobject_init_and_add(root, &xe_sriov_dev_ktype, parent, "sriov_admin"); + err = kobject_add(root, parent, "sriov_admin"); if (err) return pf_sysfs_error(xe, err, "root init"); @@ -513,20 +517,14 @@ static int pf_setup_tree(struct xe_device *xe) root = xe->sriov.pf.sysfs.root; for (n = 0; n <= totalvfs; n++) { - kobj = create_xe_sriov_kobj(xe, VFID(n)); - if (!kobj) - return pf_sysfs_error(xe, -ENOMEM, "tree obj"); - - err = devm_add_action_or_reset(xe->drm.dev, action_put_kobject, root); - if (err) - return pf_sysfs_error(xe, err, "tree action"); + kobj = create_xe_sriov_kobj(xe, VFID(n), &xe_sriov_vf_ktype); + if (IS_ERR(kobj)) + return pf_sysfs_error(xe, PTR_ERR(kobj), "tree obj"); if (n) - err = kobject_init_and_add(kobj, &xe_sriov_vf_ktype, - root, "vf%u", n); + err = kobject_add(kobj, root, "vf%u", n); else - err = kobject_init_and_add(kobj, &xe_sriov_vf_ktype, - root, "pf"); + err = kobject_add(kobj, root, "pf"); if (err) return pf_sysfs_error(xe, err, "tree init"); -- cgit 1.3-korg
bf7172cd25eddrm/xe/pf: Fix sysfs initialization
1 file changed · +26 −29
drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c+26 −29 modifieddiff --git a/drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c b/drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c index 3d140506ba36b..82a1055985ba7 100644 --- a/drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c +++ b/drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c @@ -349,18 +349,33 @@ static const struct attribute_group *xe_sriov_vf_attr_groups[] = { /* no user serviceable parts below */ -static struct kobject *create_xe_sriov_kobj(struct xe_device *xe, unsigned int vfid) +static void action_put_kobject(void *arg) +{ + struct kobject *kobj = arg; + + kobject_put(kobj); +} + +static struct kobject *create_xe_sriov_kobj(struct xe_device *xe, unsigned int vfid, + const struct kobj_type *ktype) { struct xe_sriov_kobj *vkobj; + int err; xe_sriov_pf_assert_vfid(xe, vfid); vkobj = kzalloc(sizeof(*vkobj), GFP_KERNEL); if (!vkobj) - return NULL; + return ERR_PTR(-ENOMEM); vkobj->xe = xe; vkobj->vfid = vfid; + kobject_init(&vkobj->base, ktype); + + err = devm_add_action_or_reset(xe->drm.dev, action_put_kobject, &vkobj->base); + if (err) + return ERR_PTR(err); + return &vkobj->base; } @@ -463,28 +478,17 @@ static void pf_sysfs_note(struct xe_device *xe, int err, const char *what) xe_sriov_dbg(xe, "Failed to setup sysfs %s (%pe)\n", what, ERR_PTR(err)); } -static void action_put_kobject(void *arg) -{ - struct kobject *kobj = arg; - - kobject_put(kobj); -} - static int pf_setup_root(struct xe_device *xe) { struct kobject *parent = &xe->drm.dev->kobj; struct kobject *root; int err; - root = create_xe_sriov_kobj(xe, PFID); - if (!root) - return pf_sysfs_error(xe, -ENOMEM, "root obj"); - - err = devm_add_action_or_reset(xe->drm.dev, action_put_kobject, root); - if (err) - return pf_sysfs_error(xe, err, "root action"); + root = create_xe_sriov_kobj(xe, PFID, &xe_sriov_dev_ktype); + if (IS_ERR(root)) + return pf_sysfs_error(xe, PTR_ERR(root), "root obj"); - err = kobject_init_and_add(root, &xe_sriov_dev_ktype, parent, "sriov_admin"); + err = kobject_add(root, parent, "sriov_admin"); if (err) return pf_sysfs_error(xe, err, "root init"); @@ -505,20 +509,14 @@ static int pf_setup_tree(struct xe_device *xe) root = xe->sriov.pf.sysfs.root; for (n = 0; n <= totalvfs; n++) { - kobj = create_xe_sriov_kobj(xe, VFID(n)); - if (!kobj) - return pf_sysfs_error(xe, -ENOMEM, "tree obj"); - - err = devm_add_action_or_reset(xe->drm.dev, action_put_kobject, root); - if (err) - return pf_sysfs_error(xe, err, "tree action"); + kobj = create_xe_sriov_kobj(xe, VFID(n), &xe_sriov_vf_ktype); + if (IS_ERR(kobj)) + return pf_sysfs_error(xe, PTR_ERR(kobj), "tree obj"); if (n) - err = kobject_init_and_add(kobj, &xe_sriov_vf_ktype, - root, "vf%u", n); + err = kobject_add(kobj, root, "vf%u", n); else - err = kobject_init_and_add(kobj, &xe_sriov_vf_ktype, - root, "pf"); + err = kobject_add(kobj, root, "pf"); if (err) return pf_sysfs_error(xe, err, "tree init"); -- cgit 1.3-korg
98b16727f07edrm/xe/pf: Fix sysfs initialization
1 file changed · +26 −28
drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c+26 −28 modified@@ -349,18 +349,33 @@ static const struct attribute_group *xe_sriov_vf_attr_groups[] = { /* no user serviceable parts below */ -static struct kobject *create_xe_sriov_kobj(struct xe_device *xe, unsigned int vfid) +static void action_put_kobject(void *arg) +{ + struct kobject *kobj = arg; + + kobject_put(kobj); +} + +static struct kobject *create_xe_sriov_kobj(struct xe_device *xe, unsigned int vfid, + const struct kobj_type *ktype) { struct xe_sriov_kobj *vkobj; + int err; xe_sriov_pf_assert_vfid(xe, vfid); vkobj = kzalloc(sizeof(*vkobj), GFP_KERNEL); if (!vkobj) - return NULL; + return ERR_PTR(-ENOMEM); vkobj->xe = xe; vkobj->vfid = vfid; + kobject_init(&vkobj->base, ktype); + + err = devm_add_action_or_reset(xe->drm.dev, action_put_kobject, &vkobj->base); + if (err) + return ERR_PTR(err); + return &vkobj->base; } @@ -463,28 +478,17 @@ static void pf_sysfs_note(struct xe_device *xe, int err, const char *what) xe_sriov_dbg(xe, "Failed to setup sysfs %s (%pe)\n", what, ERR_PTR(err)); } -static void action_put_kobject(void *arg) -{ - struct kobject *kobj = arg; - - kobject_put(kobj); -} - static int pf_setup_root(struct xe_device *xe) { struct kobject *parent = &xe->drm.dev->kobj; struct kobject *root; int err; - root = create_xe_sriov_kobj(xe, PFID); - if (!root) - return pf_sysfs_error(xe, -ENOMEM, "root obj"); - - err = devm_add_action_or_reset(xe->drm.dev, action_put_kobject, root); - if (err) - return pf_sysfs_error(xe, err, "root action"); + root = create_xe_sriov_kobj(xe, PFID, &xe_sriov_dev_ktype); + if (IS_ERR(root)) + return pf_sysfs_error(xe, PTR_ERR(root), "root obj"); - err = kobject_init_and_add(root, &xe_sriov_dev_ktype, parent, "sriov_admin"); + err = kobject_add(root, parent, "sriov_admin"); if (err) return pf_sysfs_error(xe, err, "root init"); @@ -505,20 +509,14 @@ static int pf_setup_tree(struct xe_device *xe) root = xe->sriov.pf.sysfs.root; for (n = 0; n <= totalvfs; n++) { - kobj = create_xe_sriov_kobj(xe, VFID(n)); - if (!kobj) - return pf_sysfs_error(xe, -ENOMEM, "tree obj"); - - err = devm_add_action_or_reset(xe->drm.dev, action_put_kobject, root); - if (err) - return pf_sysfs_error(xe, err, "tree action"); + kobj = create_xe_sriov_kobj(xe, VFID(n), &xe_sriov_vf_ktype); + if (IS_ERR(kobj)) + return pf_sysfs_error(xe, PTR_ERR(kobj), "tree obj"); if (n) - err = kobject_init_and_add(kobj, &xe_sriov_vf_ktype, - root, "vf%u", n); + err = kobject_add(kobj, root, "vf%u", n); else - err = kobject_init_and_add(kobj, &xe_sriov_vf_ktype, - root, "pf"); + err = kobject_add(kobj, root, "pf"); if (err) return pf_sysfs_error(xe, err, "tree init");
bf7172cd25eddrm/xe/pf: Fix sysfs initialization
1 file changed · +26 −29
drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c+26 −29 modifieddiff --git a/drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c b/drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c index 3d140506ba36b..82a1055985ba7 100644 --- a/drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c +++ b/drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c @@ -349,18 +349,33 @@ static const struct attribute_group *xe_sriov_vf_attr_groups[] = { /* no user serviceable parts below */ -static struct kobject *create_xe_sriov_kobj(struct xe_device *xe, unsigned int vfid) +static void action_put_kobject(void *arg) +{ + struct kobject *kobj = arg; + + kobject_put(kobj); +} + +static struct kobject *create_xe_sriov_kobj(struct xe_device *xe, unsigned int vfid, + const struct kobj_type *ktype) { struct xe_sriov_kobj *vkobj; + int err; xe_sriov_pf_assert_vfid(xe, vfid); vkobj = kzalloc(sizeof(*vkobj), GFP_KERNEL); if (!vkobj) - return NULL; + return ERR_PTR(-ENOMEM); vkobj->xe = xe; vkobj->vfid = vfid; + kobject_init(&vkobj->base, ktype); + + err = devm_add_action_or_reset(xe->drm.dev, action_put_kobject, &vkobj->base); + if (err) + return ERR_PTR(err); + return &vkobj->base; } @@ -463,28 +478,17 @@ static void pf_sysfs_note(struct xe_device *xe, int err, const char *what) xe_sriov_dbg(xe, "Failed to setup sysfs %s (%pe)\n", what, ERR_PTR(err)); } -static void action_put_kobject(void *arg) -{ - struct kobject *kobj = arg; - - kobject_put(kobj); -} - static int pf_setup_root(struct xe_device *xe) { struct kobject *parent = &xe->drm.dev->kobj; struct kobject *root; int err; - root = create_xe_sriov_kobj(xe, PFID); - if (!root) - return pf_sysfs_error(xe, -ENOMEM, "root obj"); - - err = devm_add_action_or_reset(xe->drm.dev, action_put_kobject, root); - if (err) - return pf_sysfs_error(xe, err, "root action"); + root = create_xe_sriov_kobj(xe, PFID, &xe_sriov_dev_ktype); + if (IS_ERR(root)) + return pf_sysfs_error(xe, PTR_ERR(root), "root obj"); - err = kobject_init_and_add(root, &xe_sriov_dev_ktype, parent, "sriov_admin"); + err = kobject_add(root, parent, "sriov_admin"); if (err) return pf_sysfs_error(xe, err, "root init"); @@ -505,20 +509,14 @@ static int pf_setup_tree(struct xe_device *xe) root = xe->sriov.pf.sysfs.root; for (n = 0; n <= totalvfs; n++) { - kobj = create_xe_sriov_kobj(xe, VFID(n)); - if (!kobj) - return pf_sysfs_error(xe, -ENOMEM, "tree obj"); - - err = devm_add_action_or_reset(xe->drm.dev, action_put_kobject, root); - if (err) - return pf_sysfs_error(xe, err, "tree action"); + kobj = create_xe_sriov_kobj(xe, VFID(n), &xe_sriov_vf_ktype); + if (IS_ERR(kobj)) + return pf_sysfs_error(xe, PTR_ERR(kobj), "tree obj"); if (n) - err = kobject_init_and_add(kobj, &xe_sriov_vf_ktype, - root, "vf%u", n); + err = kobject_add(kobj, root, "vf%u", n); else - err = kobject_init_and_add(kobj, &xe_sriov_vf_ktype, - root, "pf"); + err = kobject_add(kobj, root, "pf"); if (err) return pf_sysfs_error(xe, err, "tree init"); -- cgit 1.3-korg
6ae479b1919edrm/xe/pf: Fix sysfs initialization
1 file changed · +26 −29
drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c+26 −29 modifieddiff --git a/drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c b/drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c index c0b767ac735cf..d1c1f6c295664 100644 --- a/drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c +++ b/drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c @@ -349,18 +349,33 @@ static const struct attribute_group *xe_sriov_vf_attr_groups[] = { /* no user serviceable parts below */ -static struct kobject *create_xe_sriov_kobj(struct xe_device *xe, unsigned int vfid) +static void action_put_kobject(void *arg) +{ + struct kobject *kobj = arg; + + kobject_put(kobj); +} + +static struct kobject *create_xe_sriov_kobj(struct xe_device *xe, unsigned int vfid, + const struct kobj_type *ktype) { struct xe_sriov_kobj *vkobj; + int err; xe_sriov_pf_assert_vfid(xe, vfid); vkobj = kzalloc(sizeof(*vkobj), GFP_KERNEL); if (!vkobj) - return NULL; + return ERR_PTR(-ENOMEM); vkobj->xe = xe; vkobj->vfid = vfid; + kobject_init(&vkobj->base, ktype); + + err = devm_add_action_or_reset(xe->drm.dev, action_put_kobject, &vkobj->base); + if (err) + return ERR_PTR(err); + return &vkobj->base; } @@ -471,28 +486,17 @@ static void pf_sysfs_note(struct xe_device *xe, int err, const char *what) xe_sriov_dbg(xe, "Failed to setup sysfs %s (%pe)\n", what, ERR_PTR(err)); } -static void action_put_kobject(void *arg) -{ - struct kobject *kobj = arg; - - kobject_put(kobj); -} - static int pf_setup_root(struct xe_device *xe) { struct kobject *parent = &xe->drm.dev->kobj; struct kobject *root; int err; - root = create_xe_sriov_kobj(xe, PFID); - if (!root) - return pf_sysfs_error(xe, -ENOMEM, "root obj"); - - err = devm_add_action_or_reset(xe->drm.dev, action_put_kobject, root); - if (err) - return pf_sysfs_error(xe, err, "root action"); + root = create_xe_sriov_kobj(xe, PFID, &xe_sriov_dev_ktype); + if (IS_ERR(root)) + return pf_sysfs_error(xe, PTR_ERR(root), "root obj"); - err = kobject_init_and_add(root, &xe_sriov_dev_ktype, parent, "sriov_admin"); + err = kobject_add(root, parent, "sriov_admin"); if (err) return pf_sysfs_error(xe, err, "root init"); @@ -513,20 +517,14 @@ static int pf_setup_tree(struct xe_device *xe) root = xe->sriov.pf.sysfs.root; for (n = 0; n <= totalvfs; n++) { - kobj = create_xe_sriov_kobj(xe, VFID(n)); - if (!kobj) - return pf_sysfs_error(xe, -ENOMEM, "tree obj"); - - err = devm_add_action_or_reset(xe->drm.dev, action_put_kobject, root); - if (err) - return pf_sysfs_error(xe, err, "tree action"); + kobj = create_xe_sriov_kobj(xe, VFID(n), &xe_sriov_vf_ktype); + if (IS_ERR(kobj)) + return pf_sysfs_error(xe, PTR_ERR(kobj), "tree obj"); if (n) - err = kobject_init_and_add(kobj, &xe_sriov_vf_ktype, - root, "vf%u", n); + err = kobject_add(kobj, root, "vf%u", n); else - err = kobject_init_and_add(kobj, &xe_sriov_vf_ktype, - root, "pf"); + err = kobject_add(kobj, root, "pf"); if (err) return pf_sysfs_error(xe, err, "tree init"); -- cgit 1.3-korg
Vulnerability mechanics
Root cause
"Failure to properly initialize kobjects before registering cleanup actions leads to use-after-free and null pointer dereference vulnerabilities."
Attack vector
An attacker can trigger this vulnerability during the initialization of SR-IOV (Single Root I/O Virtualization) functionality within the Linux kernel's graphics drivers. Specifically, if the `devm_add_action_or_reset()` function fails during kobject setup, the system attempts to call `kobject_put()` on an uninitialized kobject. This can lead to errors such as null pointer dereferences or refcount underflows, potentially causing system instability or crashes [patch_id=4686587].
Affected code
The vulnerability resides in the `drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c` file, specifically within the `create_xe_sriov_kobj`, `pf_setup_root`, and `pf_setup_tree` functions. The original code used `kobject_init_and_add` which could lead to issues if `devm_add_action_or_reset` failed, as seen in the call traces provided in the patch commit messages [patch_id=4686587].
What the fix does
The patch modifies the sysfs initialization process for SR-IOV in the Linux kernel's graphics drivers. It separates the calls to `kobject_init()` and `kobject_add()`, ensuring that the kobject is fully initialized before any cleanup actions are registered using `devm_add_action_or_reset()`. Additionally, the cleanup registration is moved into a create helper function to correctly handle parent kobjects and prevent memory leaks [patch_id=4686587].
Generated on Jun 3, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
2News mentions
1- Linux Kernel: 25 Vulnerabilities Disclosed in Single Batch on June 3, 2026Vypr Intelligence · Jun 3, 2026