简体   繁体   English

使用消息队列进行堆栈粉碎

[英]Stack Smashing Using Message Queues

i have the following main code: 我有以下主要代码:

#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();

}
}

The code is for testing my communication platform. 该代码用于测试我的通信平台。 The platform works well, but the problem appears when the messages are received by the Handler (ComHandler). 该平台运行良好,但是当处理程序(ComHandler)接收到消息时,就会出现问题。 When i call the method "receiveMsg" from ComHandler, i get a "stack smashing detected" in the "return" of the method. 当我从ComHandler调用方法“receiveMsg”时,我在方法的“返回”中得到“堆栈粉碎检测”。

This is the "ComHandler" class: 这是“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_ */

The comData structure: 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;

And the method with the problem: 以及有问题的方法:

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;

}

The stack smashing error appears after "return qtyReceived;" “return qtyReceived”后出现堆栈粉碎错误 is called. 叫做。 And the /* More Code */ in the middle is the non important code, because if a delete that part, the stack smashing stills appears. 并且/ *更多代码* /中间是非重要代码,因为如果删除该部分,则会出现堆栈粉碎剧照。 After much debugging i found that the smashing appears if i call: 经过大量调试后,我发现如果我致电,就会显示该粉碎:

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

if i comment that line, i don't get the error. 如果我评论那条线,我不会收到错误。 Also with the debugger, i was able to see that the messages from the queue arrive with good format and size, exactly as they should. 同样使用调试器,我能够看到来自队列的消息以良好的格式和大小到达,正如它们应该的那样。

The console output is: 控制台输出是:

*** 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]

So, any ideas? 那么,有什么想法吗? If you need something about the code, just ask me. 如果您需要有关代码的信息,请问我。

According to this , the msgsz parameter of msgrcv() should be the size of the mtext member of the mymsg struct: 根据 ,在msgsz的参数msgrcv()应是大小mtext的的构件mymsg结构:

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

The problem is that you include the size of the mtype member (4 bytes) so msgrcv() writes four bytes past the end of your struct which trashes the stack. 问题是您包括了mtype成员的大小(4个字节),因此msgrcv()在结构的末尾写入了四个字节,这破坏了堆栈。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM