[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#740127: libc6-dev: reusing compiled regex causes segfault on regexec



Package: libc6-dev
Version: 2.17-97
Severity: important



-- System Information:
Debian Release: jessie/sid
  APT prefers testing
  APT policy: (500, 'testing')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 3.12-1-amd64 (SMP w/8 CPU cores)
Locale: LANG=en_US.utf8, LC_CTYPE=en_US.utf8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages libc6-dev depends on:
ii  libc-dev-bin    2.17-97
ii  libc6           2.17-97
ii  linux-libc-dev  3.12.9-1

Versions of packages libc6-dev recommends:
ii  gcc [c-compiler]      4:4.8.2-2
ii  gcc-4.4 [c-compiler]  4.4.7-7
ii  gcc-4.6 [c-compiler]  4.6.4-5
ii  gcc-4.7 [c-compiler]  4.7.3-10
ii  gcc-4.8 [c-compiler]  4.8.2-16

Versions of packages libc6-dev suggests:
pn  glibc-doc     <none>
ii  manpages-dev  3.58-1

-- no debconf information

compiling the and executeing the followning causes a segfault.
compiled with "gcc-4.8 -Wall -g -std=c99 -o test main.c"
escaping the '.' with '\\.' (in regex) reduces the problem but it still exists in form of a crash on the last "non existent match"
reusing the compiled regex crashes with regexec causes the crash.
regfree and recompile evrytime works but is slow and should not be needed.

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <regex.h>
#include <sys/types.h>
#include <inttypes.h>

#define MAXIPS 512

const char* const line = "132.32.1.34:6643 132.32.1.34:6643 255.255.255.255:6643 fffff";

typedef struct {
    union {
        int32_t ipaddr;
        uint8_t ip[4];
    };
    uint16_t port;
} ip4nport_t;

void print_regerror (int errcode, regex_t *compiled) {
    size_t length = regerror (errcode, compiled, (char*)NULL, 0);
    char *buffer = (char*)malloc(length);
    (void) regerror(errcode, compiled, buffer, length);
    fprintf(stderr,"%s",buffer);
    free(buffer);
}

int main() {
    regmatch_t match[32];
    ip4nport_t proxys[MAXIPS];
    int proxyindex=0;
    regex_t regexip;
    int error=0;

    memset(match,0,sizeof(regmatch_t)*32);


    if ((error=regcomp(&regexip,"((2[0-5][0-5])|(1{0,1}[0-9]{1,2})).((2[0-5][0-5])|(1{0,1}[0-9]{1,2})).((2[0-5][0-5])|(1{0,1}[0-9]{1,2})).((2[0-5][0-5])|(1{0,1}[0-9]{1,2})):((6[0-5][0-5][0-3][0-5])|([12345]{0,1}[0-9]{1,4}))",REG_EXTENDED))) {
	    print_regerror(error,&regexip);
        return 1;
    }

    printf("subs: %"PRIu64"\n",regexip.re_nsub);
    const char* ptr = line;
    for (int ok=1; ok;) {
        ok = 0;
        printf("in:%s\n",ptr);
        error=regexec(&regexip,ptr,1,match,REG_NOTBOL|REG_NOTEOL);
        printf("err:%d\n",error);
        //regfree(&regexip);
        if (!(error)) {
            ok=1;
            if (MAXIPS<=proxyindex) {printf("max proxys\n"); continue;}
            char tmp[12];
            memset(tmp,0,12);
            memcpy(tmp, ptr + match[0].rm_so, match[0].rm_eo - match[0].rm_so);
            sscanf(tmp,"%"SCNu8".%"SCNu8".%"SCNu8".%"SCNu8":%"SCNu16,&(proxys[proxyindex].ip[0]),&(proxys[proxyindex].ip[1]),&(proxys[proxyindex].ip[2]),&(proxys[proxyindex].ip[3]),&(proxys[proxyindex].port));
            printf("%"PRIu8".%"PRIu8".%"PRIu8".%"PRIu8":%"PRIu16"\n",proxys[proxyindex].ip[0],proxys[proxyindex].ip[1],proxys[proxyindex].ip[2],proxys[proxyindex].ip[3],proxys[proxyindex].port);
            ptr += match[0].rm_eo;
            ++proxyindex;
            /*if ((error=regcomp(&regexip,"((2[0-5][0-5])|(1{0,1}[0-9]{1,2})).((2[0-5][0-5])|(1{0,1}[0-9]{1,2})).((2[0-5][0-5])|(1{0,1}[0-9]{1,2})).((2[0-5][0-5])|(1{0,1}[0-9]{1,2})):((6[0-5][0-5][0-3][0-5])|([12345]{0,1}[0-9]{1,4}))",REG_EXTENDED))) {
                print_regerror(error,&regexip);
            }*/
        } else {
            printf("no match\n");
        }
    }

    return 0;
}


 


Reply to: