beasone
beasone

Reputation: 1085

Valgrind shows the debugging result,but the result isn't right

When I just run my program:ns-server everytime, it will show me that it decrypts message fail, but when I use valgrind try to find why this error happens, it works fine. Every time when I use valgrind to debug it, it works fine. the valgrind result is :

valgrind --leak-check=yes ./ns-server
==44887== Memcheck, a memory error detector
==44887== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==44887== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==44887== Command: ./ns-server
==44887== 
first get nextlen 564
nextlen is 564
==44887== Thread 2:
==44887== Invalid read of size 1
==44887==    at 0x6C49: strlen (vg_replace_strmem.c:427)
==44887==    by 0x100134E6F: StringBuffer::setString(char const*) (in ./ns-server)
==44887==    by 0x100159A4F: XString::setFromAnsi(char const*) (in ./ns-server)
==44887==    by 0x100025396: CkRsa::DecryptStringENC(char const*, bool,  CkString&) (in ./ns-server)
==44887==    by 0x1000130EA: My_RSA::MyDecryption(char*, CkString&) (RSAsample.cpp:52)
==44887==    by 0x1000021C1: Server::Register(char*, int, char*) (Server.cpp:164)
==44887==    by 0x100001EAB: Server::Evaluate_MSG(void*) (Server.cpp:75)
==44887==    by 0x409898: _pthread_body (in /usr/lib/system/libsystem_pthread.dylib)
==44887==    by 0x409729: _pthread_start (in /usr/lib/system/libsystem_pthread.dylib)
==44887==    by 0x40DFC8: thread_start (in /usr/lib/system/libsystem_pthread.dylib)
==44887==  Address 0x100b3f150 is 0 bytes after a block of size 128 alloc'd
==44887==    at 0x47E1: malloc (vg_replace_malloc.c:300)
==44887==    by 0x1000020F4: Server::Register(char*, int, char*) (Server.cpp:154)
==44887==    by 0x100001EAB: Server::Evaluate_MSG(void*) (Server.cpp:75)
==44887==    by 0x409898: _pthread_body (in /usr/lib/system/libsystem_pthread.dylib)
==44887==    by 0x409729: _pthread_start (in /usr/lib/system/libsystem_pthread.dylib)
==44887==    by 0x40DFC8: thread_start (in /usr/lib/system/libsystem_pthread.dylib)
==44887== 

This is part of the result. In this result, it mentions:

by 0x100134E6F: StringBuffer::setString(char const*) (in ./ns-server)
==44887==    by 0x100159A4F: XString::setFromAnsi(char const*) (in ./ns-server)
==44887==    by 0x100025396: CkRsa::DecryptStringENC(char const*, bool,  CkString&) (in ./ns-server)

But these 3 functions come from static library which I download them from http://www.chilkatsoft.com/refdoc/vcCkRsaRef.html does this mean the error actually happen in these functions? Why when I run with valgrind, my project can output the right result?When I run it without any debugging tool, it will output "decrypt fail". Valgrind will change something related to my program?

My code is as follows:

int main(int argc, const char * argv[])
{
Server myServer(SERVER_PORT);//initialize server's port num,set up socket

myServer.Start();
return 0;
}

int Server::Start()
{

send_public_key server_pub_key;
server_pub_key.heads.random=random()%10;
server_pub_key.heads.request_type=PUBLICKEY;
server_pub_key.heads.length=sizeof(send_public_key);

strcpy(server_pub_key.pubkey,server_rsa.publickey);

TCPServer.SetupListen(PortListen,Evaluate_MSG,"",0,PUBLICKEY,(char *)&server_pub_key,server_pub_key.heads.length);
    return 0;
}

int TCPConnect::SetupListen(int port, void * trifunc(void *),char * refuseMSG,int refuseLen,int pub,char *msg,int length)
{
if((mi_SocketToListen=socket(AF_INET,SOCK_STREAM,0))==-1)
{
    printf("create socket failed\n");
    return errno;
}

struct sockaddr_in ts_SocketAddrToListen;
ts_SocketAddrToListen.sin_addr.s_addr=INADDR_ANY;
SetupSocketAddrToTarget(NULL, port, ts_SocketAddrToListen,1);
if( bind(mi_SocketToListen,(struct sockaddr *)&ts_SocketAddrToListen,sizeof(struct sockaddr)) == -1)
{
    printf("establish socket failed!\n");
    return errno;
}
if(listen(mi_SocketToListen,99)==-1)
{
    printf("listen failed\n");
    return errno;
}
while (1)
{
    int ti_sockfd;
    struct sockaddr_in ts_sockaddr;
    socklen_t ti_size = sizeof(struct sockaddr_in);
    if((ti_sockfd=accept(mi_SocketToListen,(struct sockaddr *)&ts_sockaddr,&ti_size))==-1)
    {
        printf("accept user failed\n");
        return errno;
    }
    if (threadlist.size() < mi_MaxConnection)
    {

        if(pub==80)//if this needs me to send a public key immediately afther i accept it
        {

            SendMsg(ti_sockfd, msg,length);

        }

        mm_clients.insert(std::pair<int,struct sockaddr_in>(ti_sockfd,ts_sockaddr));

        pthread_t tp_threadfd;

        pthread_create(&tp_threadfd,NULL,trifunc,(void *)&ti_sockfd);

        threadlist.push_back(tp_threadfd);

    }
    else
    {
        SendMsg(ti_sockfd, refuseMSG, refuseLen);
        CloseConnect(ti_sockfd,NULL);
    }
}

return 0;
};

void * Server::Evaluate_MSG(void *arg)
{

int socketfd = *((int *) arg);

header checkheader;
int err;
while (true)
{
    err = 0;

    char * msg;
    char *ip;
    ip=(char *)malloc(sizeof(char)*INET_ADDRSTRLEN);
    memset(ip,0,sizeof(char)*INET_ADDRSTRLEN);

    int nextlen=Server::TCPServer.GetNextlen(socketfd);

    msg=(char *)malloc(sizeof(char)*nextlen);
    memset(msg,0,sizeof(char)*nextlen);

    msg=Server::TCPServer.Receive(socketfd, nextlen);

    //Server::TCPServer.Receive(socketfd,msg);
    struct sockaddr_in sender_ip;
    memset(&sender_ip,0,sizeof(struct sockaddr_in));

    sender_ip=Server::TCPServer.GetInfoBySocket(socketfd);

    inet_ntop(AF_INET,&sender_ip.sin_addr,ip,INET_ADDRSTRLEN);

    memset(&checkheader,0,sizeof(header));
    memcpy(&checkheader,msg,sizeof(header));
    switch(checkheader.request_type)
    {
        case REGISTER:
            err = Register(msg, socketfd,ip);

            break;
        case LOGIN:
            err=Login(msg, socketfd,ip);
            break;
        default:
            break;
    }
    free(ip);
    free(msg);
    if (err<0)
    {
        cout<<"error!"<<endl;
        pthread_exit(0);
    }
}

}

int Server::Register(char *msg,int sockfd,char *ip)
{
request_register reg;
memset(&reg,0,sizeof(request_register));
 memcpy(&reg,msg,sizeof(request_register));



if(reg.real_pass!=REAL_PASS)
{
    //ignore
}
else
{
    send_user_success success_err;
    success_err.heads.random=random()%10;
    success_err.heads.length=sizeof(success_err);
    CkString user_name_outData;
    char *recv_username;
    recv_username=(char *)malloc(sizeof(char)*LENGTH_CIPHERTEXT);
    memset(recv_username,0,sizeof(char)*LENGTH_CIPHERTEXT);
    memcpy(recv_username,reg.username,sizeof(char)*LENGTH_CIPHERTEXT);

    server_rsa.MyDecryption(recv_username,user_name_outData);
    //it decrypt fails

    cout<<"after returning:"<<user_name_outData.getString()<<endl;

-------------------Above is part of function of Register(), it is too long, I just post part of it----------------

bool My_RSA::MyDecryption(char *ciphertext,CkString &outData)
 {
 rsaDecryptor.put_EncodingMode("hex");
 rsaDecryptor.ImportPrivateKey(privatekey);
 bool userPrivateKey;
 userPrivateKey=true;

 const char *cipher;
 cipher=ciphertext;


const char * decryptedStr ;
decryptedStr= new char[SAY_MAX];
memset((char *)decryptedStr,0,sizeof(char)*SAY_MAX);

 bool test=(char *) rsaDecryptor.DecryptStringENC(ciphertext, userPrivateKey, outData);//(decryptedStr, userPrivateKey);
if (!test) {
    cout<<"decrypt failed"<<endl;
    return false;
}

return true;

}

The error is: it will shows "decrypt failed" when I run without any debug tool, but it will decrypt definitely with valgrind. This is header(part):

static std::map <string,struct user_info> user_info_map;//string is user's name
static My_RSA server_rsa;

class Server
{
public:
Server(int p);

protected:

static TCPConnect TCPServer;

public:
int PortListen;


protected:
static int Register(char *msg,int sockfd,char *ip);
static int Login(char *msg,int sockfd,char *ip);
static int Lock_Un_Out(char *msg,int sockfd,int lock_unlock);

static int Check_User(int sockfd);
static int Send_User(char *msg,int sockfd);

static int Update(char *msg,int sockfd);
public:
int Start();

static void * Evaluate_MSG(void *arg);
};

The error is part is that it decrypts fail, but I don't think it is related to the function of DecryptStringENC because when I run it with valgrind or Xcode, it works fine frequently.

Upvotes: 0

Views: 135

Answers (1)

beasone
beasone

Reputation: 1085

Now I see why an error happens. When I pass ciphertext into MyDecryption(char *ciphertext,CkString &outData) I set the size of it is 128bytes(Because when I use strlen to see the ciphertext's size, it shows 128). But I sudden think about that maybe I should malloc ciphertext with size of 129 bytes because '/0' will be attached to a string. Then, problem solves!!!!!!!

Upvotes: 2

Related Questions