libqrencode icon indicating copy to clipboard operation
libqrencode copied to clipboard

out of read in split.c&qrinput.c

Open Taolaw opened this issue 4 years ago • 0 comments

The vulnerability exists in the split.c file. The loop executed at line 260 determines the end of the string. When the incoming string does not end with \0 by default. The memcpy in the QRinput_List_newEntry function of qrinput.c is called later, one byte (from the heap block) will be copied, causing crash or information leakage.

==14521==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6020000000c0 at pc 0x0000004bcbc4 bp 0x7ffcf5cf7d50 sp 0x7ffcf5cf7510
READ of size 2 at 0x6020000000c0 thread T0
    #0 0x4bcbc3 in memcpy (/home/luna/libqrencode/libqrencode/fuzz+0x4bcbc3)
    #1 0x55989c in QRinput_List_newEntry (/home/luna/libqrencode/libqrencode/fuzz+0x55989c)
    #2 0x5596b4 in QRinput_append (/home/luna/libqrencode/libqrencode/fuzz+0x5596b4)
    #3 0x55e844 in Split_eat8 (/home/luna/libqrencode/libqrencode/fuzz+0x55e844)
    #4 0x55df61 in Split_splitString (/home/luna/libqrencode/libqrencode/fuzz+0x55df61)
    #5 0x55ddc9 in Split_splitStringToQRinput (/home/luna/libqrencode/libqrencode/fuzz+0x55ddc9)
    #6 0x557eb3 in QRcode_encodeStringReal (/home/luna/libqrencode/libqrencode/fuzz+0x557eb3)
    #7 0x557de3 in QRcode_encodeString (/home/luna/libqrencode/libqrencode/fuzz+0x557de3)
    #8 0x55321c in encode(unsigned char const*, int) /home/luna/libqrencode/libqrencode/fuzz.cc:1027:10
    #9 0x552a6f in qrencode(unsigned char const*, int, char const*) /home/luna/libqrencode/libqrencode/fuzz.cc:1037:11
    #10 0x4728f2 in main (/home/luna/libqrencode/libqrencode/fuzz+0x4728f2)
    #11 0x7f36d1f790b2 in __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/../csu/libc-start.c:308:16
    #12 0x41f4cd in _start (/home/luna/libqrencode/libqrencode/fuzz+0x41f4cd)

This vulnerability can be triggered by using lib in the following scenarios. It is possible that the use of a limited-length string does not end with\0

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <malloc.h>
#include <time.h>
#include <stdlib.h>
#include <stdint.h>
#include <stddef.h>
#include "libqrencode/qrencode.h" 


int version = 40;
int casesensitive = 1;
int eightbit = 0;
QRecLevel level = QR_ECLEVEL_L;
QRencodeMode hint = QR_MODE_8;

static QRcode *encode(const unsigned char *intext, int length)
{
	QRcode *code;

	if(eightbit) {
		code = QRcode_encodeData(length, intext, version, level);
	} else {
		code = QRcode_encodeString((char *)intext, version, level, hint, casesensitive);
	}

	return code;
}

int main(void){
 
    QRcode* qrcode;
    int fd = open("inputfile",O_RDONLY);
    
    if(fd == -1){
        printf("can not open the file\n");
        return 1;
    }
    
    char url[16] = {"\0"};
    int len = read(fd,url,16);
    
    qrcode = encode( (const unsigned char *)url, len );
    free(qrcode);
    close(fd);
    
    return 0;
}

This is an extreme case, but the design of libary should allow more boundary cases

Taolaw avatar Mar 14 '21 05:03 Taolaw