GithubHelp home page GithubHelp logo

0branch / boron Goto Github PK

View Code? Open in Web Editor NEW
20.0 4.0 2.0 1.91 MB

Boron is a scripting language similar to Rebol. The interpreter is a C library which may be copied under the terms of the LGPLv3. (Mirror of: git://git.code.sf.net/p/urlan/boron/code.)

Home Page: http://urlan.sourceforge.net/boron/

License: GNU Lesser General Public License v3.0

C 83.50% Brainfuck 9.59% C++ 4.86% Makefile 0.49% Shell 0.12% Limbo 1.44%
rebol

boron's People

Contributors

drkameleon avatar wickedsmoke avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

smorimura rgchris

boron's Issues

Heap Overflows in Libboron v2.0.8

Hi!

While I was running boron in my environment, I happened to stumble upon 2 heap buffer overflows in the libboron library (libboron.so.2 version 2.0.8) when processing slightly malformed input. I have included reproduction files and tried my best to pinpoint the location of both heap buffer overflows. I tested this on both Mac (x86_64) and Linux (x86_64):

Files for reproduction

reproduction.zip

Compiling

git clone https://github.com/0branch/boron.git
cd boron
./configure && make
sudo make install && sudo ldconfig

Heap buffer overflow in ur_parseBlockI at i_parse_blk.c:

int ur_parseBlockI( UBlockParser* par, const uint8_t* pc, const UCell* it )

First, I executed boron against the file that produced the crash:

$ ./boron ur_parseBlockI_overflow.b 
malloc(): invalid size (unsorted)
zsh: IOT instruction  ./boron ur_parseBlockI_overflow.b

The output made be believe that there was a heap overflow corrupting a heap chunk in the unsorted bin, so I compiled the project with address sanitizer and debug symbols to verify:

Makefile

# Boron Makefile for UNIX systems.

VER=2.0.8

DESTDIR ?= /usr/local
BIN_DIR=$(DESTDIR)/bin
LIB_DIR=$(DESTDIR)/lib
INC_DIR=$(DESTDIR)/include/boron
MAN_DIR=$(DESTDIR)/share/man/man1
VIM_DIR=$(DESTDIR)/share/vim/vimfiles/syntax

OS := $(shell uname)

CFLAGS = -pipe -pedantic -Wall -W -Iinclude -Iurlan -Ieval -Isupport -g -fsanitize=address -DDEBUG
#CFLAGS += -O3 -DNDEBUG
#CFLAGS += -g -DDEBUG

ifeq ($(OS), Darwin)
CFLAGS += -std=c99
AR_LIB = libtool -static -o
else
CFLAGS += -std=gnu99 -fPIC
AR_LIB = ar rc
ifneq (,$(wildcard /usr/lib64/libc.so))
LIB_DIR=$(DESTDIR)/lib64
else ifneq (,$(wildcard /usr/lib/x86_64-linux-gnu/.))
LIB_DIR=$(DESTDIR)/lib/x86_64-linux-gnu
endif
endif

CONFIG := $(shell cat config.opt)
ifneq (,$(findstring _STATIC,$(CONFIG)))
	STATIC_LIB = true
endif

LIBS := -lm

ODIR = .obj
OBJ_FN = env.o array.o binary.o block.o coord.o date.o path.o \
	string.o context.o gc.o serialize.o tokenize.o \
	vector.o parse_block.o parse_string.o
OBJ_FN += str.o mem_util.o quickSortIndex.o fpconv.o
OBJ_FN += os.o boron.o port_file.o wait.o
ifneq (,$(findstring _HASHMAP,$(CONFIG)))
OBJ_FN += hashmap.o
endif
ifneq (,$(findstring _RANDOM,$(CONFIG)))
OBJ_FN += well512.o random.o
endif
ifneq (,$(findstring _SOCKET,$(CONFIG)))
OBJ_FN += port_socket.o
endif
ifneq (,$(findstring _THREAD,$(CONFIG)))
OBJ_FN += port_thread.o
ifeq ($(OS), Linux)
LIBS += -lpthread
endif
endif
LIB_OBJS = $(addprefix $(ODIR)/,$(OBJ_FN))


MAIN_FN = main.o 
ifneq (,$(findstring _LINENOISE,$(CONFIG)))
MAIN_FN += linenoise.o
else
EXE_LIBS += -lreadline -lhistory
endif
ifneq (,$(findstring _COMPRESS=1,$(CONFIG)))
LIBS += -lz
endif
ifneq (,$(findstring _COMPRESS=2,$(CONFIG)))
LIBS += -lbz2
endif
EXE_OBJS = $(addprefix $(ODIR)/,$(MAIN_FN))

ifdef STATIC_LIB
BORON_LIB = libboron.a
EXE_LIBS += $(LIBS)
else ifeq ($(OS), Darwin)
BORON_LIB = libboron.dylib
else
BORON_LIB = libboron.so.$(VER)
endif


$(ODIR)/%.o: urlan/%.c
	cc -c $(CFLAGS) $(CONFIG) $< -o $@
$(ODIR)/%.o: support/%.c
	cc -c $(CFLAGS) $(CONFIG) $< -o $@
$(ODIR)/%.o: eval/%.c
	cc -c $(CFLAGS) $(CONFIG) $< -o $@

boron: $(EXE_OBJS) $(BORON_LIB)
	cc $^ -o $@ $(EXE_LIBS) -g -fsanitize=address

$(ODIR)/os.o: unix/os.c
	cc -c $(CFLAGS) $(CONFIG) $< -o $@

$(EXE_OBJS): | $(ODIR)
$(LIB_OBJS): | $(ODIR)
$(ODIR):
	mkdir -p $@

$(BORON_LIB): $(LIB_OBJS)
ifdef STATIC_LIB
	$(AR_LIB) $@ $^
	ranlib $@
else ifeq ($(OS), Darwin)
	libtool -dynamiclib -o $@ $^ -install_name @rpath/$(BORON_LIB) $(LIBS)
else
	cc -o $@  -shared -g -fsanitize=address -Wl,-soname,libboron.so.2 $^ $(LIBS)
	ln -sf $(BORON_LIB) libboron.so.2
	ln -sf $(BORON_LIB) libboron.so
endif

.PHONY: clean install uninstall install-dev uninstall-dev

clean:
	rm -f boron $(BORON_LIB) $(LIB_OBJS) $(EXE_OBJS)
ifndef STATIC_LIB
	rm -f libboron.so*
endif
	rmdir $(ODIR)

install:
	mkdir -p $(BIN_DIR) $(LIB_DIR) $(MAN_DIR)
ifndef STATIC_LIB
ifeq ($(OS), Darwin)
	install_name_tool -id $(LIB_DIR)/libboron.dylib libboron.dylib
	install_name_tool -change libboron.dylib $(LIB_DIR)/libboron.dylib boron
	install -m 644 libboron.dylib $(LIB_DIR)
else
	install -m 755 -s $(BORON_LIB) $(LIB_DIR)
	ln -s $(BORON_LIB) $(LIB_DIR)/libboron.so.2
endif
endif
	install -s -m 755 boron $(BIN_DIR)
	gzip -c -n doc/boron.troff > doc/boron.1.gz
	install -m 644 doc/boron.1.gz $(MAN_DIR)

uninstall:
	rm -f $(BIN_DIR)/boron $(MAN_DIR)/boron.1
ifndef STATIC_LIB
	rm -f $(LIB_DIR)/$(BORON_LIB)
ifneq ($(OS), Darwin)
	rm -f $(LIB_DIR)/libboron.so.2
endif
endif

install-dev:
	mkdir -p $(INC_DIR) $(LIB_DIR)
	sed -e 's~"urlan.h"~<boron/urlan.h>~' include/boron.h >boron.tmp
	install -m 644 boron.tmp $(INC_DIR)/boron.h
	rm boron.tmp
	install -m 644 include/urlan.h        $(INC_DIR)
	install -m 644 include/urlan_atoms.h  $(INC_DIR)
#	install -m 755 scripts/copr.b $(BIN_DIR)/copr
ifdef STATIC_LIB
	install -m 644 $(BORON_LIB) $(LIB_DIR)
endif
ifneq ($(OS), Darwin)
	mkdir -p $(VIM_DIR)
	install -m 644 doc/boron.vim $(VIM_DIR)
ifndef STATIC_LIB
	ln -s $(BORON_LIB) $(LIB_DIR)/libboron.so
endif
endif

uninstall-dev:
ifdef STATIC_LIB
	rm -f $(LIB_DIR)/$(BORON_LIB)
endif
ifneq ($(OS), Darwin)
ifndef STATIC_LIB
	rm -f $(LIB_DIR)/libboron.so
endif
	rm -f $(VIM_DIR)/boron.vim
endif
#	rm -f $(BIN_DIR)/copr
	rm -f $(INC_DIR)/boron.h $(INC_DIR)/urlan.h $(INC_DIR)/urlan_atoms.h
	rmdir $(INC_DIR)

Executing boron against ur_parseBlockI_overflow.b a second time produces the following output from ASAN, confirming the heap buffer overflow:

Address Sanitizer Output

=================================================================
==104977==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603000000ce8 at pc 0x7ff8ed7c9b02 bp 0x7ffdcef68600 sp 0x7ffdcef685f8
WRITE of size 1 at 0x603000000ce8 thread T0
    #0 0x7ff8ed7c9b01  (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0xa1b01) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #1 0x7ff8ed7c8426 in ur_parseBlockI (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0xa0426) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #2 0x7ff8ed7c8e63 in ur_parseBlockI (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0xa0e63) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #3 0x7ff8ed7cbf88 in boron_compileArgProgram (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0xa3f88) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #4 0x7ff8ed7b1364  (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0x89364) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #5 0x7ff8ed7cdefe  (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0xa5efe) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #6 0x7ff8ed7cfac0 in boron_eval1 (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0xa7ac0) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #7 0x7ff8ed7cfe44 in boron_eval1 (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0xa7e44) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #8 0x7ff8ed7d090c in boron_doBlock (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0xa890c) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #9 0x7ff8ed7a119f in boron_doVoid (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0x7919f) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #10 0x7ff8ed7b052d  (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0x8852d) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #11 0x7ff8ed7b071c  (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0x8871c) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #12 0x7ff8ed7cdefe  (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0xa5efe) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #13 0x7ff8ed7cfac0 in boron_eval1 (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0xa7ac0) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #14 0x7ff8ed7cf2f2  (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0xa72f2) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #15 0x7ff8ed7cfb41 in boron_eval1 (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0xa7b41) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #16 0x7ff8ed7cfe44 in boron_eval1 (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0xa7e44) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #17 0x7ff8ed7d090c in boron_doBlock (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0xa890c) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #18 0x55a6bcb4873f in main eval/main.c:354
    #19 0x7ff8ed56d6c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #20 0x7ff8ed56d784 in __libc_start_main_impl ../csu/libc-start.c:360
    #21 0x55a6bcb474d0 in _start (/dev/shm/boron/boron+0x34d0) (BuildId: bdf03d04eb6f48f8cccbd806f9b1261d304239a6)

0x603000000ce8 is located 0 bytes after 24-byte region [0x603000000cd0,0x603000000ce8)
allocated by thread T0 here:
    #0 0x7ff8ed8d85cf in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x7ff8ed764cdf in ur_binReserve (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0x3ccdf) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #2 0x7ff8ed7cbb5a in boron_compileArgProgram (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0xa3b5a) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #3 0x7ff8ed7b1364  (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0x89364) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #4 0x7ff8ed7cdefe  (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0xa5efe) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #5 0x7ff8ed7cfac0 in boron_eval1 (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0xa7ac0) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #6 0x7ff8ed7cfe44 in boron_eval1 (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0xa7e44) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #7 0x7ff8ed7d090c in boron_doBlock (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0xa890c) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #8 0x7ff8ed7a119f in boron_doVoid (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0x7919f) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #9 0x7ff8ed7b052d  (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0x8852d) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #10 0x7ff8ed7b071c  (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0x8871c) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #11 0x7ff8ed7cdefe  (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0xa5efe) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #12 0x7ff8ed7cfac0 in boron_eval1 (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0xa7ac0) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #13 0x7ff8ed7cf2f2  (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0xa72f2) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #14 0x7ff8ed7cfb41 in boron_eval1 (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0xa7b41) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #15 0x7ff8ed7cfe44 in boron_eval1 (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0xa7e44) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #16 0x7ff8ed7d090c in boron_doBlock (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0xa890c) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #17 0x55a6bcb4873f in main eval/main.c:354
    #18 0x7ff8ed56d6c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58

SUMMARY: AddressSanitizer: heap-buffer-overflow (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0xa1b01) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a) 
Shadow bytes around the buggy address:
  0x603000000a00: 00 00 06 fa fa fa 00 00 04 fa fa fa 00 00 03 fa
  0x603000000a80: fa fa 00 00 01 fa fa fa 00 00 02 fa fa fa 00 00
  0x603000000b00: 00 03 fa fa 00 00 00 06 fa fa 00 00 00 fa fa fa
  0x603000000b80: 00 00 00 03 fa fa 00 00 00 fa fa fa 00 00 00 fa
  0x603000000c00: fa fa 00 00 00 fa fa fa 00 00 00 fa fa fa 00 00
=>0x603000000c80: 00 fa fa fa 00 00 00 fa fa fa 00 00 00[fa]fa fa
  0x603000000d00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x603000000d80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x603000000e00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x603000000e80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x603000000f00: 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
==104977==ABORTING

Heap buffer overflow in ur_strInitUtf8 at string.c

void ur_strInitUtf8( UBuffer* buf, const uint8_t* it, const uint8_t* end )

Next, I executed boron against the file that produced the crash in ur_strInitUtf8:

./boron ur_strInitUtf8_overflow.b 
corrupted size vs. prev_size
zsh: IOT instruction  ./boron ur_strInitUtf8_overflow.b

The output made be believe that there was a heap overflow corrupting the heap chunk size/prev_size, so I compiled the project with address sanitizer and debug symbols to verify:

# Boron Makefile for UNIX systems.

VER=2.0.8

DESTDIR ?= /usr/local
BIN_DIR=$(DESTDIR)/bin
LIB_DIR=$(DESTDIR)/lib
INC_DIR=$(DESTDIR)/include/boron
MAN_DIR=$(DESTDIR)/share/man/man1
VIM_DIR=$(DESTDIR)/share/vim/vimfiles/syntax

OS := $(shell uname)

CFLAGS = -pipe -pedantic -Wall -W -Iinclude -Iurlan -Ieval -Isupport -g -fsanitize=address -DDEBUG
#CFLAGS += -O3 -DNDEBUG
#CFLAGS += -g -DDEBUG

ifeq ($(OS), Darwin)
CFLAGS += -std=c99
AR_LIB = libtool -static -o
else
CFLAGS += -std=gnu99 -fPIC
AR_LIB = ar rc
ifneq (,$(wildcard /usr/lib64/libc.so))
LIB_DIR=$(DESTDIR)/lib64
else ifneq (,$(wildcard /usr/lib/x86_64-linux-gnu/.))
LIB_DIR=$(DESTDIR)/lib/x86_64-linux-gnu
endif
endif

CONFIG := $(shell cat config.opt)
ifneq (,$(findstring _STATIC,$(CONFIG)))
	STATIC_LIB = true
endif

LIBS := -lm

ODIR = .obj
OBJ_FN = env.o array.o binary.o block.o coord.o date.o path.o \
	string.o context.o gc.o serialize.o tokenize.o \
	vector.o parse_block.o parse_string.o
OBJ_FN += str.o mem_util.o quickSortIndex.o fpconv.o
OBJ_FN += os.o boron.o port_file.o wait.o
ifneq (,$(findstring _HASHMAP,$(CONFIG)))
OBJ_FN += hashmap.o
endif
ifneq (,$(findstring _RANDOM,$(CONFIG)))
OBJ_FN += well512.o random.o
endif
ifneq (,$(findstring _SOCKET,$(CONFIG)))
OBJ_FN += port_socket.o
endif
ifneq (,$(findstring _THREAD,$(CONFIG)))
OBJ_FN += port_thread.o
ifeq ($(OS), Linux)
LIBS += -lpthread
endif
endif
LIB_OBJS = $(addprefix $(ODIR)/,$(OBJ_FN))


MAIN_FN = main.o 
ifneq (,$(findstring _LINENOISE,$(CONFIG)))
MAIN_FN += linenoise.o
else
EXE_LIBS += -lreadline -lhistory
endif
ifneq (,$(findstring _COMPRESS=1,$(CONFIG)))
LIBS += -lz
endif
ifneq (,$(findstring _COMPRESS=2,$(CONFIG)))
LIBS += -lbz2
endif
EXE_OBJS = $(addprefix $(ODIR)/,$(MAIN_FN))

ifdef STATIC_LIB
BORON_LIB = libboron.a
EXE_LIBS += $(LIBS)
else ifeq ($(OS), Darwin)
BORON_LIB = libboron.dylib
else
BORON_LIB = libboron.so.$(VER)
endif


$(ODIR)/%.o: urlan/%.c
	cc -c $(CFLAGS) $(CONFIG) $< -o $@
$(ODIR)/%.o: support/%.c
	cc -c $(CFLAGS) $(CONFIG) $< -o $@
$(ODIR)/%.o: eval/%.c
	cc -c $(CFLAGS) $(CONFIG) $< -o $@

boron: $(EXE_OBJS) $(BORON_LIB)
	cc $^ -o $@ $(EXE_LIBS) -g -fsanitize=address

$(ODIR)/os.o: unix/os.c
	cc -c $(CFLAGS) $(CONFIG) $< -o $@

$(EXE_OBJS): | $(ODIR)
$(LIB_OBJS): | $(ODIR)
$(ODIR):
	mkdir -p $@

$(BORON_LIB): $(LIB_OBJS)
ifdef STATIC_LIB
	$(AR_LIB) $@ $^
	ranlib $@
else ifeq ($(OS), Darwin)
	libtool -dynamiclib -o $@ $^ -install_name @rpath/$(BORON_LIB) $(LIBS)
else
	cc -o $@  -shared -g -fsanitize=address -Wl,-soname,libboron.so.2 $^ $(LIBS)
	ln -sf $(BORON_LIB) libboron.so.2
	ln -sf $(BORON_LIB) libboron.so
endif

.PHONY: clean install uninstall install-dev uninstall-dev

clean:
	rm -f boron $(BORON_LIB) $(LIB_OBJS) $(EXE_OBJS)
ifndef STATIC_LIB
	rm -f libboron.so*
endif
	rmdir $(ODIR)

install:
	mkdir -p $(BIN_DIR) $(LIB_DIR) $(MAN_DIR)
ifndef STATIC_LIB
ifeq ($(OS), Darwin)
	install_name_tool -id $(LIB_DIR)/libboron.dylib libboron.dylib
	install_name_tool -change libboron.dylib $(LIB_DIR)/libboron.dylib boron
	install -m 644 libboron.dylib $(LIB_DIR)
else
	install -m 755 -s $(BORON_LIB) $(LIB_DIR)
	ln -s $(BORON_LIB) $(LIB_DIR)/libboron.so.2
endif
endif
	install -s -m 755 boron $(BIN_DIR)
	gzip -c -n doc/boron.troff > doc/boron.1.gz
	install -m 644 doc/boron.1.gz $(MAN_DIR)

uninstall:
	rm -f $(BIN_DIR)/boron $(MAN_DIR)/boron.1
ifndef STATIC_LIB
	rm -f $(LIB_DIR)/$(BORON_LIB)
ifneq ($(OS), Darwin)
	rm -f $(LIB_DIR)/libboron.so.2
endif
endif

install-dev:
	mkdir -p $(INC_DIR) $(LIB_DIR)
	sed -e 's~"urlan.h"~<boron/urlan.h>~' include/boron.h >boron.tmp
	install -m 644 boron.tmp $(INC_DIR)/boron.h
	rm boron.tmp
	install -m 644 include/urlan.h        $(INC_DIR)
	install -m 644 include/urlan_atoms.h  $(INC_DIR)
#	install -m 755 scripts/copr.b $(BIN_DIR)/copr
ifdef STATIC_LIB
	install -m 644 $(BORON_LIB) $(LIB_DIR)
endif
ifneq ($(OS), Darwin)
	mkdir -p $(VIM_DIR)
	install -m 644 doc/boron.vim $(VIM_DIR)
ifndef STATIC_LIB
	ln -s $(BORON_LIB) $(LIB_DIR)/libboron.so
endif
endif

uninstall-dev:
ifdef STATIC_LIB
	rm -f $(LIB_DIR)/$(BORON_LIB)
endif
ifneq ($(OS), Darwin)
ifndef STATIC_LIB
	rm -f $(LIB_DIR)/libboron.so
endif
	rm -f $(VIM_DIR)/boron.vim
endif
#	rm -f $(BIN_DIR)/copr
	rm -f $(INC_DIR)/boron.h $(INC_DIR)/urlan.h $(INC_DIR)/urlan_atoms.h
	rmdir $(INC_DIR)

Executing boron against ur_strInitUtf8_overflow.b a second time will produce the output from ASAN confirming the heap buffer overflow:

└─$ ./boron overflows/ur_strInitUtf8_overflow.b 
=================================================================
==122297==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x61a000001708 at pc 0x7f6b69141450 bp 0x7ffc47b562d0 sp 0x7ffc47b562c8
WRITE of size 1 at 0x61a000001708 thread T0
    #0 0x7f6b6914144f in ur_strInitUtf8 (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0x4644f) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #1 0x7f6b6914185c in ur_makeStringUtf8 (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0x4685c) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #2 0x7f6b69159959 in ur_tokenizeB (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0x5e959) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #3 0x7f6b6915a3ac in ur_tokenize (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0x5f3ac) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #4 0x7f6b69193e78  (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0x98e78) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #5 0x7f6b691a774b in boron_load (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0xac74b) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #6 0x55e53db95707 in main eval/main.c:351
    #7 0x7f6b688456c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #8 0x7f6b68845784 in __libc_start_main_impl ../csu/libc-start.c:360
    #9 0x55e53db944d0 in _start (/dev/shm/boron/boron+0x34d0) (BuildId: bdf03d04eb6f48f8cccbd806f9b1261d304239a6)

0x61a000001708 is located 0 bytes after 1160-byte region [0x61a000001280,0x61a000001708)
allocated by thread T0 here:
    #0 0x7f6b68ad85cf in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x7f6b69136c11 in ur_arrInit (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0x3bc11) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #2 0x7f6b69141908 in ur_strInit (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0x46908) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #3 0x7f6b691412bd in ur_strInitUtf8 (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0x462bd) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #4 0x7f6b6914185c in ur_makeStringUtf8 (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0x4685c) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #5 0x7f6b69159959 in ur_tokenizeB (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0x5e959) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #6 0x7f6b6915a3ac in ur_tokenize (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0x5f3ac) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #7 0x7f6b69193e78  (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0x98e78) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #8 0x7f6b691a774b in boron_load (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0xac74b) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a)
    #9 0x55e53db95707 in main eval/main.c:351
    #10 0x7f6b688456c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58

SUMMARY: AddressSanitizer: heap-buffer-overflow (/usr/local/lib/x86_64-linux-gnu/libboron.so.2+0x4644f) (BuildId: 8604ed3373a7d0fad1d0ab72cbd67e9bc93ce54a) in ur_strInitUtf8
Shadow bytes around the buggy address:
  0x61a000001480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x61a000001500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x61a000001580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x61a000001600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x61a000001680: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x61a000001700: 00[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x61a000001780: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x61a000001800: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x61a000001880: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x61a000001900: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x61a000001980: 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
==122297==ABORTING

Mitigation

For both of these heap overflows a check on the size of the data being copied over to the heap should do the trick.

Thanks!
Halcy0nic

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.