Bug 2122089 (CVE-2022-20166) - CVE-2022-20166 kernel: possible buffer overflow in sysfs reading
Summary: CVE-2022-20166 kernel: possible buffer overflow in sysfs reading
Keywords:
Status: NEW
Alias: CVE-2022-20166
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Nobody
QA Contact:
URL:
Whiteboard:
Depends On: 2122468 2122470 2122471 2122472
Blocks: 2122088
TreeView+ depends on / blocked
 
Reported: 2022-08-29 04:54 UTC by Wade Mealing
Modified: 2023-12-20 19:42 UTC (History)
50 users (show)

Fixed In Version: kernel-5.10-rc1
Doc Type: If docs needed, set a value
Doc Text:
A flaw was found in the Linux kernel’s sysfs layer. This flaw allows a local user who can read files under the /sysfs mount point to corrupt memory or possibly crash the system.
Clone Of:
Environment:
Last Closed:
Embargoed:


Attachments (Terms of Use)

Description Wade Mealing 2022-08-29 04:54:08 UTC
A flaw was found in the Linux kernels sysfs layer data reporting. A local users with the ability to read files under the /sysfs mount point can create a possible out of bounds write due to a heap buffer overflow. By grooming memory in this 'out of bounds' location, a local attacker could use this write to manipulate the kernel into executing attacker provided code crashing the system or creating possible privilege escalation for attacker controlled userspace code.


References:
http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2022-20166
https://source.android.com/security/bulletin/pixel/2022-06-01

Fix: 
https://github.com/torvalds/linux/commit/aa838896d87af561a33ecefea1caa4c15a68bc47

Comment 7 Ian Kent 2022-08-31 00:44:56 UTC
(In reply to Wade Mealing from comment #0)
> A flaw was found in the Linux kernels sysfs layer data reporting. A local
> users with the ability to read files under the /sysfs mount point can create
> a possible out of bounds write due to a heap buffer overflow. By grooming
> memory in this 'out of bounds' location, a local attacker could use this
> write to manipulate the kernel into executing attacker provided code
> crashing the system or creating possible privilege escalation for attacker
> controlled userspace code.

I find this a little puzzling.

I would really like to see a reproducer of this hypothetical case or
at least an explanation of how an out of bounds write to a buffer can
happen within a file system whose files are all created by in kernel
sub-systems and use the seq file interface for reading (which uses a
PAGE_SIZE buffer everywhere).

I thought we fixed the possible seq file over size buffer allocation
ages ago ... if it is possible for kvmalloc() to return success upon
failing to get the requested memory in any case then we probably have
much bigger problems.

Perhaps the problem is the passed in read buffer can be too small and
its size isn't checked ... but, based on the suggested fix that doesn't
appear to be the problem that's fixed ...

Ian

Comment 8 Eric Sandeen 2022-09-01 20:29:59 UTC
I agree - this is a fairly wide change with no real explanation of why it's needed.

note that sysfs_emit doesn't exist in RHEL7, and was only somewhat recently added to RHEL8.

The upstream commit was:

commit 2efc459d06f1630001e3984854848a5647086232
Author: Joe Perches <joe>
Date:   Wed Sep 16 13:40:38 2020 -0700

    sysfs: Add sysfs_emit and sysfs_emit_at to format sysfs output
    
    Output defects can exist in sysfs content using sprintf and snprintf.
    
    sprintf does not know the PAGE_SIZE maximum of the temporary buffer
    used for outputting sysfs content and it's possible to overrun the
    PAGE_SIZE buffer length.
    
    Add a generic sysfs_emit function that knows that the size of the
    temporary buffer and ensures that no overrun is done.
    
    Add a generic sysfs_emit_at function that can be used in multiple
    call situations that also ensures that no overrun is done.
    
    Validate the output buffer argument to be page aligned.
    Validate the offset len argument to be within the PAGE_SIZE buf.
    
    Signed-off-by: Joe Perches <joe>
    Link: https://lore.kernel.org/r/884235202216d464d61ee975f7465332c86f76b2.1600285923.git.joe@perches.com
    Signed-off-by: Greg Kroah-Hartman <gregkh>

which offerrs some clues.

Further, although all the child bugs were assigned to filesystem, this really is not a filesystem bug - every change in this commit is under drivers/ so this should probably be a core kernel bug.

That said, if failing to use sysfs_emit is a security problem, is it really only drivers/ that is affected?

Comment 9 Eric Sandeen 2022-09-01 20:37:45 UTC
A couple other thoughts. This is similar to the prior CVE-2021-27365, which only addressed the problem in iscsi.

For that CVE, the RHEL7 workaround for lack of sysfs_emit was noted:

commit af581fe518f4d6a6f28064f932d9374e0444d706
Author: Chris Leech <cleech>
Date:   Thu Mar 4 09:57:23 2021 -0800

    scsi: iscsi: Ensure sysfs attributes are limited to PAGE_SIZE
    
    Bugzilla: http://bugzilla.redhat.com/1930849
    CVE: CVE-2021-27363
    
    Conflicts: The sysfs_emit helper doesn't exist for backports, but other
    than a sanity check on buf it's just a call to scnprintf with a
    PAGE_SIZE limit.
    converted with s/sysfs_emit(buf,/scnprintf(buf, PAGE_SIZE,/

Comment 10 Ian Kent 2022-09-02 04:53:46 UTC
(In reply to Ian Kent from comment #7)
> 
> Perhaps the problem is the passed in read buffer can be too small and
> its size isn't checked ... but, based on the suggested fix that doesn't
> appear to be the problem that's fixed ...

Actually, my mistake, the fix does introduce a PAGE_SIZE length check but
we would be very hard pressed to find anything in kernel sub-systems using
sysfs whose ->show() routine generates output greater than 4k.

Comment 11 Eric Sandeen 2022-09-06 16:44:57 UTC
(In reply to Ian Kent from comment #10)

> Actually, my mistake, the fix does introduce a PAGE_SIZE length check but
> we would be very hard pressed to find anything in kernel sub-systems using
> sysfs whose ->show() routine generates output greater than 4k.

Yeah this seems like the trick here; it's certainly good defensive programming to always have the check.

But in RHEL kernels,

1) can anything actually exceed page size today? and
2) do other subsystems using sysfs have similar problems which remain unaddressed by the patch?

This seems like a CVE generated for defensive programming goals, not an actual demonstrated flaw.

Comment 12 Ian Kent 2022-09-06 22:51:49 UTC
(In reply to Eric Sandeen from comment #11)
> (In reply to Ian Kent from comment #10)
> 
> > Actually, my mistake, the fix does introduce a PAGE_SIZE length check but
> > we would be very hard pressed to find anything in kernel sub-systems using
> > sysfs whose ->show() routine generates output greater than 4k.
> 
> Yeah this seems like the trick here; it's certainly good defensive
> programming to always have the check.
> 
> But in RHEL kernels,
> 
> 1) can anything actually exceed page size today? and

Probably, but you would think kernel developers would know what they are
outputting and its length since they should know that the seq file system
uses a page size buffer for this.

> 2) do other subsystems using sysfs have similar problems which remain
> unaddressed by the patch?

Probably, consider the mount table output, it has paths in some fields
for which you don't know the length. I'm pretty sure that uses the seq
file interface too.

> 
> This seems like a CVE generated for defensive programming goals, not an
> actual demonstrated flaw.

The question I still have is how does an attacker arrange for the buffer
to overflow. Maybe there are cases where system setup would cause this,
IIRC we saw something like that with mount table size ...

I'll go through comment #6 and see if I can find some of this info.

Ian

Comment 13 Ian Kent 2022-09-07 04:52:22 UTC
(In reply to Ian Kent from comment #12)
> (In reply to Eric Sandeen from comment #11)
> > (In reply to Ian Kent from comment #10)
> > 
> > > Actually, my mistake, the fix does introduce a PAGE_SIZE length check but
> > > we would be very hard pressed to find anything in kernel sub-systems using
> > > sysfs whose ->show() routine generates output greater than 4k.
> > 
> > Yeah this seems like the trick here; it's certainly good defensive
> > programming to always have the check.
> > 
> > But in RHEL kernels,
> > 
> > 1) can anything actually exceed page size today? and
> 
> Probably, but you would think kernel developers would know what they are
> outputting and its length since they should know that the seq file system
> uses a page size buffer for this.
> 
> > 2) do other subsystems using sysfs have similar problems which remain
> > unaddressed by the patch?
> 
> Probably, consider the mount table output, it has paths in some fields
> for which you don't know the length. I'm pretty sure that uses the seq
> file interface too.

Mmm ... sysfs only half heatedly uses the seq file interface and only for
sysfs attributes that aren't binary.

The buffer allocated is PAGE_SIZE (seq file norm) so limiting writes to the
buffer to that amount isn't a bad idea.

Still would be nice to have an example attack scenario as these are created
by kernel sub-systems and to load a bogus module requires admin privilege.

Ian

Comment 19 Mauro Matteo Cascella 2023-12-20 19:41:30 UTC
This issue was fixed upstream in kernel version 5.10. The kernel packages as shipped in Red Hat Enterprise Linux 8 were previously updated to a version that contains the fix via the following errata:

kernel in Red Hat Enterprise Linux 8
https://access.redhat.com/errata/RHSA-2021:4356

kernel-rt in Red Hat Enterprise Linux 8
https://access.redhat.com/errata/RHSA-2021:4140


Note You need to log in before you can comment on or make changes to this bug.