Hi. I am using libvirt for some time and I have found the following problem.
When I try opening two connections with the same credentials to the same host but using different transport(TCP and TLS) I get the following error when trying to free the TLS one:
"*** Error in `./test': double free or corruption (!prev): 0x00000000014a7a60 ***
Aborted (core dumped)"
Example code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libvirt/libvirt.h>
struct CredentialsPack {
const char* username;
const char* password;
};
struct CredentialsPack* newCredentialsPack(const char* username,
const char* password) {
struct CredentialsPack* ptr = malloc(sizeof(struct CredentialsPack));
ptr->username = username;
ptr->password = password;
return ptr;
}
static int authCredTypes[] = { VIR_CRED_AUTHNAME, VIR_CRED_PASSPHRASE, };
static int authCb(virConnectCredentialPtr cred, unsigned int ncred,
void* cbdata) {
struct CredentialsPack* inputCreds = (struct CredentialsPack*) cbdata;
int i;
for (i = 0; i < ncred; ++i) {
if (cred[i].type == VIR_CRED_AUTHNAME) {
cred[i].result = strdup(inputCreds->username);
if (cred[i].result == NULL) {
return -1;
}
cred[i].resultlen = strlen(cred[i].result);
} else if (cred[i].type == VIR_CRED_PASSPHRASE) {
cred[i].result = strdup(inputCreds->password);
if (cred[i].result == NULL) {
return -1;
}
cred[i].resultlen = strlen(cred[i].result);
}
}
return 0;
}
int main(){
struct CredentialsPack* credentials = newCredentialsPack("user", "pass");
virConnectAuth auth;
auth.credtype = authCredTypes;
auth.ncredtype = sizeof(authCredTypes) / sizeof(int);
auth.cb = authCb;
auth.cbdata = credentials;
virConnectPtr conn;
conn = virConnectOpenAuth("qemu+tcp://host1/system", &auth, 0);
struct CredentialsPack* credentials2 = newCredentialsPack("user", "pass");
virConnectAuth auth2;
auth2.credtype = authCredTypes;
auth2.ncredtype = sizeof(authCredTypes) / sizeof(int);
auth2.cb = authCb;
auth2.cbdata = credentials2;
virConnectPtr conn2;
conn2 = virConnectOpenAuth("qemu://host1/system", &auth2, 0);
// virConnectClose(conn); // this does not change the behaviour
virConnectClose(conn2); // here the error occurs
}
If I try to close "conn" then everything works until I try to close "conn2". I can even invoke virConnectListAllDomains using "conn2" and use the domain pointers when "conn" is closed. The problem is when I try to close "conn2".