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

Stack Buffer Overflow in _lou_translate when processing formatting options #1726

Closed
shuangxiangkan opened this issue Feb 20, 2025 · 3 comments · Fixed by #1735
Closed

Stack Buffer Overflow in _lou_translate when processing formatting options #1726

shuangxiangkan opened this issue Feb 20, 2025 · 3 comments · Fixed by #1735
Labels
memory error Buffer overflow, use after free, memory leak, ...

Comments

@shuangxiangkan
Copy link

Description

While fuzzing liblouis with AFL++, I discovered a heap buffer overflow vulnerability when parsing small input file

Environment

  • OS: Ubuntu 22.04
  • Compiler: Clang 16.0.6
  • AFL++ Version: afl-fuzz++4.22a

Reproduction

afl-clang-fast fuzz_translate_generic_afl.c -o fuzz_translate_generic_afl \
    -I/path/to/liblouis/include \
    /path/to/liblouis/lib/liblouis.a \
    -fsanitize=address

./fuzz_translate_generic_afl input

ASAN Log

=================================================================
==1991181==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7f95252011e2 at pc 0x5625f1edcea1 bp 0x7ffed06d2710 sp 0x7ffed06d2708
READ of size 2 at 0x7f95252011e2 thread T0
    #0 0x5625f1edcea0 in _lou_translate /srv/scratch/PAG/ksx/Fuzz/Library/liblouis/liblouis/lou_translateString.c:1195:17
    #1 0x5625f1ed5977 in lou_translate /srv/scratch/PAG/ksx/Fuzz/Library/liblouis/liblouis/lou_translateString.c:1127:9
    #2 0x5625f1ed5977 in lou_translateString /srv/scratch/PAG/ksx/Fuzz/Library/liblouis/liblouis/lou_translateString.c:1119:9
    #3 0x5625f1e9f6b2 in main /srv/scratch/PAG/ksx/Fuzz/Library/liblouis/Fuzz/reproduce/fuzz_translate_generic/fuzz_translate_generic_afl.c:115:5
    #4 0x7f952694a249 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #5 0x7f952694a304 in __libc_start_main csu/../csu/libc-start.c:360:3
    #6 0x5625f1ddf400 in _start (/srv/scratch/PAG/ksx/Fuzz/Library/liblouis/Fuzz/reproduce/fuzz_translate_generic/fuzz_translate_generic_afl+0x2a400) (BuildId: 01238ac578a325b42315b5488898247839474595)

Address 0x7f95252011e2 is located in stack of thread T0 at offset 4578 in frame
    #0 0x5625f1e9f14f in main /srv/scratch/PAG/ksx/Fuzz/Library/liblouis/Fuzz/reproduce/fuzz_translate_generic/fuzz_translate_generic_afl.c:46

  This frame has 5 object(s):
    [32, 4128) 'input' (line 47)
    [4256, 4512) 'buf' (line 49)
    [4576, 4578) 'formatting' (line 89) <== Memory access at offset 4578 overflows this variable
    [4592, 4596) 'inputLen' (line 107)
    [4608, 4612) 'outputLen' (line 108)
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow /srv/scratch/PAG/ksx/Fuzz/Library/liblouis/liblouis/lou_translateString.c:1195:17 in _lou_translate

Fuzz file and input

input.zip

fuzz_translate_generic_afl.c.zip

@bertfrees bertfrees added the memory error Buffer overflow, use after free, memory leak, ... label Feb 20, 2025
@egli egli added this to the 3.33 milestone Feb 21, 2025
@egli egli self-assigned this Feb 25, 2025
@egli
Copy link
Member

egli commented Feb 25, 2025

I used your code and your input but I do not get a log from ASAN. But I can imagine what the problem is:

If you pass some input and a typeform that is smaller than the input then the following loop will cause a memory overflow:

		for (k = 0; k < input.length; k++) {
			typebuf[k] = typeform[k];
			if (typebuf[k] & EMPHASIS) haveEmphasis = 1;
		}

It just copies the typeform into a typebuf and assumes the typeform has the same length as the input.

At the moment I do not know how to solve this, as through the API we get a pointer to the input, a pointer to the typeform and a length of the input.

@bertfrees @shuangxiangkan Any ideas?

@egli
Copy link
Member

egli commented Feb 26, 2025

I'm tempted to mark this as wontfix.

@shuangxiangkan what you have discovered is that you can shoot yourself in the foot if you lie to the API, i.e. you tell it that the buffer is of length inlen but the typeform is in reality much smaller. I do not know how to make this safer in C.

I do not think this is really a security concern, as the typeform is not user input. Instead it comes from a program using the lou_translateString API.

@egli egli removed their assignment Feb 26, 2025
@bertfrees bertfrees removed this from the 3.33 milestone Feb 26, 2025
@egli
Copy link
Member

egli commented Feb 27, 2025

I added some comments to the API to the effect that the behavior is undefined if you pass in a inbuf or a typeform that are smaller than inlen

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
memory error Buffer overflow, use after free, memory leak, ...
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants