PicoC v3.2.2 には、variable.c に NULL ポインタ参照の脆弱性があることが判明しました。Picoc を使用するプロジェクトやライブラリも、この問題の影響を受けます。例としては、picoc-js が挙げられます。
PicoC の NULL ポインタ参照の脆弱性を再現するには、まず PicoC ライブラリとインタプリタの脆弱性のあるバージョン (v3.2.2) をダウンロードしてコンパイルする必要があります:
git clone https://github.com/jpoirier/picoc.git
cd picoc
git checkout a97d94fa3d4d35c6b78b7de69faac7643e34de22
make
このリポジトリに含まれている poc.c ファイルに対して、スクリプトモードでインタプリタを実行します:
$ ./picoc -s poc.c
プログラムはセグメンテーションフォールト (segfault) を引き起こし、クラッシュします。これは、ライブラリまたはインタプリタによって捕捉・処理されない NULL ポインタ参照が原因です。この問題が発生している場所をより明確にするために、アドレスサニタイザ (ASAN) を使用してプロジェクトを再コンパイルできます。Makefile の CFLAGS 変数に -fsanitize=address を追加し、ライブラリを再コンパイルしましょう:
CFLAGS=-Wall -g -std=gnu11 -pedantic -DUNIX_HOST -DVER=\"`git show-ref --abbrev=8 --head --hash head`\" -DTAG=\"`git describe --abbrev=0 --tags`\" -fsanitize=address
ライブラリとインタプリタを再コンパイルします (picoc のルートディレクトリから):
make clean
make
プログラムを実行すると、ASAN から以下の出力が得られ、NULL ポインタ参照が variable.c の 519 行目で発生していることが示されます:
AddressSanitizer:DEADLYSIGNAL
=================================================================
==157769==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000018 (pc 0x55b55571240e bp 0x7ffe4f5c39b0 sp 0x7ffe4f5c3980 T0)
==157769==The signal is caused by a READ memory access.
==157769==Hint: address points to the zero page.
#0 0x55b55571240e in VariableDereferencePointer /dev/shm/picoc/variable.c:519
#1 0x55b5556fefea in ExpressionStackPushDereference /dev/shm/picoc/expression.c:430
#2 0x55b555701881 in ExpressionPrefixOperator /dev/shm/picoc/expression.c:687
#3 0x55b5557053d5 in ExpressionStackCollapse /dev/shm/picoc/expression.c:1257
#4 0x55b555706e35 in ExpressionParse /dev/shm/picoc/expression.c:1553
#5 0x55b5556fb6a0 in ParseStatement /dev/shm/picoc/parse.c:646
#6 0x55b5556fd380 in PicocParse /dev/shm/picoc/parse.c:897
#7 0x55b555715d0e in PicocPlatformScanFile platform/platform_unix.c:129
#8 0x55b5556ec213 in main /dev/shm/picoc/picoc.c:62
#9 0x7f15bd767189 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
#10 0x7f15bd767244 in __libc_start_main_impl ../csu/libc-start.c:381
#11 0x55b5556ebd40 in _start (/dev/shm/picoc/picoc+0x16d40)
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /dev/shm/picoc/variable.c:519 in VariableDereferencePointer
==157769==ABORTING
519: *DerefType = PointerValue->Typ->FromType;