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 varible keys_inst #12

Closed
EnchantedJohn opened this issue May 29, 2018 · 15 comments
Closed

stack-buffer-overflow in varible keys_inst #12

EnchantedJohn opened this issue May 29, 2018 · 15 comments

Comments

@EnchantedJohn
Copy link

@EnchantedJohn EnchantedJohn commented May 29, 2018

Hello,I use my company tools to fuzz test on sela.I first found the crash.Then I want to show error information to your guys.

@EnchantedJohn
Copy link
Author

@EnchantedJohn EnchantedJohn commented May 29, 2018

SimplE Lossless Audio Encoder
Copyright (c) 2015-2016. Ratul Saha
Released under MIT license

Input : /home/lx/DIVE/Trunk/bin/hfl/output/1DB330B333783C25CD43B04F3D4C575680C3C2/hfl-crash-1-{rva_0x1BEF}{code_0x8}{selaenc}
Output : output.sela
=================================================================
==108908==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffd1ff49260 at pc 0x40c6af bp 0x7ffd1ff27380 sp 0x7ffd1ff27378
WRITE of size 1 at 0x7ffd1ff49260 thread T0
    #0 0x40c6ae in init_apev2_keys (/home/lx/5_29/SELA/AFL/sela-latest/selaenc+0x40c6ae)
    #1 0x401716 in main (/home/lx/5_29/SELA/AFL/sela-latest/selaenc+0x401716)
    #2 0x7f39b5b8ef44 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21f44)
    #3 0x402cb4 (/home/lx/5_29/SELA/AFL/sela-latest/selaenc+0x402cb4)

Address 0x7ffd1ff49260 is located in stack of thread T0 at offset 138848 in frame
    #0 0x40124f in main (/home/lx/5_29/SELA/AFL/sela-latest/selaenc+0x40124f)

  This frame has 36 object(s):
    [32, 33) 'opt_lpc_order'
    [96, 97) 'rice_param_ref'
    [160, 161) 'rice_param_residue'
    [224, 226) 'channels'
    [288, 290) 'bps'
    [352, 354) 'req_int_ref'
    [416, 418) 'req_int_residues'
    [480, 482) 'samples_per_channel'
    [544, 548) 'i'
    [608, 612) 'sample_rate'
    [672, 676) 'metadata_sync'
    [736, 740) 'metadata_size'
    [800, 804) 'frame_sync'
    [864, 868) 'req_bits_ref'
    [928, 932) 'req_bits_residues'
    [992, 996) 'samples'
    [1056, 1060) 'estimated_frames'
    [1120, 1140) 'state'
    [1184, 1208) 'ape_list'
    [1248, 1344) 'tags'
    [1376, 1776) 'qtz_ref_coeffs'
    [1824, 2224) 'unsigned_ref'
    [2272, 2672) 'encoded_ref'
    [2720, 3520) 'ref'
    [3552, 4360) 'lpc'
    [4416, 5224) 'autocorr'
    [5280, 9376) 'short_samples'
    [9408, 17600) 'int_samples'
    [17632, 25824) 'residues'
    [25856, 34048) 'u_residues'
    [34080, 42272) 'encoded_residues'
    [42304, 58688) 'qtz_samples'
    [58720, 138720) 'lpc_mat'
    [138752, 138756) 'magic_number'
    [138816, 138848) 'keys_inst' <== Memory access at offset 138848 overflows this variable
    [138880, 138912) 'header'
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow ??:0 init_apev2_keys
Shadow bytes around the buggy address:
  0x100023fe11f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100023fe1200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100023fe1210: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100023fe1220: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100023fe1230: 00 00 00 00 00 00 00 00 00 00 00 00 f2 f2 f2 f2
=>0x100023fe1240: 04 f4 f4 f4 f2 f2 f2 f2 00 00 00 00[f2]f2 f2 f2
  0x100023fe1250: 00 00 00 00 f3 f3 f3 f3 f3 f3 f3 f3 00 00 00 00
  0x100023fe1260: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100023fe1270: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100023fe1280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100023fe1290: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Contiguous container OOB:fc
  ASan internal:           fe
==108908==ABORTING
@EnchantedJohn
Copy link
Author

@EnchantedJohn EnchantedJohn commented May 29, 2018

Then it is GDB information:

SimplE Lossless Audio Encoder
Copyright (c) 2015-2016. Ratul Saha
Released under MIT license

Input : /home/lx/DIVE/Trunk/bin/hfl/output/1DB330B333783C25CD43B04F3D4C575680C3C2/hfl-crash-1-{rva_0x1BEF}{code_0x8}{selaenc}
Output : output.sela
WAV file detected

Stream Information
------------------
Sampling Rate : 44100 Hz
Bits per sample : 16
Channels : 1 (Monoaural)

Metadata
--------
No metadata found.
[                         ]

Statistics
----------
15 frames written (0min 0sec)
Compression Ratio : 35.97%

Program received signal SIGFPE, Arithmetic exception.
0x0000000000401bef in main ()
(gdb) bt
#0  0x0000000000401bef in main ()
@EnchantedJohn
Copy link
Author

@EnchantedJohn EnchantedJohn commented May 29, 2018

(gdb) i r
rax            0x2b028	176168
rbx            0x0	0
rcx            0x0	0
rdx            0x0	0
rsi            0x1	1
rdi            0x7ffff7ace1c0	140737348690368
rbp            0x5605	0x5605
rsp            0x7ffffffdc940	0x7ffffffdc940
r8             0x7ffff7fc7740	140737353905984
r9             0x7fffffff	2147483647
r10            0x1	1
r11            0x246	582
r12            0xef2c	61228
r13            0x60a490	6333584
r14            0x60a250	6333008
r15            0x60a010	6332432
rip            0x401bef	0x401bef <main+4063>
eflags         0x10246	[ PF ZF IF RF ]
cs             0x33	51
ss             0x2b	43
ds             0x0	0
es             0x0	0
fs             0x0	0
gs             0x0	0
(gdb) x/10i $pc
=> 0x401bef <main+4063>:	div    %rcx
   0x401bf2 <main+4066>:	mov    $0x406905,%edx
   0x401bf7 <main+4071>:	mov    %rax,%rcx
   0x401bfa <main+4074>:	xor    %eax,%eax
   0x401bfc <main+4076>:	callq  0x400be0 <__fprintf_chk@plt>
   0x401c01 <main+4081>:	mov    %r13,%rdi
   0x401c04 <main+4084>:	callq  0x400a80 <free@plt>
   0x401c09 <main+4089>:	lea    0xf0(%rsp),%rdi
   0x401c11 <main+4097>:	callq  0x4058e0 <destroy_wav_tags>
   0x401c16 <main+4102>:	lea    0xd0(%rsp),%rsi
@EnchantedJohn
Copy link
Author

@EnchantedJohn EnchantedJohn commented May 29, 2018

I think stack-buffer-overflow is due to varible keys_inst. and finally div zero.
then I want to show the encode.c:

85 
 86         //Metadata data structures
 87         wav_tags tags;
 88         apev2_state state;
 89         apev2_keys keys_inst;    //I think it is the key problem 
 90         apev2_hdr_ftr header;
 91         apev2_item_list ape_list;
 92 
 93         //Init wav tags
 94         init_wav_tags(&tags);
 95 
 96         //Init apev2 state
 97         init_apev2(&state);
 98 
 99         //Init apev2 keys
100         init_apev2_keys(&state,&keys_inst);
101 
102         //Init apev2 header
103         init_apev2_header(&state,&header);
104 
105         //Init apev2 item link list
106         init_apev2_item_list(&state,&ape_list);
107 
108         //Check the wav file
109         int32_t is_wav = check_wav_file(infile,&sample_rate,&channels,&bps,&samples,&tags);
110         uint32_t estimated_frames = ceil((float)samples/(channels * BLOCK_SIZE * sizeof(int16_t)));
@sahaRatul
Copy link
Owner

@sahaRatul sahaRatul commented May 29, 2018

Please provide the input file.

@EnchantedJohn
Copy link
Author

@EnchantedJohn EnchantedJohn commented May 31, 2018

okay,you can use empty file.then sela will crash.

@EnchantedJohn
Copy link
Author

@EnchantedJohn EnchantedJohn commented May 31, 2018

It is due to ArrayIndexOutOfBoundsException in stack-buffer-overflow core/apev2.c:99 init_apev2_keys
apev2_keys define :

typedef struct apev2_keys
 51 {
 52         char title[5];
 53         char artist[6];
 54         char album[6];
 55         char year[4];
 56         char genre[5];
 57         char comment[6];
 58 }apev2_keys;
92         //Comment key
 93         inst->comment[0] = 'C';
 94         inst->comment[1] = 'o';
 95         inst->comment[2] = 'm';
 96         inst->comment[3] = 'm';
 97         inst->comment[4] = 'e';
 98         inst->comment[5] = 'n';
 99         inst->comment[6] = 't';
100 
101         state->ape_last_state = APE_KEYS_INIT_SUCCESS;
102         return APE_KEYS_INIT_SUCCESS;
@sahaRatul
Copy link
Owner

@sahaRatul sahaRatul commented May 31, 2018

Increased size of comment array from 6 to 7. Should be fixed now.

@sahaRatul
Copy link
Owner

@sahaRatul sahaRatul commented May 31, 2018

Please confirm if you are still getting error on your tests.

@EnchantedJohn
Copy link
Author

@EnchantedJohn EnchantedJohn commented May 31, 2018

yes, I also change this Bug.But I find another. I want to show you my process

@EnchantedJohn
Copy link
Author

@EnchantedJohn EnchantedJohn commented May 31, 2018

In calc_residue() function:

...
for(k = ord + 1; k < N; k++)
	{
		y = corr;

		y += (int64_t)(coff[0] * samples[k - 0]);
		y += (int64_t)(coff[1] * samples[k - 1]);
		y += (int64_t)(coff[2] * samples[k - 2]);
		y += (int64_t)(coff[3] * samples[k - 3]);
		y += (int64_t)(coff[4] * samples[k - 4]);
		y += (int64_t)(coff[5] * samples[k - 5]);
		y += (int64_t)(coff[6] * samples[k - 6]);
		y += (int64_t)(coff[7] * samples[k - 7]);
		y += (int64_t)(coff[8] * samples[k - 8]);
		y += (int64_t)(coff[9] * samples[k - 9]);
		y += (int64_t)(coff[10] * samples[k - 10]);
		y += (int64_t)(coff[11] * samples[k - 11]);
		y += (int64_t)(coff[12] * samples[k - 12]);
		y += (int64_t)(coff[13] * samples[k - 13]);
		y += (int64_t)(coff[14] * samples[k - 14]);
		y += (int64_t)(coff[15] * samples[k - 15]);
		y += (int64_t)(coff[16] * samples[k - 16]);
		y += (int64_t)(coff[17] * samples[k - 17]);
		y += (int64_t)(coff[18] * samples[k - 18]);
		y += (int64_t)(coff[19] * samples[k - 19]);
		y += (int64_t)(coff[20] * samples[k - 20]);
		y += (int64_t)(coff[21] * samples[k - 21]);
		y += (int64_t)(coff[22] * samples[k - 22]);
		y += (int64_t)(coff[23] * samples[k - 23]);
		y += (int64_t)(coff[24] * samples[k - 24]);
		y += (int64_t)(coff[25] * samples[k - 25]);
		y += (int64_t)(coff[26] * samples[k - 26]);
		y += (int64_t)(coff[27] * samples[k - 27]);
		y += (int64_t)(coff[28] * samples[k - 28]);
		y += (int64_t)(coff[29] * samples[k - 29]);
		y += (int64_t)(coff[30] * samples[k - 30]);
		y += (int64_t)(coff[31] * samples[k - 31]);
		y += (int64_t)(coff[32] * samples[k - 32]);
		y += (int64_t)(coff[33] * samples[k - 33]);
		y += (int64_t)(coff[34] * samples[k - 34]);
		y += (int64_t)(coff[35] * samples[k - 35]);
		y += (int64_t)(coff[36] * samples[k - 36]);
		y += (int64_t)(coff[37] * samples[k - 37]);
		y += (int64_t)(coff[38] * samples[k - 38]);
		y += (int64_t)(coff[39] * samples[k - 39]);
		y += (int64_t)(coff[40] * samples[k - 40]);
		y += (int64_t)(coff[41] * samples[k - 41]);
		y += (int64_t)(coff[42] * samples[k - 42]);
		y += (int64_t)(coff[43] * samples[k - 43]);
		y += (int64_t)(coff[44] * samples[k - 44]);
		y += (int64_t)(coff[45] * samples[k - 45]);
		y += (int64_t)(coff[46] * samples[k - 46]);
		y += (int64_t)(coff[47] * samples[k - 47]);
		y += (int64_t)(coff[48] * samples[k - 48]);
		y += (int64_t)(coff[49] * samples[k - 49]);
		y += (int64_t)(coff[50] * samples[k - 50]);
		y += (int64_t)(coff[51] * samples[k - 51]);
		y += (int64_t)(coff[52] * samples[k - 52]);
		y += (int64_t)(coff[53] * samples[k - 53]);
		y += (int64_t)(coff[54] * samples[k - 54]);
		y += (int64_t)(coff[55] * samples[k - 55]);
		y += (int64_t)(coff[56] * samples[k - 56]);
		y += (int64_t)(coff[57] * samples[k - 57]);
		y += (int64_t)(coff[58] * samples[k - 58]);
		y += (int64_t)(coff[59] * samples[k - 59]);
		y += (int64_t)(coff[60] * samples[k - 60]);
		y += (int64_t)(coff[61] * samples[k - 61]);
		y += (int64_t)(coff[62] * samples[k - 62]);
		y += (int64_t)(coff[63] * samples[k - 63]);
		y += (int64_t)(coff[64] * samples[k - 64]);
		y += (int64_t)(coff[65] * samples[k - 65]);
		y += (int64_t)(coff[66] * samples[k - 66]);
		y += (int64_t)(coff[67] * samples[k - 67]);
		y += (int64_t)(coff[68] * samples[k - 68]);
		y += (int64_t)(coff[69] * samples[k - 69]);
		y += (int64_t)(coff[70] * samples[k - 70]);
		y += (int64_t)(coff[71] * samples[k - 71]);
		y += (int64_t)(coff[72] * samples[k - 72]);
		y += (int64_t)(coff[73] * samples[k - 73]);
		y += (int64_t)(coff[74] * samples[k - 74]);
		y += (int64_t)(coff[75] * samples[k - 75]);
		y += (int64_t)(coff[76] * samples[k - 76]);
		y += (int64_t)(coff[77] * samples[k - 77]);
		y += (int64_t)(coff[78] * samples[k - 78]);
		y += (int64_t)(coff[79] * samples[k - 79]);
		y += (int64_t)(coff[80] * samples[k - 80]);
		y += (int64_t)(coff[81] * samples[k - 81]);
		y += (int64_t)(coff[82] * samples[k - 82]);
		y += (int64_t)(coff[83] * samples[k - 83]);
		y += (int64_t)(coff[84] * samples[k - 84]);
		y += (int64_t)(coff[85] * samples[k - 85]);
		y += (int64_t)(coff[86] * samples[k - 86]);
		y += (int64_t)(coff[87] * samples[k - 87]);
		y += (int64_t)(coff[88] * samples[k - 88]);
		y += (int64_t)(coff[89] * samples[k - 89]);
		y += (int64_t)(coff[90] * samples[k - 90]);
		y += (int64_t)(coff[91] * samples[k - 91]);
		y += (int64_t)(coff[92] * samples[k - 92]);
		y += (int64_t)(coff[93] * samples[k - 93]);
		y += (int64_t)(coff[94] * samples[k - 94]);
		y += (int64_t)(coff[95] * samples[k - 95]);
		y += (int64_t)(coff[96] * samples[k - 96]);
		y += (int64_t)(coff[97] * samples[k - 97]);
		y += (int64_t)(coff[98] * samples[k - 98]);
		y += (int64_t)(coff[99] * samples[k - 99]);
		y += (int64_t)(coff[100] * samples[k - 100]);
		
		//for(i = 0; i <= ord; i++)
			//y += (int64_t)(coff[i] * samples[k-i]);
		residues[k] = samples[k] - (int32_t)(y >> Q);
	}

	return;

when my testcase k=91,then crash caused by ArrayIndexOutOfBoundsException.

@EnchantedJohn
Copy link
Author

@EnchantedJohn EnchantedJohn commented May 31, 2018

then there is my GDB information:

(gdb) print k
$1 = 91
(gdb)

but when y += (int64_t)(coff[92] * samples[k - 92]); ,crash was created.

@sahaRatul
Copy link
Owner

@sahaRatul sahaRatul commented Jun 28, 2018

@EnchantedJohn

19b07d2

Should fix this issue.

@EnchantedJohn
Copy link
Author

@EnchantedJohn EnchantedJohn commented Jun 29, 2018

Ok,I will close it.Thanks again!

@sahaRatul
Copy link
Owner

@sahaRatul sahaRatul commented Jun 29, 2018

Is it causing buffer overflow exceptions now in your test cases?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants
You can’t perform that action at this time.