Fix a memory leak of port service name (strdup but not freed)

This commit is contained in:
dmiller 2022-09-13 21:09:38 +00:00
parent 8b3465231e
commit 5f21094a68
2 changed files with 47 additions and 36 deletions

View file

@ -84,33 +84,39 @@ Port::Port() {
state_reason_init(&reason);
}
void Port::freeService(bool del_service) {
if (service != NULL) {
std::vector<char *>::iterator it;
void serviceDeductions::erase() {
std::vector<char *>::iterator it;
if (service->name)
free(service->name);
if (service->product)
free(service->product);
if (service->version)
free(service->version);
if (service->extrainfo)
free(service->extrainfo);
if (service->hostname)
free(service->hostname);
if (service->ostype)
free(service->ostype);
if (service->devicetype)
free(service->devicetype);
if (service->service_fp)
free(service->service_fp);
for (it = service->cpe.begin(); it != service->cpe.end(); it++)
free(*it);
service->cpe.clear();
if (this->product)
free(this->product);
if (this->version)
free(this->version);
if (this->extrainfo)
free(this->extrainfo);
if (this->hostname)
free(this->hostname);
if (this->ostype)
free(this->ostype);
if (this->devicetype)
free(this->devicetype);
if (this->service_fp)
free(this->service_fp);
// For now, always free CPE strings
for (it = this->cpe.begin(); it != this->cpe.end(); it++)
free(*it);
this->cpe.clear();
if (del_service)
delete service;
}
this->name = NULL;
this->name_confidence = 0;
this->product = NULL;
this->version = NULL;
this->extrainfo = NULL;
this->hostname = NULL;
this->ostype = NULL;
this->devicetype = NULL;
this->service_tunnel = SERVICE_TUNNEL_NONE;
this->service_fp = NULL;
this->dtype = SERVICE_DETECTION_TABLE;
}
void Port::freeScriptResults(void)
@ -253,7 +259,6 @@ void serviceDeductions::populateFullVersionString(char *buf, size_t n) const {
// pass in an allocated struct serviceDeductions (don't worry about
// initializing, and you don't have to free any internal ptrs. See the
// serviceDeductions definition for the fields that are populated.
// Returns 0 if at least a name is available.
void PortList::getServiceDeductions(u16 portno, int protocol, struct serviceDeductions *sd) const {
const Port *port;
@ -265,7 +270,7 @@ void PortList::getServiceDeductions(u16 portno, int protocol, struct serviceDedu
*sd = serviceDeductions();
service = nmap_getservbyport(portno, IPPROTO2STR(protocol));
if (service != NULL)
sd->name = strdup(service->s_name);
sd->name = service->s_name;
else
sd->name = NULL;
sd->name_confidence = 3;
@ -315,6 +320,8 @@ void PortList::setServiceProbeResults(u16 portno, int protocol,
port = createPort(portno, protocol);
if (port->service == NULL)
port->service = new serviceDeductions;
else
port->service->erase();
if (sres == PROBESTATE_FINISHED_HARDMATCHED
|| sres == PROBESTATE_FINISHED_SOFTMATCHED) {
@ -341,10 +348,8 @@ void PortList::setServiceProbeResults(u16 portno, int protocol,
// port->serviceprobe_results = sres;
port->service->service_tunnel = tunnel;
port->freeService(false);
if (sname)
port->service->name = strdup(sname);
port->service->name = sname;
else
port->service->name = NULL;
@ -426,10 +431,14 @@ PortList::~PortList() {
for(proto=0; proto < PORTLIST_PROTO_MAX; proto++) { // for every protocol
if(port_list[proto]) {
for(i=0; i < port_list_count[proto]; i++) { // free every Port
if(port_list[proto][i]) {
port_list[proto][i]->freeService(true);
port_list[proto][i]->freeScriptResults();
delete port_list[proto][i];
Port *port = port_list[proto][i];
if(port) {
if (port->service) {
port->service->erase();
delete port->service;
}
port->freeScriptResults();
delete port;
}
}
free(port_list[proto]);

View file

@ -115,9 +115,11 @@ void random_port_cheat(u16 *ports, int portcount);
struct serviceDeductions {
serviceDeductions();
// Free any strings that need to be freed and set all pointers to null.
void erase();
void populateFullVersionString(char *buf, size_t n) const;
char *name; // will be NULL if can't determine
const char *name; // will be NULL if can't determine
// Confidence is a number from 0 (least confident) to 10 (most
// confident) expressing how accurate the service detection is
// likely to be.
@ -236,7 +238,7 @@ class PortList {
// pass in an allocated struct serviceDeductions (don't worry about initializing, and
// you don't have to free any internal ptrs. See the serviceDeductions definition for
// the fields that are populated. Returns 0 if at least a name is available.
// the fields that are populated.
void getServiceDeductions(u16 portno, int protocol, struct serviceDeductions *sd) const;
#ifndef NOLUA