tkomatsu / minishell

my own shell like bash
MIT License
3 stars 0 forks source link

t_listでのtokenの読み込み #31

Closed tkomatsu closed 3 years ago

tkomatsu commented 3 years ago
minishell on  dev_read [$!]
❯ lldb ./minishell
(lldb) target create "./minishell"
Current executable set to '/Users/tkomatsu/Documents/42/minishell/minishell' (x86_64).
(lldb) r
Process 55279 launched: '/Users/tkomatsu/Documents/42/minishell/minishell' (x86_64)

WELCOME TO MINISHELL

> hhd
=================================================================
==55279==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000234 at pc 0x000100002ba4 bp 0x7ffeefbff440 sp 0x7ffeefbff438
READ of size 1 at 0x602000000234 thread T0
    #0 0x100002ba3 in split_tokens read_tokens.c:31
    #1 0x100002f5b in read_tokens read_tokens.c:47
    #2 0x10000223e in minish_loop minishell.c:64
    #3 0x100002289 in main minishell.c:75
    #4 0x7fff69525cc8 in start+0x0 (libdyld.dylib:x86_64+0x1acc8)

0x602000000234 is located 0 bytes to the right of 4-byte region [0x602000000230,0x602000000234)
allocated by thread T0 here:
    #0 0x10016617d in wrap_malloc+0x9d (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x4917d)
    #1 0x100006b73 in ft_strdup+0x33 (minishell:x86_64+0x100006b73)
    #2 0x1000060bf in gnl_return+0x4f (minishell:x86_64+0x1000060bf)
    #3 0x100005f73 in get_next_line+0xf3 (minishell:x86_64+0x100005f73)
    #4 0x100002318 in read_arg read_arg.c:67
    #5 0x100002f22 in read_tokens read_tokens.c:46
    #6 0x10000223e in minish_loop minishell.c:64
    #7 0x100002289 in main minishell.c:75
    #8 0x7fff69525cc8 in start+0x0 (libdyld.dylib:x86_64+0x1acc8)

SUMMARY: AddressSanitizer: heap-buffer-overflow read_tokens.c:31 in split_tokens
Shadow bytes around the buggy address:
  0x1c03fffffff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1c0400000000: fa fa fd fd fa fa 00 00 fa fa fd fd fa fa fd fd
  0x1c0400000010: fa fa fd fd fa fa 00 00 fa fa 00 00 fa fa 00 06
  0x1c0400000020: fa fa 00 fa fa fa 00 07 fa fa 00 00 fa fa 00 00
  0x1c0400000030: fa fa 00 00 fa fa 00 06 fa fa 00 07 fa fa 00 06
=>0x1c0400000040: fa fa fd fa fa fa[04]fa fa fa 01 fa fa fa 00 00
  0x1c0400000050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c0400000060: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c0400000070: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c0400000080: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c0400000090: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
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
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
2021-01-26 21:11:37.453625+0900 minishell[55279:529334] =================================================================
2021-01-26 21:11:37.454198+0900 minishell[55279:529334] ==55279==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000234 at pc 0x000100002ba4 bp 0x7ffeefbff440 sp 0x7ffeefbff438
2021-01-26 21:11:37.454258+0900 minishell[55279:529334] READ of size 1 at 0x602000000234 thread T0
2021-01-26 21:11:37.454275+0900 minishell[55279:529334]     #0 0x100002ba3 in split_tokens read_tokens.c:31
2021-01-26 21:11:37.454290+0900 minishell[55279:529334]     #1 0x100002f5b in read_tokens read_tokens.c:47
2021-01-26 21:11:37.454304+0900 minishell[55279:529334]     #2 0x10000223e in minish_loop minishell.c:64
2021-01-26 21:11:37.454318+0900 minishell[55279:529334]     #3 0x100002289 in main minishell.c:75
2021-01-26 21:11:37.454332+0900 minishell[55279:529334]     #4 0x7fff69525cc8 in start+0x0 (libdyld.dylib:x86_64+0x1acc8)
2021-01-26 21:11:37.454348+0900 minishell[55279:529334]
2021-01-26 21:11:37.454361+0900 minishell[55279:529334] 0x602000000234 is located 0 bytes to the right of 4-byte region [0x602000000230,0x602000000234)
2021-01-26 21:11:37.454377+0900 minishell[55279:529334] allocated by thread T0 here:
2021-01-26 21:11:37.454392+0900 minishell[55279:529334]     #0 0x10016617d in wrap_malloc+0x9d (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x4917d)
2021-01-26 21:11:37.454408+0900 minishell[55279:529334]     #1 0x100006b73 in ft_strdup+0x33 (minishell:x86_64+0x100006b73)
2021-01-26 21:11:37.454424+0900 minishell[55279:529334]     #2 0x1000060bf in gnl_return+0x4f (minishell:x86_64+0x1000060bf)
2021-01-26 21:11:37.454439+0900 minishell[55279:529334]     #3 0x100005f73 in get_next_line+0xf3 (minishell:x86_64+0x100005f73)
2021-01-26 21:11:37.454455+0900 minishell[55279:529334]     #4 0x100002318 in read_arg read_arg.c:67
2021-01-26 21:11:37.454469+0900 minishell[55279:529334]     #5 0x100002f22 in read_tokens read_tokens.c:46
2021-01-26 21:11:37.454483+0900 minishell[55279:529334]     #6 0x10000223e in minish_loop minishell.c:64
2021-01-26 21:11:37.454497+0900 minishell[55279:529334]     #7 0x100002289 in main minishell.c:75
2021-01-26 21:11:37.454512+0900 minishell[55279:529334]     #8 0x7fff69525cc8 in start+0x0 (libdyld.dylib:x86_64+0x1acc8)
2021-01-26 21:11:37.454526+0900 minishell[55279:529334]
2021-01-26 21:11:37.454537+0900 minishell[55279:529334] SUMMARY: AddressSanitizer: heap-buffer-overflow read_tokens.c:31 in split_tokens
2021-01-26 21:11:37.454552+0900 minishell[55279:529334] Shadow bytes around the buggy address:
2021-01-26 21:11:37.454566+0900 minishell[55279:529334]   0x1c03fffffff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
2021-01-26 21:11:37.454581+0900 minishell[55279:529334]   0x1c0400000000: fa fa fd fd fa fa 00 00 fa fa fd fd fa fa fd fd
2021-01-26 21:11:37.454596+0900 minishell[55279:529334]   0x1c0400000010: fa fa fd fd fa fa 00 00 fa fa 00 00 fa fa 00 06
2021-01-26 21:11:37.454611+0900 minishell[55279:529334]   0x1c0400000020: fa fa 00 fa fa fa 00 07 fa fa 00 00 fa fa 00 00
2021-01-26 21:11:37.454626+0900 minishell[55279:529334]   0x1c0400000030: fa fa 00 00 fa fa 00 06 fa fa 00 07 fa fa 00 06
2021-01-26 21:11:37.454641+0900 minishell[55279:529334] =>0x1c0400000040: fa fa fd fa fa fa[04]fa fa fa 01 fa fa fa 00 00
2021-01-26 21:11:37.454656+0900 minishell[55279:529334]   0x1c0400000050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
2021-01-26 21:11:37.454671+0900 minishell[55279:529334]   0x1c0400000060: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
2021-01-26 21:11:37.454686+0900 minishell[55279:529334]   0x1c0400000070: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
2021-01-26 21:11:37.454701+0900 minishell[55279:529334]   0x1c0400000080: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
2021-01-26 21:11:37.454717+0900 minishell[55279:529334]   0x1c0400000090: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
2021-01-26 21:11:37.454732+0900 minishell[55279:529334] Shadow byte legend (one shadow byte represents 8 application bytes):
2021-01-26 21:11:37.454752+0900 minishell[55279:529334]   Addressable:           00
2021-01-26 21:11:37.454775+0900 minishell[55279:529334]   Partially addressable: 01 02 03 04 05 06 07
2021-01-26 21:11:37.454788+0900 minishell[55279:529334]   Heap left redzone:       fa
2021-01-26 21:11:37.454801+0900 minishell[55279:529334]   Freed heap region:       fd
2021-01-26 21:11:37.454814+0900 minishell[55279:529334]   Stack left redzone:      f1
2021-01-26 21:11:37.454827+0900 minishell[55279:529334]   Stack mid redzone:       f2
2021-01-26 21:11:37.454839+0900 minishell[55279:529334]   Stack right redzone:     f3
2021-01-26 21:11:37.454851+0900 minishell[55279:529334]   Stack after return:      f5
2021-01-26 21:11:37.454864+0900 minishell[55279:529334]   Stack use after scope:   f8
2021-01-26 21:11:37.454878+0900 minishell[55279:529334]   Global redzone:          f9
2021-01-26 21:11:37.454891+0900 minishell[55279:529334]   Global init order:       f6
2021-01-26 21:11:37.454904+0900 minishell[55279:529334]   Poisoned by user:        f7
2021-01-26 21:11:37.454918+0900 minishell[55279:529334]   Container overflow:      fc
2021-01-26 21:11:37.454931+0900 minishell[55279:529334]   Array cookie:            ac
2021-01-26 21:11:37.454945+0900 minishell[55279:529334]   Intra object redzone:    bb
2021-01-26 21:11:37.454957+0900 minishell[55279:529334]   ASan internal:           fe
2021-01-26 21:11:37.454970+0900 minishell[55279:529334]   Left alloca redzone:     ca
2021-01-26 21:11:37.454983+0900 minishell[55279:529334]   Right alloca redzone:    cb
2021-01-26 21:11:37.454996+0900 minishell[55279:529334]   Shadow gap:              cc
==55279==ABORTING
(lldb) AddressSanitizer report breakpoint hit. Use 'thread info -s' to get extended information about the report.
Process 55279 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = Heap buffer overflow
    frame #0: 0x000000010016eb20 libclang_rt.asan_osx_dynamic.dylib`__asan::AsanDie()
libclang_rt.asan_osx_dynamic.dylib`__asan::AsanDie:
->  0x10016eb20 <+0>: pushq  %rbp
    0x10016eb21 <+1>: movq   %rsp, %rbp
    0x10016eb24 <+4>: pushq  %rbx
    0x10016eb25 <+5>: pushq  %rax
Target 0: (minishell) stopped.
tkomatsu commented 3 years ago

https://github.com/tkomatsu/minishell/blob/27153c43f62bee549db5dd5f7c2169abaf9351b0/srcs/read/read_tokens.c#L42-L64 再帰からwhileのループ処理にして動くことを確認。 デバッグフラグを付けずにコンパイルするとセグフォが発生。

tkomatsu commented 3 years ago
❯ ./minishell

WELCOME TO MINISHELL

> hello
[ 0]hello
> world
[ 0]hello
[ 1]world
> this
[ 0]hello
[ 1]world
[ 2]this
> is test
[ 0]hello
[ 1]world
[ 2]this
[ 3]is
[ 4]test
>

毎回連結リストの先頭を参照してしまっている。 https://github.com/tkomatsu/minishell/blob/27153c43f62bee549db5dd5f7c2169abaf9351b0/srcs/minishell.c#L55-L68 whileが回る度にリセットする必要がある。

tkomatsu commented 3 years ago

https://github.com/tkomatsu/minishell/blob/2b379564fad6862166fc6c38ae04b44bc03c3fc3/srcs/read/read_tokens.c#L89-L98 read_tokens()の呼び出し時に、連結リストを初期化するように変更。 デバグフラグなしだとセグフォが発生するのは改善せず。

tkomatsu commented 3 years ago
minishell on  dev_read [$!]
❯ make debug
Removing object files and program ...
█████████████████████
Compiled source files
████████████████████████████████████████████████████████████████████████
Compiled libft
Finish compiling minishell!
Try "./minishell" to use
Debug build done
minishell on  dev_read [$!]
❯ lldb minishell
(lldb) target create "minishell"
Current executable set to '/Users/tkomatsu/Documents/42/minishell/minishell' (x86_64).
(lldb) r
Process 8741 launched: '/Users/tkomatsu/Documents/42/minishell/minishell' (x86_64)

WELCOME TO MINISHELL

> hello
Process 8741 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
    frame #0: 0x0000000100001d08 minishell`test_tokens(tokens=0x00000001000e2b50) at minishell.c:24:33
   21       for (int i = 0; tokens; i++)
   22       {
   23           token = (t_token*)tokens->content;
-> 24           printf("[%2d]%s\n", i, token->word);
   25           tokens = tokens->next;
   26       }
   27   }
Target 0: (minishell) stopped.
(lldb) exit
Quitting LLDB will kill one or more processes. Do you really want to proceed: [Y/n] Y
minishell on  dev_read [$!]
❯

ヒープ領域とスタック領域をごちゃ混ぜにして使ってしまっているのが理解できなくなっている原因っぽい。

tkomatsu commented 3 years ago
echo hello
0: echo, SPACE
1: hello, END
tkomatsu commented 3 years ago
echo                     hello
0: echo, SPACE
1: hello, END
tkomatsu commented 3 years ago
echo hello world
0: echo, SPACE
1: hello, SPACE
2: world, END
tkomatsu commented 3 years ago
echo "hello world"
0: echo, SPACE
1: "hello world", END
tkomatsu commented 3 years ago
echo 'hello world'
0: echo, SPACE
1: 'hello world', END
tkomatsu commented 3 years ago

シングルクォートとダブルクォートをreadの段階で外しちゃうと、$stringが展開出来なくなっちゃうから残さないといけないね

tkomatsu commented 3 years ago

これ特に問題なくなってるはずなので、閉じます。