--- extensions/printpkt.c +++ extensions/printpkt.c 2007/01/08 18:20:04 @@ -95,13 +95,17 @@ static struct intr_id intr_ids[INTR_IDS] #define GET_VALUE(x) ulogd_keyh[intr_ids[x].id].interp->result[ulogd_keyh[intr_ids[x].id].offset].value #define GET_FLAGS(x) ulogd_keyh[intr_ids[x].id].interp->result[ulogd_keyh[intr_ids[x].id].offset].flags -int printpkt_print(ulog_iret_t *res, char *buf, int prefix) +int printpkt_print(ulog_iret_t *res, char *buf, size_t buf_siz, int prefix) { char *timestr; char *tmp; time_t now; - char *buf_cur = buf; + if( buf_siz) *buf = '\0'; + size_t buf_len = 0; + +#define BUF_ADD(ptr, siz, off, fmt...) \ + snprintf(((ptr)+(off)), ((siz) > (off) ? (siz)-(off) : 0), ##fmt) if (prefix) { now = (time_t) GET_VALUE(0).ui32; @@ -116,127 +120,191 @@ int printpkt_print(ulog_iret_t *res, cha *tmp = '\0'; /* print time and hostname */ - buf_cur += sprintf(buf_cur, "%.15s %s", timestr, hostname); + buf_len = strlen(buf); + BUF_ADD(buf,buf_siz,buf_len, "%.15s %s", timestr, hostname); } if (*(char *) GET_VALUE(1).ptr) - buf_cur += sprintf(buf_cur, " %s", (char *) GET_VALUE(1).ptr); + { + buf_len = strlen(buf); + BUF_ADD(buf,buf_siz,buf_len, " %s", (char *) GET_VALUE(1).ptr); + } - buf_cur += sprintf(buf_cur," IN=%s OUT=%s ", - (char *) GET_VALUE(2).ptr, - (char *) GET_VALUE(3).ptr); + buf_len = strlen(buf); + BUF_ADD(buf,buf_siz,buf_len," IN=%s OUT=%s ", + (char *) GET_VALUE(2).ptr, + (char *) GET_VALUE(3).ptr); /* FIXME: configurable */ - buf_cur += sprintf(buf_cur, "MAC=%s ", - (GET_FLAGS(4) & ULOGD_RETF_VALID) ? (char *) GET_VALUE(4).ptr : ""); - - buf_cur += sprintf(buf_cur, "SRC=%s ", - inet_ntoa((struct in_addr) {htonl(GET_VALUE(5).ui32)})); - buf_cur += sprintf(buf_cur, "DST=%s ", - inet_ntoa((struct in_addr) {htonl(GET_VALUE(6).ui32)})); - - buf_cur += sprintf(buf_cur,"LEN=%u TOS=%02X PREC=0x%02X TTL=%u ID=%u ", - GET_VALUE(7).ui16, GET_VALUE(8).ui8 & IPTOS_TOS_MASK, - GET_VALUE(8).ui8 & IPTOS_PREC_MASK, GET_VALUE(9).ui8, - GET_VALUE(10).ui16); + buf_len = strlen(buf); + BUF_ADD(buf,buf_siz,buf_len, "MAC=%s ", + (GET_FLAGS(4) & ULOGD_RETF_VALID) ? (char *) GET_VALUE(4).ptr : ""); + + buf_len = strlen(buf); + BUF_ADD(buf,buf_siz,buf_len, "SRC=%s ", + inet_ntoa((struct in_addr) {htonl(GET_VALUE(5).ui32)})); + + buf_len = strlen(buf); + BUF_ADD(buf,buf_siz,buf_len, "DST=%s ", + inet_ntoa((struct in_addr) {htonl(GET_VALUE(6).ui32)})); + + buf_len = strlen(buf); + BUF_ADD(buf,buf_siz,buf_len, + "LEN=%u TOS=%02X PREC=0x%02X TTL=%u ID=%u ", + GET_VALUE(7).ui16, GET_VALUE(8).ui8 & IPTOS_TOS_MASK, + GET_VALUE(8).ui8 & IPTOS_PREC_MASK, GET_VALUE(9).ui8, + GET_VALUE(10).ui16); if (GET_VALUE(10).ui16 & IP_RF) - buf_cur += sprintf(buf_cur, "CE "); + { + buf_len = strlen(buf); + BUF_ADD(buf,buf_siz,buf_len, "CE "); + } if (GET_VALUE(11).ui16 & IP_DF) - buf_cur += sprintf(buf_cur, "DF "); + { + buf_len = strlen(buf); + BUF_ADD(buf,buf_siz,buf_len, "DF "); + } if (GET_VALUE(11).ui16 & IP_MF) - buf_cur += sprintf(buf_cur, "MF "); + { + buf_len = strlen(buf); + BUF_ADD(buf,buf_siz,buf_len, "MF "); + } if (GET_VALUE(11).ui16 & IP_OFFMASK) - buf_cur += sprintf(buf_cur, "FRAG:%u ", + { + buf_len = strlen(buf); + BUF_ADD(buf,buf_siz,buf_len, "FRAG:%u ", GET_VALUE(11).ui16 & IP_OFFMASK); + } switch (GET_VALUE(12).ui8) { case IPPROTO_TCP: - buf_cur += sprintf(buf_cur, "PROTO=TCP "); - buf_cur += sprintf(buf_cur, "SPT=%u DPT=%u ", - GET_VALUE(13).ui16, GET_VALUE(14).ui16); + buf_len = strlen(buf); + BUF_ADD(buf,buf_siz,buf_len, "PROTO=TCP "); + buf_len = strlen(buf); + BUF_ADD(buf,buf_siz,buf_len, "SPT=%u DPT=%u ", + GET_VALUE(13).ui16, GET_VALUE(14).ui16); /* FIXME: config */ - buf_cur += sprintf(buf_cur, "SEQ=%u ACK=%u ", - GET_VALUE(15).ui32, GET_VALUE(16).ui32); - - buf_cur += sprintf(buf_cur, "WINDOW=%u ", GET_VALUE(17).ui16); + buf_len = strlen(buf); + BUF_ADD(buf,buf_siz,buf_len, "SEQ=%u ACK=%u ", + GET_VALUE(15).ui32, GET_VALUE(16).ui32); + + buf_len = strlen(buf); + BUF_ADD(buf,buf_siz,buf_len, + "WINDOW=%u ", GET_VALUE(17).ui16); -// buf_cur += sprintf(buf_cur, "RES=0x%02x ", +// buf_len = strlen(buf); +// BUF_ADD(buf,buf_siz,buf_len, "RES=0x%02x ", if (GET_VALUE(18).b) - buf_cur += sprintf(buf_cur, "URG "); + { + buf_len = strlen(buf); + BUF_ADD(buf,buf_siz,buf_len, "URG "); + } if (GET_VALUE(19).b) - buf_cur += sprintf(buf_cur, "ACK "); + { + buf_len = strlen(buf); + BUF_ADD(buf,buf_siz,buf_len, "ACK "); + } if (GET_VALUE(20).b) - buf_cur += sprintf(buf_cur, "PSH "); + { + buf_len = strlen(buf); + BUF_ADD(buf,buf_siz,buf_len, "PSH "); + } if (GET_VALUE(21).b) - buf_cur += sprintf(buf_cur, "RST "); + { + buf_len = strlen(buf); + BUF_ADD(buf,buf_siz,buf_len, "RST "); + } if (GET_VALUE(22).b) - buf_cur += sprintf(buf_cur, "SYN "); + { + buf_len = strlen(buf); + BUF_ADD(buf,buf_siz,buf_len, "SYN "); + } if (GET_VALUE(23).b) - buf_cur += sprintf(buf_cur, "FIN "); + { + buf_len = strlen(buf); + BUF_ADD(buf,buf_siz,buf_len, "FIN "); + } - buf_cur += sprintf(buf_cur, "URGP=%u ", GET_VALUE(24).ui16); + buf_len = strlen(buf); + BUF_ADD(buf,buf_siz,buf_len, "URGP=%u ", GET_VALUE(24).ui16); break; case IPPROTO_UDP: - buf_cur += sprintf(buf_cur, "PROTO=UDP "); + buf_len = strlen(buf); + BUF_ADD(buf,buf_siz,buf_len, "PROTO=UDP "); - buf_cur += sprintf(buf_cur, "SPT=%u DPT=%u LEN=%u ", + buf_len = strlen(buf); + BUF_ADD(buf,buf_siz,buf_len, "SPT=%u DPT=%u LEN=%u ", GET_VALUE(25).ui16, GET_VALUE(26).ui16, GET_VALUE(27).ui16); break; case IPPROTO_ICMP: - buf_cur += sprintf(buf_cur, "PROTO=ICMP "); + buf_len = strlen(buf); + BUF_ADD(buf,buf_siz,buf_len, "PROTO=ICMP "); - buf_cur += sprintf(buf_cur, "TYPE=%u CODE=%u ", + buf_len = strlen(buf); + BUF_ADD(buf,buf_siz,buf_len, "TYPE=%u CODE=%u ", GET_VALUE(28).ui8, GET_VALUE(29).ui8); switch (GET_VALUE(28).ui8) { case ICMP_ECHO: case ICMP_ECHOREPLY: - buf_cur += sprintf(buf_cur, "ID=%u SEQ=%u ", + buf_len = strlen(buf); + BUF_ADD(buf,buf_siz,buf_len, "ID=%u SEQ=%u ", GET_VALUE(30).ui16, GET_VALUE(31).ui16); break; case ICMP_PARAMETERPROB: - buf_cur += sprintf(buf_cur, "PARAMETER=%u ", + buf_len = strlen(buf); + BUF_ADD(buf,buf_siz,buf_len, "PARAMETER=%u ", GET_VALUE(32).ui32 >> 24); break; case ICMP_REDIRECT: - buf_cur += sprintf(buf_cur, "GATEWAY=%s ", inet_ntoa((struct in_addr) {htonl(GET_VALUE(32).ui32)})); + buf_len = strlen(buf); + BUF_ADD(buf,buf_siz,buf_len, "GATEWAY=%s ", inet_ntoa((struct in_addr) {htonl(GET_VALUE(32).ui32)})); break; case ICMP_DEST_UNREACH: if (GET_VALUE(29).ui8 == ICMP_FRAG_NEEDED) - buf_cur += sprintf(buf_cur, "MTU=%u ", + { + buf_len = strlen(buf); + BUF_ADD(buf,buf_siz,buf_len, "MTU=%u ", GET_VALUE(33).ui16); + } break; } break; case IPPROTO_ESP: case IPPROTO_AH: - buf_cur += sprintf(buf_cur, "PROTO=%s ", GET_VALUE(12).ui8 == IPPROTO_ESP ? "ESP" : "AH"); + buf_len = strlen(buf); + BUF_ADD(buf,buf_siz,buf_len, "PROTO=%s ", GET_VALUE(12).ui8 == IPPROTO_ESP ? "ESP" : "AH"); /* FIXME: "INCOMPLETE [%u bytes]" in case of short pkt */ if (intr_ids[34].id > 0) { - buf_cur += sprintf(buf_cur, "SPI=0x%x ", GET_VALUE(34).ui32); + buf_len = strlen(buf); + BUF_ADD(buf,buf_siz,buf_len, "SPI=0x%x ", GET_VALUE(34).ui32); } break; default: - buf_cur += sprintf(buf_cur, "PROTO=%u ", GET_VALUE(11).ui8); + buf_len = strlen(buf); + BUF_ADD(buf,buf_siz,buf_len, "PROTO=%u ", GET_VALUE(11).ui8); } - strcat(buf_cur, "\n"); + buf_len = strlen(buf); + BUF_ADD(buf,buf_siz,buf_len, "\n"); + +#undef BUF_ADD return 0; } --- extensions/printpkt.h +++ extensions/printpkt.h 2007/01/08 18:20:04 @@ -1,7 +1,7 @@ #ifndef _PRINTPKT_H #define _PRINTPKT_H -int printpkt_print(ulog_iret_t *res, char *buf, int prefix); +int printpkt_print(ulog_iret_t *res, char *buf, size_t buf_siz, int prefix); int printpkt_init(void); #endif --- extensions/ulogd_BASE.c +++ extensions/ulogd_BASE.c 2007/01/08 18:20:04 @@ -65,9 +65,11 @@ static ulog_iret_t *_interp_raw(ulog_int int i; char *buf, *oldbuf = NULL; ulog_iret_t *ret = ip->result; + size_t siz; if (pkt->mac_len) { - buf = (char *) malloc(3 * pkt->mac_len + 1); + siz = 3 * pkt->mac_len + 1; + buf = (char *) malloc(siz); if (!buf) { ulogd_log(ULOGD_ERROR, "OOM!!!\n"); return NULL; @@ -77,7 +79,7 @@ static ulog_iret_t *_interp_raw(ulog_int p = pkt->mac; oldbuf = buf; for (i = 0; i < pkt->mac_len; i++, p++) - sprintf(buf, "%s%02x%c", oldbuf, *p, i==pkt->mac_len-1 ? ' ':':'); + snprintf(buf, siz, "%s%02x%c", oldbuf, *p, i==pkt->mac_len-1 ? ' ':':'); ret[0].value.ptr = buf; ret[0].flags |= ULOGD_RETF_VALID; } --- extensions/ulogd_LOGEMU.c +++ extensions/ulogd_LOGEMU.c 2007/01/08 18:20:04 @@ -67,7 +67,7 @@ static int _output_logemu(ulog_iret_t *r { static char buf[4096]; - printpkt_print(res, buf, 1); + printpkt_print(res, buf, sizeof(buf), 1); fprintf(of, "%s", buf); --- extensions/ulogd_PWSNIFF.c +++ extensions/ulogd_PWSNIFF.c 2007/01/08 18:20:04 @@ -116,7 +116,7 @@ static ulog_iret_t *_interp_pwsniff(ulog return NULL; } strncpy(ret[0].value.ptr, (const char *)begp, len); - *((char *)ret[0].value.ptr + len + 1) = '\0'; + *((char *)ret[0].value.ptr + len) = '\0'; } if (pw_len) { ret[1].value.ptr = (char *) malloc(pw_len+1); @@ -126,7 +126,7 @@ static ulog_iret_t *_interp_pwsniff(ulog return NULL; } strncpy(ret[1].value.ptr, (const char *)pw_begp, pw_len); - *((char *)ret[1].value.ptr + pw_len + 1) = '\0'; + *((char *)ret[1].value.ptr + pw_len) = '\0'; } return ret; --- extensions/ulogd_SYSLOG.c +++ extensions/ulogd_SYSLOG.c 2007/01/08 18:20:04 @@ -61,7 +61,7 @@ static int _output_syslog(ulog_iret_t *r { static char buf[4096]; - printpkt_print(res, buf, 0); + printpkt_print(res, buf, sizeof(buf), 0); syslog(syslog_level|syslog_facility, buf); return 0; --- mysql/ulogd_MYSQL.c +++ mysql/ulogd_MYSQL.c 2007/01/08 18:20:04 @@ -39,6 +39,7 @@ #include #include #include +#include #ifdef DEBUG_MYSQL #define DEBUGP(x, args...) fprintf(stderr, x, ## args) @@ -61,6 +62,9 @@ static struct _field *fields; /* buffer for our insert statement */ static char *stmt; +/* size of our insert statement buffer */ +static size_t stmt_siz; + /* pointer to the beginning of the "VALUES" part */ static char *stmt_val; @@ -130,71 +134,85 @@ static int mysql_output(ulog_iret_t *res if (!res || !IS_VALID((*res))) { /* no result, we have to fake something */ - sprintf(stmt_ins, "NULL,"); + snprintf(stmt_ins, stmt_siz-(stmt_ins-stmt), "NULL,"); stmt_ins = stmt + strlen(stmt); continue; } switch (res->type) { case ULOGD_RET_INT8: - sprintf(stmt_ins, "%d,", res->value.i8); + snprintf(stmt_ins, stmt_siz-(stmt_ins-stmt), "%d,", res->value.i8); break; case ULOGD_RET_INT16: - sprintf(stmt_ins, "%d,", res->value.i16); + snprintf(stmt_ins, stmt_siz-(stmt_ins-stmt), "%d,", res->value.i16); break; case ULOGD_RET_INT32: - sprintf(stmt_ins, "%d,", res->value.i32); + snprintf(stmt_ins, stmt_siz-(stmt_ins-stmt), "%d,", res->value.i32); break; case ULOGD_RET_INT64: - sprintf(stmt_ins, "%lld,", res->value.i64); + snprintf(stmt_ins, stmt_siz-(stmt_ins-stmt), "%"PRId64",", res->value.i64); break; case ULOGD_RET_UINT8: - sprintf(stmt_ins, "%u,", res->value.ui8); + snprintf(stmt_ins, stmt_siz-(stmt_ins-stmt), "%u,", res->value.ui8); break; case ULOGD_RET_UINT16: - sprintf(stmt_ins, "%u,", res->value.ui16); + snprintf(stmt_ins, stmt_siz-(stmt_ins-stmt), "%u,", res->value.ui16); break; case ULOGD_RET_IPADDR: #ifdef IP_AS_STRING memset(&addr, 0, sizeof(addr)); addr.s_addr = ntohl(res->value.ui32); - *stmt_ins++ = '\''; tmpstr = inet_ntoa(addr); + if(stmt_siz > (stmt_ins-stmt)+(strlen(tmpstr)*2)+4) + { + *stmt_ins++ = '\''; #ifdef OLD_MYSQL - mysql_escape_string(stmt_ins, tmpstr, - strlen(tmpstr)); + mysql_escape_string(stmt_ins, tmpstr, + strlen(tmpstr)); #else - mysql_real_escape_string(dbh, stmt_ins, - tmpstr, - strlen(tmpstr)); + mysql_real_escape_string(dbh, stmt_ins, + tmpstr, + strlen(tmpstr)); #endif /* OLD_MYSQL */ - stmt_ins = stmt + strlen(stmt); - sprintf(stmt_ins, "',"); + stmt_ins = stmt + strlen(stmt); + snprintf(stmt_ins, stmt_siz-(stmt_ins-stmt), "',"); + } + else + { + snprintf(stmt_ins, stmt_siz-(stmt_ins-stmt), "'',"); + } break; #endif /* IP_AS_STRING */ /* EVIL: fallthrough when logging IP as * u_int32_t */ case ULOGD_RET_UINT32: - sprintf(stmt_ins, "%u,", res->value.ui32); + snprintf(stmt_ins, stmt_siz-(stmt_ins-stmt), "%u,", res->value.ui32); break; case ULOGD_RET_UINT64: - sprintf(stmt_ins, "%llu,", res->value.ui64); + snprintf(stmt_ins, stmt_siz-(stmt_ins-stmt), "%"PRIu64",", res->value.ui64); break; case ULOGD_RET_BOOL: - sprintf(stmt_ins, "'%d',", res->value.b); + snprintf(stmt_ins, stmt_siz-(stmt_ins-stmt), "'%d',", res->value.b); break; case ULOGD_RET_STRING: - *stmt_ins++ = '\''; + if(stmt_siz > (stmt_ins-stmt)+(strlen(res->value.ptr)*2)+4) + { + *stmt_ins++ = '\''; #ifdef OLD_MYSQL - mysql_escape_string(stmt_ins, res->value.ptr, - strlen(res->value.ptr)); + mysql_escape_string(stmt_ins, res->value.ptr, + strlen(res->value.ptr)); #else - mysql_real_escape_string(dbh, stmt_ins, - res->value.ptr, strlen(res->value.ptr)); + mysql_real_escape_string(dbh, stmt_ins, + res->value.ptr, strlen(res->value.ptr)); #endif - stmt_ins = stmt + strlen(stmt); - sprintf(stmt_ins, "',"); - /* sprintf(stmt_ins, "'%s',", res->value.ptr); */ + stmt_ins = stmt + strlen(stmt); + snprintf(stmt_ins, stmt_siz-(stmt_ins-stmt), "',"); + } + else + { + snprintf(stmt_ins, stmt_siz-(stmt_ins-stmt), "'',"); + } + /* snprintf(stmt_ins, stmt_siz-(stmt_ins-stmt), "'%s',", res->value.ptr); */ break; case ULOGD_RET_RAW: ulogd_log(ULOGD_NOTICE, @@ -230,7 +248,7 @@ static int mysql_output(ulog_iret_t *res static int mysql_createstmt(void) { struct _field *f; - unsigned int size; + size_t size; char buf[ULOGD_MAX_KEYLEN]; char *underscore; @@ -241,7 +259,7 @@ static int mysql_createstmt(void) } /* caclulate the size for the insert statement */ - size = strlen(MYSQL_INSERTTEMPL) + strlen(table_ce.u.string); + size = strlen(MYSQL_INSERTTEMPL) + strlen(table_ce.u.string) + 1; for (f = fields; f; f = f->next) { /* we need space for the key and a comma, as well as @@ -252,25 +270,26 @@ static int mysql_createstmt(void) ulogd_log(ULOGD_DEBUG, "allocating %u bytes for statement\n", size); stmt = (char *) malloc(size); - if (!stmt) { ulogd_log(ULOGD_ERROR, "OOM!\n"); return 1; } + stmt_siz = size; - sprintf(stmt, "insert into %s (", table_ce.u.string); + snprintf(stmt, stmt_siz, "insert into %s (", table_ce.u.string); stmt_val = stmt + strlen(stmt); for (f = fields; f; f = f->next) { - strncpy(buf, f->name, ULOGD_MAX_KEYLEN); + strncpy(buf, f->name, ULOGD_MAX_KEYLEN-1); + buf[ULOGD_MAX_KEYLEN-1] = '\0'; while ((underscore = strchr(buf, '.'))) *underscore = '_'; - sprintf(stmt_val, "%s,", buf); + snprintf(stmt_val, stmt_siz-(stmt_val-stmt), "%s,", buf); stmt_val = stmt + strlen(stmt); } *(stmt_val - 1) = ')'; - sprintf(stmt_val, " values ("); + snprintf(stmt_val, stmt_siz-(stmt_val-stmt), " values ("); stmt_val = stmt + strlen(stmt); ulogd_log(ULOGD_DEBUG, "stmt='%s'\n", stmt); @@ -298,7 +317,8 @@ static int mysql_get_columns(const char while ((field = mysql_fetch_field(result))) { /* replace all underscores with dots */ - strncpy(buf, field->name, ULOGD_MAX_KEYLEN); + strncpy(buf, field->name, ULOGD_MAX_KEYLEN-1); + buf[ULOGD_MAX_KEYLEN-1] = '\0'; while ((underscore = strchr(buf, '_'))) *underscore = '.'; @@ -317,7 +337,8 @@ static int mysql_get_columns(const char ulogd_log(ULOGD_ERROR, "OOM!\n"); return 1; } - strncpy(f->name, buf, ULOGD_MAX_KEYLEN); + strncpy(f->name, buf, ULOGD_MAX_KEYLEN-1); + f->name[ULOGD_MAX_KEYLEN-1] = '\0'; f->id = id; f->next = fields; fields = f; --- pgsql/ulogd_PGSQL.c +++ pgsql/ulogd_PGSQL.c 2007/01/08 18:20:04 @@ -39,6 +39,9 @@ static struct _field *fields; /* buffer for our insert statement */ static char *stmt; +/* size of our insert statement buffer */ +static size_t stmt_siz; + /* pointer to the beginning of the "VALUES" part */ static char *stmt_val; @@ -120,62 +123,78 @@ static int pgsql_output(ulog_iret_t *res if (!res || !IS_VALID((*res))) { /* no result, we have to fake something */ - sprintf(stmt_ins, "NULL,"); + snprintf(stmt_ins, stmt_siz-(stmt_ins-stmt), "NULL,"); stmt_ins = stmt + strlen(stmt); continue; } switch (res->type) { case ULOGD_RET_INT8: - sprintf(stmt_ins, "%d,", res->value.i8); + snprintf(stmt_ins, stmt_siz-(stmt_ins-stmt), "%d,", res->value.i8); break; case ULOGD_RET_INT16: - sprintf(stmt_ins, "%d,", res->value.i16); + snprintf(stmt_ins, stmt_siz-(stmt_ins-stmt), "%d,", res->value.i16); break; case ULOGD_RET_INT32: - sprintf(stmt_ins, "%d,", res->value.i32); + snprintf(stmt_ins, stmt_siz-(stmt_ins-stmt), "%d,", res->value.i32); break; case ULOGD_RET_INT64: - sprintf(stmt_ins, "%lld,", res->value.i64); + snprintf(stmt_ins, stmt_siz-(stmt_ins-stmt), "%lld,", res->value.i64); break; case ULOGD_RET_UINT8: - sprintf(stmt_ins, "%u,", res->value.ui8); + snprintf(stmt_ins, stmt_siz-(stmt_ins-stmt), "%u,", res->value.ui8); break; case ULOGD_RET_UINT16: - sprintf(stmt_ins, "%u,", res->value.ui16); + snprintf(stmt_ins, stmt_siz-(stmt_ins-stmt), "%u,", res->value.ui16); break; case ULOGD_RET_IPADDR: #ifdef IP_AS_STRING - *stmt_ins++ = '\''; memset(&addr, 0, sizeof(addr)); addr.s_addr = ntohl(res->value.ui32); tmpstr = (char *)inet_ntoa(addr); - PQescapeString(stmt_ins,tmpstr,strlen(tmpstr)); - stmt_ins = stmt + strlen(stmt); - sprintf(stmt_ins, "',"); + if(stmt_siz > (stmt_ins-stmt)+(strlen(tmpstr)*2)+4) + { + *stmt_ins++ = '\''; + PQescapeString(stmt_ins,tmpstr,strlen(tmpstr)); + stmt_ins = stmt + strlen(stmt); + snprintf(stmt_ins, stmt_siz-(stmt_ins-stmt), "',"); + } + else + { + ulogd_log(ULOGD_NOTICE,"%s: pgsql - no space to add escaped ip string to insert statement\n"); + snprintf(stmt_ins, stmt_siz-(stmt_ins-stmt), "'',"); + } break; #endif /* IP_AS_STRING */ /* EVIL: fallthrough when logging IP as * u_int32_t */ case ULOGD_RET_UINT32: - sprintf(stmt_ins, "%u,", res->value.ui32); + snprintf(stmt_ins, stmt_siz-(stmt_ins-stmt), "%u,", res->value.ui32); break; case ULOGD_RET_UINT64: - sprintf(stmt_ins, "%llu,", res->value.ui64); + snprintf(stmt_ins, stmt_siz-(stmt_ins-stmt), "%llu,", res->value.ui64); break; case ULOGD_RET_BOOL: - sprintf(stmt_ins, "'%d',", res->value.b); + snprintf(stmt_ins, stmt_siz-(stmt_ins-stmt), "'%d',", res->value.b); break; case ULOGD_RET_STRING: - *stmt_ins++ = '\''; - PQescapeString(stmt_ins,res->value.ptr,strlen(res->value.ptr)); - stmt_ins = stmt + strlen(stmt); - sprintf(stmt_ins, "',"); + if(stmt_siz > (stmt_ins-stmt)+(strlen(res->value.ptr)*2)+4) + { + *stmt_ins++ = '\''; + PQescapeString(stmt_ins,res->value.ptr,strlen(res->value.ptr)); + stmt_ins = stmt + strlen(stmt); + snprintf(stmt_ins, stmt_siz-(stmt_ins-stmt), "',"); + } + else + { + ulogd_log(ULOGD_NOTICE,"%s: pgsql - no space to add escaped string to insert statement\n"); + snprintf(stmt_ins, stmt_siz-(stmt_ins-stmt), "'',"); + } break; case ULOGD_RET_RAW: ulogd_log(ULOGD_NOTICE,"%s: pgsql doesn't support type RAW\n",res->key); - sprintf(stmt_ins, "NULL,"); + snprintf(stmt_ins, stmt_siz-(stmt_ins-stmt), "NULL,"); break; default: ulogd_log(ULOGD_NOTICE, @@ -205,12 +224,13 @@ static int pgsql_output(ulog_iret_t *res /* Determine if server support schemas */ static int pgsql_namespace(void) { PGresult *result; - char pgbuf[strlen(PGSQL_HAVE_NAMESPACE_TEMPLATE)+strlen(schema_ce.u.string)+1]; + size_t pgbuf_siz = strlen(PGSQL_HAVE_NAMESPACE_TEMPLATE)+strlen(schema_ce.u.string)+1; + char pgbuf[pgbuf_siz]; if (!dbh) return 1; - sprintf(pgbuf, PGSQL_HAVE_NAMESPACE_TEMPLATE, schema_ce.u.string); + snprintf(pgbuf, pgbuf_siz, PGSQL_HAVE_NAMESPACE_TEMPLATE, schema_ce.u.string); ulogd_log(ULOGD_DEBUG, "%s\n", pgbuf); result = PQexec(dbh, pgbuf); @@ -265,25 +285,27 @@ static int pgsql_createstmt(void) ulogd_log(ULOGD_ERROR, "OOM!\n"); return 1; } + stmt_siz = size; if (pgsql_have_schemas) { - sprintf(stmt, "insert into %s.%s (", schema_ce.u.string, table_ce.u.string); + snprintf(stmt, stmt_siz, "insert into %s.%s (", schema_ce.u.string, table_ce.u.string); } else { - sprintf(stmt, "insert into %s (", table_ce.u.string); + snprintf(stmt, stmt_siz, "insert into %s (", table_ce.u.string); } stmt_val = stmt + strlen(stmt); for (f = fields; f; f = f->next) { - strncpy(buf, f->name, ULOGD_MAX_KEYLEN); + strncpy(buf, f->name, ULOGD_MAX_KEYLEN-1); + buf[ULOGD_MAX_KEYLEN-1] = '\0'; while ((underscore = strchr(buf, '.'))) *underscore = '_'; - sprintf(stmt_val, "%s,", buf); + snprintf(stmt_val, stmt_siz-(stmt_val-stmt), "%s,", buf); stmt_val = stmt + strlen(stmt); } *(stmt_val - 1) = ')'; - sprintf(stmt_val, " values ("); + snprintf(stmt_val, stmt_siz-(stmt_val-stmt), " values ("); stmt_val = stmt + strlen(stmt); ulogd_log(ULOGD_DEBUG, "stmt='%s'\n", stmt); @@ -331,7 +353,8 @@ static int pgsql_get_columns(const char for (intaux=0; intauxname, buf, ULOGD_MAX_KEYLEN); + strncpy(f->name, buf, ULOGD_MAX_KEYLEN-1); + f->name[ULOGD_MAX_KEYLEN-1] = '\0'; f->id = id; f->next = fields; fields = f; @@ -384,32 +408,34 @@ static int pgsql_open_db(char *server, i if (port) len += 20; - connstr = (char *) malloc(len); + connstr = (char *) malloc(len+1); if (!connstr) return 1; if (server) { - strcpy(connstr, " host="); - strcat(connstr, server); + strncpy(connstr, " host=", len); + connstr[len] = '\0'; + strncat(connstr, server, len-strlen(connstr)); } if (port) { char portbuf[20]; snprintf(portbuf, sizeof(portbuf), " port=%u", port); - strcat(connstr, portbuf); + strncat(connstr, portbuf, len-strlen(connstr)); } - strcat(connstr, " dbname="); - strcat(connstr, db); - strcat(connstr, " user="); - strcat(connstr, user); + strncat(connstr, " dbname=", len-strlen(connstr)); + strncat(connstr, db, len-strlen(connstr)); + strncat(connstr, " user=", len-strlen(connstr)); + strncat(connstr, user, len-strlen(connstr)); if (pass) { - strcat(connstr, " password="); - strcat(connstr, pass); + strncat(connstr, " password=", len-strlen(connstr)); + strncat(connstr, pass, len-strlen(connstr)); } dbh = PQconnectdb(connstr); + free(connstr); if (PQstatus(dbh)!=CONNECTION_OK) { exit_nicely(dbh); return 1; --- sqlite3/ulogd_SQLITE3.c +++ sqlite3/ulogd_SQLITE3.c 2007/01/08 18:20:04 @@ -55,6 +55,9 @@ static struct _field *fields; /* buffer for our insert statement */ static char *stmt; +/* size of our insert statement buffer */ +static size_t stmt_siz; + /* pointer to the final prepared statement */ static sqlite3_stmt *p_stmt; @@ -193,7 +196,7 @@ static int _sqlite3_output(ulog_iret_t * static int _sqlite3_createstmt(void) { struct _field *f; - unsigned int size; + size_t size; char buf[ULOGD_MAX_KEYLEN]; char *underscore; char *stmt_pos; @@ -207,7 +210,7 @@ static int _sqlite3_createstmt(void) } /* caclulate the size for the insert statement */ - size = strlen(_SQLITE3_INSERTTEMPL) + strlen(table_ce.u.string); + size = strlen(_SQLITE3_INSERTTEMPL) + strlen(table_ce.u.string) + 1; DEBUGP("initial size: %u\n", size); @@ -230,29 +233,31 @@ static int _sqlite3_createstmt(void) ulogd_log(ULOGD_ERROR, "OOM!\n"); return 1; } + stmt_siz = size; - sprintf(stmt, "insert into %s (", table_ce.u.string); + snprintf(stmt, stmt_siz, "insert into %s (", table_ce.u.string); stmt_pos = stmt + strlen(stmt); for (f = fields; f; f = f->next) { - strncpy(buf, f->name, ULOGD_MAX_KEYLEN); + strncpy(buf, f->name, ULOGD_MAX_KEYLEN-1); + buf[ULOGD_MAX_KEYLEN-1] = '\0'; while ((underscore = strchr(buf, '.'))) *underscore = '_'; - sprintf(stmt_pos, "%s,", buf); + snprintf(stmt_pos, stmt_siz-(stmt_pos-stmt), "%s,", buf); stmt_pos = stmt + strlen(stmt); } *(stmt_pos - 1) = ')'; - sprintf(stmt_pos, " values ("); + snprintf(stmt_pos, stmt_siz-(stmt_pos-stmt), " values ("); stmt_pos = stmt + strlen(stmt); for (i = 0; i < col_count - 1; i++) { - sprintf(stmt_pos,"?,"); + snprintf(stmt_pos, stmt_siz-(stmt_pos-stmt), "?,"); stmt_pos += 2; } - sprintf(stmt_pos, "?)"); + snprintf(stmt_pos, stmt_siz-(stmt_pos-stmt), "?)"); ulogd_log(ULOGD_DEBUG, "stmt='%s'\n", stmt); DEBUGP("about to prepare statement.\n"); @@ -277,7 +282,7 @@ static int _sqlite3_createstmt(void) static int _sqlite3_get_columns(const char *table) { char buf[ULOGD_MAX_KEYLEN]; - char query[SQLITE_SELECT_LEN + CONFIG_VAL_STRING_LEN] = "select * from \0"; + char query[SQLITE_SELECT_LEN + CONFIG_VAL_STRING_LEN + 1] = "select * from \0"; char *underscore; struct _field *f; sqlite3_stmt *schema_stmt; @@ -288,8 +293,8 @@ static int _sqlite3_get_columns(const ch if (!dbh) return 1; - strncat(query,table,LINE_LEN); - + strncat(query,table,sizeof(query)-strlen(query)-1); + result = sqlite3_prepare(dbh,query,-1,&schema_stmt,0); if (result != SQLITE_OK) @@ -297,7 +302,8 @@ static int _sqlite3_get_columns(const ch for (column = 0; column < sqlite3_column_count(schema_stmt); column++) { /* replace all underscores with dots */ - strncpy(buf, sqlite3_column_name(schema_stmt,column), ULOGD_MAX_KEYLEN); + strncpy(buf, sqlite3_column_name(schema_stmt,column), ULOGD_MAX_KEYLEN-1); + buf[ULOGD_MAX_KEYLEN-1] = '\0'; while ((underscore = strchr(buf, '_'))) *underscore = '.'; @@ -316,7 +322,8 @@ static int _sqlite3_get_columns(const ch ulogd_log(ULOGD_ERROR, "OOM!\n"); return 1; } - strncpy(f->name, buf, ULOGD_MAX_KEYLEN); + strncpy(f->name, buf, ULOGD_MAX_KEYLEN-1); + f->name[ULOGD_MAX_KEYLEN-1] = '\0'; f->id = id; f->next = fields; fields = f;