Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid crash on crash report when a bad function pointer was called #11298

Merged
merged 6 commits into from
Sep 29, 2022

Conversation

MeirShpilraien
Copy link
Collaborator

@MeirShpilraien MeirShpilraien commented Sep 21, 2022

If Redis crashes due to calling an invalid function pointer, the backtrace function will try to de-reference this invalid pointer which will cause a crash inside the crash report and will kill the processes without having all the crash report information.

Example:

=== REDIS BUG REPORT START: Cut & paste starting from here ===
198672:M 19 Sep 2022 18:06:12.936 # Redis 255.255.255 crashed by signal: 11, si_code: 1
198672:M 19 Sep 2022 18:06:12.936 # Accessing address: 0x1
198672:M 19 Sep 2022 18:06:12.936 # Crashed running the instruction at: 0x1
// here the processes is crashing

This PR tries to fix this crash by:

  1. Identify the issue when it happened.
  2. Replace the invalid pointer with a pointer to some dummy function so that backtrace will not crash.

The identification is done by comparing eip to info->si_addr, if they are the same we know that the crash happened on the same address it tries to accesses and we can conclude that it tries to call and invalid function pointer.

To replace the invalid pointer we introduce a new function, setAndGetMcontextEip, which replaces getMcontextEip and allow to set the Eip for the different supported OS's. After printing the trace we retrieve the old Eip value.

If Redis crashes due to calling an invalid function pointer,
the `backtrace` function will try to dereference this invalid pointer
which will cause a crash inside the crash report and will kill
the processes without having all the crash report infomation.

Example:

```
=== REDIS BUG REPORT START: Cut & paste starting from here ===
198672:M 19 Sep 2022 18:06:12.936 # Redis 255.255.255 crashed by signal: 11, si_code: 1
198672:M 19 Sep 2022 18:06:12.936 # Accessing address: 0x1
198672:M 19 Sep 2022 18:06:12.936 # Crashed running the instruction at: 0x1
// here the processes is crashing
```

This PR tries to fix this crash be:
1. Identify the issue when it happened.
2. Replace the invalid pointer with a pointer to some dummy function
   so that `backtrace` will not crash.

I identification is done by comparing `eip` to `info->si_addr`, if they
are the same we know that the crash happened on the same address it tries to
accesses and we can coclude that it tries to call and invalid function pointer.

To replace the invalid pointer we introduce a new function, `setMcontextEip`,
which is very similar to `getMcontextEip` and it knows to set the Eip for the
different supported OS's. After printing the trace we retrieve the old `Eip` value.
@MeirShpilraien MeirShpilraien marked this pull request as draft September 21, 2022 13:39
@oranagra
Copy link
Member

oranagra commented Sep 21, 2022

@oranagra
Copy link
Member

@devnexen maybe you can test this on some other platforms?

@MeirShpilraien MeirShpilraien marked this pull request as ready for review September 21, 2022 16:04
@devnexen
Copy link
Contributor

@devnexen maybe you can test this on some other platforms?

so tried
macos arm64 (seeing "eip" on non-x86 archs feels kind of weird :-) your PR just made me realised it), BSD and Illumos on x86_64. No issues so far.

src/debug.c Outdated Show resolved Hide resolved
src/debug.c Outdated Show resolved Hide resolved
src/debug.c Outdated Show resolved Hide resolved
MeirShpilraien and others added 2 commits September 22, 2022 13:33
Co-authored-by: Oran Agra <oran@redislabs.com>
Copy link
Member

@yossigo yossigo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@oranagra @MeirShpilraien The problem is clear, but don't you think this is going a bit too far into the C library's responsibility domain?

@oranagra
Copy link
Member

@yossigo the C library is broken.
Are you suggesting we'll live with it?
If the fix is safe, I don't see any reason not to do it.

@yossigo
Copy link
Member

yossigo commented Sep 28, 2022

@oranagra It's more platform-specific code that may have more undesired side-effect or extra maintenance burden in the long term, only to fix a non-critical libc issue for which there is a workaround (get a core dump). I do not feel so strongly about it, though. We can remove it if it becomes a problem.
We should probably open a glibc issue to have it fixed.

@oranagra
Copy link
Member

@yossigo i feel the scope of this change is relatively small and we can cope with the side effects, or revert if we can't.
other than compilation errors, it can't really do any harm since it only runs in a very specific case.
i don't think the workaround of a core-dump is a good one since the crash report is needed in cases where the error happens in production and is not reproducible.

i tried filing a bug in glibc, as well as searching for an existing one (can't find it in their bugzilla), and it seems too complicated, and i'm short in time. (can't easily create an account, maybe someone who already has an account can try).
i do see however that this error was previously reported in their mailing list and ignored:
https://gcc.gnu.org/legacy-ml/gcc/2007-06/msg00329.html

@oranagra oranagra changed the title Avoid crash on crash report. Avoid crash on crash report when an invalid function pointer was used Sep 29, 2022
@oranagra oranagra changed the title Avoid crash on crash report when an invalid function pointer was used Avoid crash on crash report when a bad function pointer was called Sep 29, 2022
@oranagra oranagra merged commit 0bf90d9 into redis:unstable Sep 29, 2022
esteinerMW added a commit to esteinerMW/redis that referenced this pull request Nov 3, 2022
@iav20
Copy link

iav20 commented Nov 14, 2022

Hello Team ,

Can you please share the details by when the fix of this issue will be backported in 7.0 Release

Best Regards,
Apoorv

@oranagra
Copy link
Member

@iav20 it'll be part of the next release we make for 7.0 and 6.2, but we didn't define the timeline yet.
unless some urgent issue is found that justifies a new release, it can take a few months.

@esteinerMW
Copy link

@oranagra Thank you for your feedback!

A data point regarding 6.2:
Porting the fix would address the following issue: (NIST NVD score was flagged by compliance scans)
https://nvd.nist.gov/vuln/detail/CVE-2022-3647

Thanks in advance for your consideration!
Eitan

@yossigo
Copy link
Member

yossigo commented Nov 15, 2022

@esteinerMW I think this CVE is wrong, this is not really a denial of service issue. We'll see if this can be corrected, regardless of the fix being backported.

oranagra pushed a commit that referenced this pull request Dec 12, 2022
…11298)

If Redis crashes due to calling an invalid function pointer,
the `backtrace` function will try to dereference this invalid pointer
which will cause a crash inside the crash report and will kill
the processes without having all the crash report information.

Example:

```
=== REDIS BUG REPORT START: Cut & paste starting from here ===
198672:M 19 Sep 2022 18:06:12.936 # Redis 255.255.255 crashed by signal: 11, si_code: 1
198672:M 19 Sep 2022 18:06:12.936 # Accessing address: 0x1
198672:M 19 Sep 2022 18:06:12.936 # Crashed running the instruction at: 0x1
// here the processes is crashing
```

This PR tries to fix this crash be:
1. Identify the issue when it happened.
2. Replace the invalid pointer with a pointer to some dummy function
   so that `backtrace` will not crash.

I identification is done by comparing `eip` to `info->si_addr`, if they
are the same we know that the crash happened on the same address it tries to
accesses and we can conclude that it tries to call and invalid function pointer.

To replace the invalid pointer we introduce a new function, `setMcontextEip`,
which is very similar to `getMcontextEip` and it knows to set the Eip for the
different supported OS's. After printing the trace we retrieve the old `Eip` value.

(cherry picked from commit 0bf90d9)
oranagra pushed a commit that referenced this pull request Dec 12, 2022
…11298)

If Redis crashes due to calling an invalid function pointer,
the `backtrace` function will try to dereference this invalid pointer
which will cause a crash inside the crash report and will kill
the processes without having all the crash report information.

Example:

```
=== REDIS BUG REPORT START: Cut & paste starting from here ===
198672:M 19 Sep 2022 18:06:12.936 # Redis 255.255.255 crashed by signal: 11, si_code: 1
198672:M 19 Sep 2022 18:06:12.936 # Accessing address: 0x1
198672:M 19 Sep 2022 18:06:12.936 # Crashed running the instruction at: 0x1
// here the processes is crashing
```

This PR tries to fix this crash be:
1. Identify the issue when it happened.
2. Replace the invalid pointer with a pointer to some dummy function
   so that `backtrace` will not crash.

I identification is done by comparing `eip` to `info->si_addr`, if they
are the same we know that the crash happened on the same address it tries to
accesses and we can conclude that it tries to call and invalid function pointer.

To replace the invalid pointer we introduce a new function, `setMcontextEip`,
which is very similar to `getMcontextEip` and it knows to set the Eip for the
different supported OS's. After printing the trace we retrieve the old `Eip` value.

(cherry picked from commit 0bf90d9)
madolson pushed a commit to madolson/redis that referenced this pull request Apr 19, 2023
…edis#11298)

If Redis crashes due to calling an invalid function pointer,
the `backtrace` function will try to dereference this invalid pointer
which will cause a crash inside the crash report and will kill
the processes without having all the crash report information.

Example:

```
=== REDIS BUG REPORT START: Cut & paste starting from here ===
198672:M 19 Sep 2022 18:06:12.936 # Redis 255.255.255 crashed by signal: 11, si_code: 1
198672:M 19 Sep 2022 18:06:12.936 # Accessing address: 0x1
198672:M 19 Sep 2022 18:06:12.936 # Crashed running the instruction at: 0x1
// here the processes is crashing
```

This PR tries to fix this crash be:
1. Identify the issue when it happened.
2. Replace the invalid pointer with a pointer to some dummy function
   so that `backtrace` will not crash.

I identification is done by comparing `eip` to `info->si_addr`, if they
are the same we know that the crash happened on the same address it tries to
accesses and we can conclude that it tries to call and invalid function pointer.

To replace the invalid pointer we introduce a new function, `setMcontextEip`,
which is very similar to `getMcontextEip` and it knows to set the Eip for the
different supported OS's. After printing the trace we retrieve the old `Eip` value.
enjoy-binbin pushed a commit to enjoy-binbin/redis that referenced this pull request Jul 31, 2023
…edis#11298)

If Redis crashes due to calling an invalid function pointer,
the `backtrace` function will try to dereference this invalid pointer
which will cause a crash inside the crash report and will kill
the processes without having all the crash report information.

Example:

```
=== REDIS BUG REPORT START: Cut & paste starting from here ===
198672:M 19 Sep 2022 18:06:12.936 # Redis 255.255.255 crashed by signal: 11, si_code: 1
198672:M 19 Sep 2022 18:06:12.936 # Accessing address: 0x1
198672:M 19 Sep 2022 18:06:12.936 # Crashed running the instruction at: 0x1
// here the processes is crashing
```

This PR tries to fix this crash be:
1. Identify the issue when it happened.
2. Replace the invalid pointer with a pointer to some dummy function
   so that `backtrace` will not crash.

I identification is done by comparing `eip` to `info->si_addr`, if they
are the same we know that the crash happened on the same address it tries to
accesses and we can conclude that it tries to call and invalid function pointer.

To replace the invalid pointer we introduce a new function, `setMcontextEip`,
which is very similar to `getMcontextEip` and it knows to set the Eip for the
different supported OS's. After printing the trace we retrieve the old `Eip` value.
@alecxvs
Copy link

alecxvs commented Dec 7, 2023

Was the fix backported, and is there any progress on correcting the CVE status? I'm running 6.2.14 but it's being flagged for this despite being disputed, and if it was already backported in the version I'm running, it may also be a false positive and the NIST db hasn't been updated with the backport version yet.

@oranagra
Copy link
Member

oranagra commented Dec 9, 2023

yes, it was backported and part of 6.2.8 and later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

None yet

7 participants