簡體   English   中英

使用消息隊列進行堆棧粉碎

[英]Stack Smashing Using Message Queues

我有以下主要代碼:

#include "ComHandler.h"
#include "socketMessage.h"

#define THIS_IP                     "localhost"
#define C_PORT                      32456
#define S_PORT                      25465
#define S_PORT_UDP                  22548

int main(int argc, char* argv[]) {

conOptions opts;
strncpy(opts.password, "PASS", sizeof("PASS"));
opts.retryQty = 5;
opts.timeout = 300;

char dir[INET6_ADDRSTRLEN];
strncpy(dir, THIS_IP, sizeof(THIS_IP));

if (argv[1][0] == 'C') {

    opts.connType = CLIENT_HANDLER;
    opts.thisID = 2;

    ComHandler comH(opts);

    char buffer[10];
    strncpy(buffer, "Testing", 10);

    int rtnValue = comH.sendMsg(buffer, 10, 1, TCP_C);

    std::cout << "Returned Value: " << rtnValue << std::endl;

} else {
    opts.connType = SERVER_HANDLER;
    opts.thisID = 1;

    ComHandler comH(opts);
    comH.addConnectionData(2, dir, C_PORT);
    comH.addConnectionData(comH.getID(), dir, S_PORT);

    char rcvdTxt[MINIDATA_DATA_SIZE];
    comH.receiveMsg(rcvdTxt, MINIDATA_DATA_SIZE, 2, TCP_C);

    std::cout << "Received: " << rcvdTxt << std::endl;

    comH.closeCommunications();

}
}

該代碼用於測試我的通信平台。 該平台運行良好,但是當處理程序(ComHandler)接收到消息時,就會出現問題。 當我從ComHandler調用方法“receiveMsg”時,我在方法的“返回”中得到“堆棧粉碎檢測”。

這是“ComHandler”類:

#ifndef COMHANDLER_H_
#define COMHANDLER_H_

#include "Constants.h"
#include "ComConstants.h"
#include "DataLogger.h"

#include <list>
#include <math.h>


#define CLIENT_HANDLER                  1
#define SERVER_HANDLER                  2
#define COMMENT_LINE                    '#'
#define TXT_SEPARATOR                       ';'


#define MINIDATA_DATA_SIZE      (COMDATA_MAX_SIZE - 4* sizeof(int))

enum CON_TYPE {
TCP_C, UDP_C
};


#pragma pack(push)
#pragma pack(1)
typedef struct {
int totalPackets;
int sequenceNumber;
int sequenceID;
int dataSize;
char data[MINIDATA_DATA_SIZE];
} miniData;
#pragma pack(pop)

typedef struct connectionOptions {
unsigned int timeout;
unsigned int retryQty;
id_t thisID;
char password[PASSWORD_MAX_SIZE];
int connType;

connectionOptions() :
        timeout(CON_TIMEOUT), retryQty(SOCKET_RETRIES), connType(
                SERVER_HANDLER) {
    memset(password, 0, PASSWORD_MAX_SIZE);
}
connectionOptions(connectionOptions& opt) {
    timeout = opt.timeout;
    retryQty = opt.retryQty;
    thisID = opt.thisID;
    connType = opt.connType;
    memcpy(password, opt.password, PASSWORD_MAX_SIZE);
}

} conOptions;

class ComHandler {
private:
int dataForwarder_ReceiverMsgQueue;
int dataForwarder_SenderMsgQueue;

conOptions opts;

int sequenceID;

Semaphore ch_mux;
SharedMemory<comHandlerGlOp> ch_shm;

void cpyMiniData(miniData* to, miniData* from);
void createIPCs();

public:
ComHandler();
ComHandler(conOptions options);
ComHandler(id_t thisID);
virtual ~ComHandler();

int receiveMsg(char* buffer, int bufferSize, id_t originID,
        CON_TYPE type = TCP_C);
int sendMsg(char* buffer, std::size_t bufferSize, id_t destinationID,
        CON_TYPE type = TCP_C);

void configListenersData(char addr[INET6_ADDRSTRLEN], int port,
        CON_TYPE type);

void addConnectionData(id_t id, char addr[INET6_ADDRSTRLEN], int port);
void addConnectionData(const char* file);
void modifyConnectionData(id_t id, char addr[INET6_ADDRSTRLEN], int port);
void removeConnectionData(id_t id);

int getID();

void closeCommunications();

};

#endif /* COMHANDLER_H_ */

comData結構:

typedef struct {
long type;
int requestType;
char destination[INET6_ADDRSTRLEN];
char origin[INET6_ADDRSTRLEN];
id_t originID;
id_t destinationID;
int port;
pid_t senderPid;
pid_t originPid;
char data[COMDATA_MAX_SIZE];
} comData;

以及有問題的方法:

int ComHandler::receiveMsg(char* buffer, int bufferSize, id_t originID,
    CON_TYPE type) {
comData aux;

aux.type = DATA_RECEIVE;
int qtyReceived = 0;

if (originID != ANY_MSG_ORIGIN) {
    if (type == TCP_C)
        aux.requestType = RECEIVE_DATA_FROM_DESTINATION_TCP;
    else
        aux.requestType = RECEIVE_DATA_FROM_DESTINATION_UDP;
} else {
    if (type == TCP_C)
        aux.requestType = RECEIVE_ANY_DATA_TCP;
    else
        aux.requestType = RECEIVE_ANY_DATA_UDP;
}

aux.originID = originID;
aux.senderPid = getpid();
aux.originPid = getpid();

msgsnd(dataForwarder_ReceiverMsgQueue, &aux, sizeof(comData), 0);
msgrcv(dataForwarder_ReceiverMsgQueue, &aux, sizeof(comData), getpid(), 0);

/* More Code */

return qtyReceived;

}

“return qtyReceived”后出現堆棧粉碎錯誤 叫做。 並且/ *更多代碼* /中間是非重要代碼,因為如果刪除該部分,則會出現堆棧粉碎劇照。 經過大量調試后,我發現如果我致電,就會顯示該粉碎:

`msgrcv(dataForwarder_ReceiverMsgQueue, &aux, sizeof(comData), getpid(), 0);`

如果我評論那條線,我不會收到錯誤。 同樣使用調試器,我能夠看到來自隊列的消息以良好的格式和大小到達,正如它們應該的那樣。

控制台輸出是:

*** stack smashing detected ***: /media/blackhole/workspace/Final/bin/ComTest terminated
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(__fortify_fail+0x45)[0xb7df88d5]
/lib/i386-linux-gnu/libc.so.6(+0xe7887)[0xb7df8887]
/media/blackhole/workspace/Final/bin/ComTest[0x804dc6b]
/media/blackhole/workspace/Final/bin/ComTest[0x804a002]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0xb7d2a113]
/media/blackhole/workspace/Final/bin/ComTest[0x8049d11]
======= Memory map: ========
08048000-08054000 r-xp 00000000 08:05 256373     /media/blackhole/workspace/Final/bin/ComTest
08054000-08055000 r--p 0000b000 08:05 256373     /media/blackhole/workspace/Final/bin/ComTest
08055000-08056000 rw-p 0000c000 08:05 256373     /media/blackhole/workspace/Final/bin/ComTest
08056000-08077000 rw-p 00000000 00:00 0          [heap]
b7d0f000-b7d11000 rw-p 00000000 00:00 0 
b7d11000-b7e87000 r-xp 00000000 08:06 525221     /lib/i386-linux-gnu/libc-2.13.so
b7e87000-b7e89000 r--p 00176000 08:06 525221     /lib/i386-linux-gnu/libc-2.13.so
b7e89000-b7e8a000 rw-p 00178000 08:06 525221     /lib/i386-linux-gnu/libc-2.13.so
b7e8a000-b7e8d000 rw-p 00000000 00:00 0 
b7e8d000-b7ea9000 r-xp 00000000 08:06 525242     /lib/i386-linux-gnu/libgcc_s.so.1
b7ea9000-b7eaa000 r--p 0001b000 08:06 525242     /lib/i386-linux-gnu/libgcc_s.so.1
b7eaa000-b7eab000 rw-p 0001c000 08:06 525242     /lib/i386-linux-gnu/libgcc_s.so.1
b7eab000-b7eac000 rw-p 00000000 00:00 0 
b7eac000-b7ed4000 r-xp 00000000 08:06 525251     /lib/i386-linux-gnu/libm-2.13.so
b7ed4000-b7ed5000 r--p 00028000 08:06 525251     /lib/i386-linux-gnu/libm-2.13.so
b7ed5000-b7ed6000 rw-p 00029000 08:06 525251     /lib/i386-linux-gnu/libm-2.13.so
b7ed6000-b7fb4000 r-xp 00000000 08:06 5514       /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16
b7fb4000-b7fb5000 ---p 000de000 08:06 5514       /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16
b7fb5000-b7fb9000 r--p 000de000 08:06 5514       /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16
b7fb9000-b7fba000 rw-p 000e2000 08:06 5514       /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16
b7fba000-b7fc1000 rw-p 00000000 00:00 0 
b7fdc000-b7fdd000 rw-s 00000000 00:04 163119127  /SYSV02056f32 (deleted)
b7fdd000-b7fdf000 rw-p 00000000 00:00 0 
b7fdf000-b7fe0000 r-xp 00000000 00:00 0          [vdso]
b7fe0000-b7ffe000 r-xp 00000000 08:06 525208     /lib/i386-linux-gnu/ld-2.13.so
b7ffe000-b7fff000 r--p 0001d000 08:06 525208     /lib/i386-linux-gnu/ld-2.13.so
b7fff000-b8000000 rw-p 0001e000 08:06 525208     /lib/i386-linux-gnu/ld-2.13.so
bffdf000-c0000000 rw-p 00000000 00:00 0          [stack]

那么,有什么想法嗎? 如果您需要有關代碼的信息,請問我。

根據 ,在msgsz的參數msgrcv()應是大小mtext的的構件mymsg結構:

struct mymsg {
  long int    mtype;     /* message type */
  char        mtext[1];  /* message text */
}

問題是您包括了mtype成員的大小(4個字節),因此msgrcv()在結構的末尾寫入了四個字節,這破壞了堆棧。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM