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

out of bounds memory access in snd_mix.cpp S_PaintChannelFrom16 #1038

Closed
namtsui opened this issue Apr 30, 2020 · 2 comments · Fixed by #1040
Closed

out of bounds memory access in snd_mix.cpp S_PaintChannelFrom16 #1038

namtsui opened this issue Apr 30, 2020 · 2 comments · Fixed by #1040

Comments

@namtsui
Copy link

namtsui commented Apr 30, 2020

Reporting a bug? Please make sure you've given the following information - thanks!

Operating system and version:

OpenBSD amd64
5203023

Is this for single player or multiplayer?

multiplayer

Description of the bug (and if possible, steps to reproduce the bug):

In multiplayer I created a game on Vjun Sentinel, got the Merr-Sonn PLX-2M behind the lifts near the starting spawn at lifts, and segfaulted either immediately or several seconds after firing it. This is somewhat hard to reproduce as most of the time I am able to fire without crashing.

(gdb) run
Starting program: /usr/local/share/JediAcademy/openjk 
[New thread 614481]
Thread 1 received signal SIGSEGV, Segmentation fault.
0x000006dce7350b97 in S_PaintChannelFrom16 (ch=0x6dce8177d00 <s_channels+920928>, sfx=0x6dce82f8890 <s_knownSfx+40832>, count=1024, sampleOffset=133859, bufferOffset=0) at /usr/ports/pobj/openjk-0.0.0.20200214/OpenJK-52030235f052772008d99e6ccb16de48e7ddb688/codemp/client/snd_mix.cpp:284
284			iData = sfx->pSoundData[ (int)ofst ];
(gdb) bt
#0  0x000006dce7350b97 in S_PaintChannelFrom16 (ch=0x6dce8177d00 <s_channels+920928>, sfx=0x6dce82f8890 <s_knownSfx+40832>, count=1024, sampleOffset=133859, bufferOffset=0) at /usr/ports/pobj/openjk-0.0.0.20200214/OpenJK-52030235f052772008d99e6ccb16de48e7ddb688/codemp/client/snd_mix.cpp:284
#1  0x000006dce7350ac9 in ChannelPaint (ch=0x6dce8177d00 <s_channels+920928>, sc=0x6dce82f8890 <s_knownSfx+40832>, count=1024, sampleOffset=133859, bufferOffset=0) at /usr/ports/pobj/openjk-0.0.0.20200214/OpenJK-52030235f052772008d99e6ccb16de48e7ddb688/codemp/client/snd_mix.cpp:353
#2  0x000006dce7350f7c in S_PaintChannels (endtime=849524) at /usr/ports/pobj/openjk-0.0.0.20200214/OpenJK-52030235f052772008d99e6ccb16de48e7ddb688/codemp/client/snd_mix.cpp:451
#3  0x000006dce734b396 in S_Update_ () at /usr/ports/pobj/openjk-0.0.0.20200214/OpenJK-52030235f052772008d99e6ccb16de48e7ddb688/codemp/client/snd_dma.cpp:3118
#4  0x000006dce734aec6 in S_Update () at /usr/ports/pobj/openjk-0.0.0.20200214/OpenJK-52030235f052772008d99e6ccb16de48e7ddb688/codemp/client/snd_dma.cpp:2788
#5  0x000006dce730f020 in CL_Frame (msec=8) at /usr/ports/pobj/openjk-0.0.0.20200214/OpenJK-52030235f052772008d99e6ccb16de48e7ddb688/codemp/client/cl_main.cpp:2209
#6  0x000006dce722ec7a in Com_Frame () at /usr/ports/pobj/openjk-0.0.0.20200214/OpenJK-52030235f052772008d99e6ccb16de48e7ddb688/codemp/qcommon/common.cpp:1585
#7  0x000006dce73852b7 in main (argc=1, argv=0x7f7ffffe69b8) at /usr/ports/pobj/openjk-0.0.0.20200214/OpenJK-52030235f052772008d99e6ccb16de48e7ddb688/shared/sys/sys_main.cpp:812
(gdb) print ofst
$1 = 143352
(gdb) print iData
$2 = 0
(gdb) print sfx->pSoundData
$3 = (short *) 0x6df55a1b020
(gdb) print sfx->pSoundData[0]
$4 = -33
(gdb) print sfx->pSoundData[1]
$5 = -33
(gdb) print sfx->pSoundData[2]
$6 = -566
(gdb) print sfx->pSoundData[3]
$7 = -566
(gdb) print sfx->pSoundData[1000]
$8 = -2543
(gdb) print sfx->pSoundData[ofst]
Cannot access memory at address 0x6df55a61010
(gdb) print sfx->pSoundData[ofst-1]
Cannot access memory at address 0x6df55a6100e
(gdb) print sfx->pSoundData[ofst-2]
Cannot access memory at address 0x6df55a6100c
(gdb) print sfx->pSoundData[ofst-1000]
$9 = 0
(gdb) print sfx->pSoundData[ofst-2000]
$10 = 3519

What did you expect to happen instead?

It looks like ofst is causing out of bounds memory access.

@namtsui
Copy link
Author

namtsui commented May 21, 2020

I saw that iSoundLengthInSamples is used as a bounds check.

// have we run off the end?
if ((offset + (i*100)) > ch->thesfx->iSoundLengthInSamples)
{
break;
}

These lines were useful to understand that iSoundLengthInSamples is number of samples stored as shorts. pSoundData is a buffer with shorts, each 2 bytes, so malloc iSoundLengthOfSamples * 2 bytes.

sfx->iSoundLengthInSamples = 512; // #samples, ie shorts
sfx->pSoundData = (short *) SND_malloc(512*2, sfx); // ... so *2 for alloc bytes

I tested with `sysctl vm.malloc_conf=S' on OpenBSD, which enables various security auditing options for malloc in the hopes of triggering this crash more often. It remains somewhat hard to reproduce even with this malloc option.

This adds a bounds check to prevent buffer over-reading. With this fix I tested loading into the map and shooting the Merr-Sonn PLX-2M. It no longer crashes.

Related commit: 69800e8

@namtsui
Copy link
Author

namtsui commented May 21, 2020

gdb showing that ofst is somewhat close to sfx->iSoundLengthInSamples at the time of the segfault.

(gdb) run
Starting program: /usr/local/share/JediAcademy/openjk 
[New thread 382056]

Thread 1 received signal SIGSEGV, Segmentation fault.
0x0000092ad753db97 in S_PaintChannelFrom16 (ch=0x92ad8307218 <s_channels+537208>, sfx=0x92ad84e5890 <s_knownSfx+40832>, count=1024, sampleOffset=135381, bufferOffset=0) at /usr/ports/pobj/openjk-0.0.0.20200214/OpenJK-52030235f052772008d99e6ccb16de48e7ddb688/codemp/client/snd_mix.cpp:284
284			iData = sfx->pSoundData[ (int)ofst ];
(gdb) print ofst
$1 = 143350.078
(gdb) print sfx->iSoundLengthInSamples
$2 = 141810
(gdb) print sfx->pSoundData[141810]
$3 = 25991
(gdb) print sfx->pSoundData[141811]
$4 = 8515
(gdb) print sfx->pSoundData[141812]
$5 = -9253
(gdb) print sfx->pSoundData[141813]
$6 = -9253
(gdb) print sfx->pSoundData[141814]
$7 = -9253
(gdb) print sfx->pSoundData[141815]
$8 = -9253
(gdb) print sfx->pSoundData[141820]
$9 = -9253
(gdb) print sfx->pSoundData[1418]
$10 = 7229
(gdb) print sfx->pSoundData[1418]
$11 = 7229
(gdb) print sfx->pSoundData[ofst]
Cannot access memory at address 0x92d08c6c00c
(gdb) print sfx->pSoundData[ofst]
Cannot access memory at address 0x92d08c6c00c
(gdb) print sfx->pSoundData[141809]
$12 = 992

namtsui added a commit to namtsui/OpenJK that referenced this issue May 21, 2020
Fixes JACoders#1038

ofst over-reads past the end of the pSoundData buffer. Add a bounds check
similar to S_CheckAmplitude() in codemp/client/snd_dma.cpp.

JACoders@69800e8
namtsui added a commit to namtsui/OpenJK that referenced this issue May 22, 2020
Sounds that use dopplerScale (e.g., rocket launcher) exhibited a buffer
over-read. S_PaintChannelFrom16's ofst reads past end of sfx->pSoundData buffer.
To resolve this, take dopplerScale increments of ofst into consideration when
calculating count, which controls the loop for ofst.

Resolves: JACoders#1038
See also: JACoders@69800e8
xycaleth pushed a commit that referenced this issue Jun 9, 2020
Fixes #1038

ofst over-reads past the end of the pSoundData buffer. Add a bounds check
similar to S_CheckAmplitude() in codemp/client/snd_dma.cpp.

69800e8
xycaleth pushed a commit that referenced this issue Jun 9, 2020
Sounds that use dopplerScale (e.g., rocket launcher) exhibited a buffer
over-read. S_PaintChannelFrom16's ofst reads past end of sfx->pSoundData buffer.
To resolve this, take dopplerScale increments of ofst into consideration when
calculating count, which controls the loop for ofst.

Resolves: #1038
See also: 69800e8
SomaZ added a commit to SomaZ/OpenJK that referenced this issue Aug 6, 2020
* Fix Travis CI build (JACoders#955)

* Fix Travis CI build

Add missing dependencies - why doesn't aptitude just download them??

* Try apt packages using apt add-on in Travis

* Remove some packages and fix host env variable

* Add libglib2.0-dev dependency for i686

* Maybe Release and Debug flavours?

* Split Debug and Release travis builds

* Add macOS build

* Brew install for OSX build

And reorder the builds

* Try using install script again

* Fix typo when running install script

* Fix install script for macOS

* Whitespace fixes

* Add missing space

* Shared: Add SDL compile and link version info to console startup

* [SP] "Give Force" limit changed from 100, uses playermodel's max force power now

Previously, the console command "give force" only allowed the amount of force power to go up to 100 and not the actual limit of the current playermodel, because it was set to go until FORCE_POWER_MAX, which was defined as 100. Now, if you are using a playermodel with an increased amount set, that amount will be used as the maximum.

* Added manifest files again, but directly to source list this time.

Hopefully this works better than the previous attempt and does not bork things.  CMake 3.4 is required on Windows for this to work. Leaving version as is for now due to other work being done on CMake support elsewhere.

Should fix DPI awareness / scaling on Windows + Have proper version info.

* Missed the manifest in last commit.

* [SP] Fix vid_restart crash

The renderer isn't initialized until the first frame after the restart.
The game frame can run before this happens which will try to do some
operations with the renderer, causing the process to crash.

* Replace OS X -> macOS

* Upgrade to newest version of SDL2 (2.0.8)

Visit https://discourse.libsdl.org/t/sdl-2-0-8-released/23957 for release notes on changes

* Shared: Add missing audio format types for newer SDL

* MP: Fix legacy server mods to use function wrappers to protect G2 API

Prevent null pointers reaching the underlying G2 code as is done for cgame.

* MP: Fix and cleanup UI legacy mods G2 API calls

Also fix minor bug in an unused G2 API UI function.
Also minor code cleanup in cgame G2 API functions.

* MP: Fix G2 AddBolt API returning inconsistent result

In original game if the g2 pointer/ref was invalid it would return -1.  In the new modules it seems to have changed to returning to 0 here causing an inconsistency.  UI already returns -1 properly but cgame and server did not.

* MP Ded: Make G2 api more in line with vanilla regular renderer

Fixes some derpiness in cases where handle is invalid and also adds missing calls to check model pointers in some functions.

* MP: Fix possible g2 collision time desync issue

* Upgrade minimum CMake to 3.1

And update all the copyright years in those files

* Remove Xbox-related or unused tools

Some of the tools were purpose-made for assets to be used on the Xbox.
We don't need these anymore so let's remove them.

* Remove tools which were moved to OpenJK-Tools

* Add SDL2 to macOS app bundle

This will make the macOS app bundle completely self-contained (as it
should be), i.e. the client will not need to install SDL2 separately.

* openbsd build fix

* Use s_khz with SDL sound backend

And remove s_sdlSpeed

* Add missing sdl_sound.h file

* macOS CI: Upgrade Homebrew packages before installing

Travis-CI's macOS worker image currently has libpng installed at a
slightly outdated version. Unlike "apt install", "brew install"
will not upgrade a package that is already installed, and will exit
unsuccessfully when asked to do so. There does not seem to be a
Homebrew command for "upgrade these packages if installed, or install
them if not installed", so the most straightforward way seems to be
to upgrade everything before invoking brew install.

Fixes: JACoders#987

* JK2: Remove mismatched allocator from std::map typedefs

The Allocator is meant to be one that is suitable for allocating
std::pair<key, value> instances, not value instances, and the
Standard C++ library provided by gcc 8 asserts that the types match.
The closest valid allocator here would be
std::allocator<std::pair<key, value>>, but that is the default for
this template anyway, so we can just omit it.

Closes: JACoders#985
Bug-Debian: https://bugs.debian.org/905477
Signed-off-by: Simon McVittie <smcv@debian.org>

* Removed superfluous code to determine the number of compressed bones.
The compressed bone pool of a Ghoul II animation file (MDXA, .gla) is always
stored at the end of the file. It is unnecessary to iterate through all frames
to determine the number of compressed bones present on big-endian machines.

This change is applied to the vanilla renderers of the single- and multiplayer
code of JK:JA.

* Re-added code to determine the number of compressed bones.
The original code removed in commit b993a8c is now only used when dealing with
MDXA formats different than the original format (version 6) present in JK:JA.
This ensures the compressed bone count is always calculated properly.

* Changed the mdxaIndex_t struct.
It now contains a three byte array rather than a regular integer. This has been
changed so the G2_GetBonePoolIndex function (and any future implementation) can
convert the three byte integer at such an offset without having to worry about
endianness.

* Weapons: fix caching previous weaps

* Events: Skip CG_EntityEvent entirely when skip cinematics

Not sure if this is sensible, but it looks to fix some issues with cent->gent being freed or reused before handled in CG_EntityEvent as the result of large timescales.

* Fix not saving saberstyle

* Trueview: fix no idle anims with cg_trueguns

I'm not entirely sure what I added this bit of code for in the first place. Changing back to how it was before.

* Fixed a bug in SP (in the original game?) where dismemberment was harder than it needed to be. Also removed cheat flag and added archive flag to g_saberRealisticCombat, debug_subdivision, g_dismemberProbabilities

* UI: add ITEM_TYPE_SLIDER_ROTATE

and some support for an angle cvar for models. allows for nice click + drag behaviour for player model in the character selection screen.

* General: minor tidy up

* Fixed a bug in SP (in the original game?) where dismemberment was harder than it needed to be. Also removed cheat flag and added archive flag to g_saberRealisticCombat, debug_subdivision, g_dismemberProbabilities

* Remove unnecessary CPackNSIS include

* --universal option no longer available

* [MP] Merge ioquake/ioq3@b61e299

Fix exploit to reset player by sending wrong serverId

If client sends wrong serverId but is already active in the world
(CS_ACTIVE) don't resend initial gamestate for the map. This isn't a
valid situation. The player should be CS_CONNECTED or CS_PRIMED.

Resending gamestate to an active player will cause them to respawn
without dying or disconnecting. If the player had a CTF flag it gets
lost until the map is changed or restarted.

Reported by Ensiform at:

https://bugzilla.icculus.org/show_bug.cgi?id=6324

* Ghoul2 SP enhancment addressing Issue JACoders#1005 (JACoders#1008)

* Modified tr_ghoul2.cpp, Lines: 3579-3603 to address enhancment issue JACoders#1005.

* Initial commit of ROFF2 SP bug fixes.

* ROFF2 SP bug fixes (JACoders#1002, JACoders#1003) and additional notetrack enhancements.

* Added appropriate system color for ROFF2 notetrack warning and error messages.

* Using proper functions for type at hand.

* ROFF2 bug fixes (JACoders#1002, JACoders#1003) and notetrack enhancements

* Add files via upload

* Add files via upload

* Add files via upload

* Removed preprocessor defines for printing ROFF2 notetracks and replaced with if statement using "g_developer->integer"

* Fixed formatting alignment, replaced spaces with tabs for type USE notetrack else if block.

* Improve code readability... use VectorClear to reset vec3_t variables.

* Add Docker support for dedicated server

* Update Dockerfile to use ubuntu:18.04 as the base image

* Update Dockerfile to follow best practices

* Add .gitattributes rule to not mangle .sh files on Windows

* Add VS2017 and VS2019 batch files

Also ensure to use Win32 architecture for all versions.

Specifying Win32 is necessary going forward with VS2019 on Win64 host.

* Fix stencil shadows in mirrors

GL_Cull already handles if the view is a mirror or not. By also handling
it in RB_DoShadowTessEnd it renders the wrong side of the shadow
geometry. This is fixed by simply removing the mirror handling in
RB_DoShadowTessEnd.

* draw stencil shadows in one drawcall when possible

* [Shared] Explicitly sized some arrays to prevent future breakage
Fixed bad memset on cg_healthBarEnts

* [Shared] Allow non-raw mouse input via in_mouse 2

* [MP] Fix array bounds check on cg_drawCrosshair, now starts at crosshaira.tga instead of crosshairb.tga, does not allow negative index

* [MP] Less hardcoded path usage for model/saber paths

* [Shared] Use correct include guard for glext.h

* [MP] Fix missing argument in SelectRandomDeathmatchSpawnPoint forward declaration

Discovered by C++ compilation not finding an exact linker match

* Remove unnecessary CPackNSIS include

* [MP] Fix glStencilOpSeparate usage for macOS

* [SP] Fix glStencilOpSeparate usage for macOS

* Use travis brew addon to install packages

* Add discord badge pointing to "coding" channel

* Travis-CI: Move from Ubuntu 14.04 to 18.04

Ubuntu 14.04 reached EOL for mainstream support in April 2019, and I'm
about to add a dependency on a version of SDL newer than the one in
14.04. Instead of going via 16.04, which only has about a year of
support lifetime left itself, let's go directly to 18.04, currently the
latest LTS release.

Update build-dependencies accordingly.

Signed-off-by: Simon McVittie <smcv@debian.org>

* Remove FindSDL2 find-module, use sdl2-config.cmake instead

This requires SDL >= 2.0.4.

Since <https://bugzilla.libsdl.org/show_bug.cgi?id=2464> was fixed in
SDL 2.0.4, SDL behaves as a CMake "config-file package", even if it was
not itself built using CMake: it installs a sdl2-config.cmake file to
${libdir}/cmake/SDL2, which tells CMake where to find SDL's headers and
library, analogous to a pkg-config .pc file.

As a result, we no longer need to copy/paste a "find-module package"
to be able to find a system copy of SDL >= 2.0.4 with find_package(SDL2).
Find-module packages are now discouraged by the CMake developers, in
favour of having upstream projects behave as config-file packages.

This results in a small API change: FindSDL2 used to set SDL2_INCLUDE_DIR
and SDL2_LIBRARY, but the standard behaviour for config-file packages is
to set <name>_INCLUDE_DIRS and <name>_LIBRARIES. Use the CONFIG keyword
to make sure we search in config-file package mode, and will not find a
FindSDL2.cmake in some other directory that implements the old interface.

In addition to deleting redundant code, this avoids some assumptions in
FindSDL2 about the layout of a SDL installation. The current libsdl2-dev
package in Debian breaks those assumptions; this is considered a bug
and will hopefully be fixed soon, but it illustrates how fragile these
assumptions can be. We can be more robust against different installation
layouts by relying on SDL's own CMake integration.

When linking to a copy of CMake in a non-standard location, users can
now set the SDL2_DIR or CMAKE_PREFIX_PATH environment variable to point
to it; previously, these users would have used the SDL2DIR environment
variable. This continues to be unnecessary if using matching system-wide
installations of CMake and SDL2, for example both from Debian.

Mitigates: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=951087
Signed-off-by: Simon McVittie <smcv@debian.org>

* Add bounds check to resolve buffer over-read

Fixes JACoders#1038

ofst over-reads past the end of the pSoundData buffer. Add a bounds check
similar to S_CheckAmplitude() in codemp/client/snd_dma.cpp.

JACoders@69800e8

* Doppler effect sound effects cause buffer overread


Sounds that use dopplerScale (e.g., rocket launcher) exhibited a buffer
over-read. S_PaintChannelFrom16's ofst reads past end of sfx->pSoundData buffer.
To resolve this, take dopplerScale increments of ofst into consideration when
calculating count, which controls the loop for ofst.

Resolves: JACoders#1038
See also: JACoders@69800e8

* GCC 10 compliance

* Update README.md

* Split CMakeModules into Modules and Toolchains

* Remove buildbot section in README.md

* Fix Travis build

* Saber: Add MP-style list box of possible sabers. Uses notInMP to determine if sabers are valid.

* Events: avoid entity events from recently freed/reused entities. causes issues at large timescales such as during cutscene skipping.

* Revert "Events: avoid entity events from recently freed/reused entities. causes issues at large timescales such as during cutscene skipping."

This reverts commit 968b8ac.

* Try harder to load fallback renderer if we have the wrong REF_API.

* Events: better fix avoid entity events from recently freed/reused entities. causes issues at large timescales such as during cutscene skipping when the event time is before the entity free time and cent->gent is used. Also remove unnecessary setting of NPC->count on takeoff/landing for boba and rockettrooper.

* Saber: Properly set list box selection

Co-authored-by: Alex Lo <alex@acslo.com>
Co-authored-by: Ensiform <ensiform@gmail.com>
Co-authored-by: PotatoMaster <20043803+PotatoMaster@users.noreply.github.com>
Co-authored-by: Alex Lo <xycaleth@gmail.com>
Co-authored-by: David Carlier <devnexen@gmail.com>
Co-authored-by: Simon McVittie <smcv@debian.org>
Co-authored-by: AJSchat <ajschat@gmail.com>
Co-authored-by: redsaurus <redsaur@redsaurus.net>
Co-authored-by: Nick Whitlock <eezstreet@live.com>
Co-authored-by: Brandon <Yberion@users.noreply.github.com>
Co-authored-by: Archangel35757 <archangel35757@yahoo.com>
Co-authored-by: SirYodaJedi <50331474+SirYodaJedi@users.noreply.github.com>
Co-authored-by: Fabien Crespel <fabien@crespel.net>
Co-authored-by: Dion Williams <dionrhys1@gmail.com>
Co-authored-by: Razish <mrrazish@gmail.com>
Co-authored-by: Filip Gawin <filip.gawin@zoho.com>
Co-authored-by: Nam Nguyen <namn@berkeley.edu>
Co-authored-by: cagelight <cagelight@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant