Search code examples
clinuxsegmentation-faultmessagestack-smash

Message queue stack smashing


I'm trying to implement a message queue and I have named the one process server and the other one client (as you can see I wanted to stick with the conventional names). The is a piece of code above the server that you don't need to care about since it works fine. I just posted it in case it messes up the whole effort.

My actual question is how the server is supposed to know the pid of the client since they cannot connect without the key, which is made using ftok and the pid as a function argument?

If you want to execute it yourself, you need to run the server program first and the client program afterward (no cmd args needed). I appreciate even the slightest kind of help. Thank you all in advance.

//HEADER FILE NAMED : v1.h
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include <sys/stat.h>
#include<string.h>

#define N 95
#define STRLIM 60
#define PID 25922   
#define MSGQ_KEY 1234
#define REQ 1
#define RSP 2

#define REQ_SIZE (sizeof(struct request))
#define RSP_SIZE (sizeof(struct response))

struct request{
    long type;
    int mqid ;
    char* msg;
};

struct response{
    long type ;
    int res;
    char* msg;
};

int estab(char** contact);

int estab(char** contact){
char* test;
test="hi";
int ret;
ret=strcmp(*contact,test);
if(ret<0){
    return 1;
}
    return 0;
}//end of estab

//SERVER 
#include <fcntl.h>  
#include"v1.h"  

char** cat;
int fd;

int main(int argc, char const *argv[])
{   int i;
    int mqid;
    struct response rsp;
    struct request req;
        
    cat=(char**)malloc(sizeof(char*)*N);
    fd=open("dictionary.txt",O_RDONLY); 
    if(fd==-1){
        printf("fd error %d" , fd);
        perror("Error:");        
    }
    
    for(i=0;i<N;i++){
        cat[i]=(char*)malloc(sizeof(char)*STRLIM);
       
        read(fd,cat[i],40);
        printf("%s", cat[i]);
    }
    //////////////////end of char ** /////////////////
    int pid=getpid();
    key_t key=ftok("/home/myName/Desktop/as3/v1/v1s.c",PID);
    printf("The key is : %d",key);
    mqid=msgget(key,IPC_CREAT|S_IRWXU|IPC_NOWAIT);
        
    int ret=0;
    do{       
        msgrcv(mqid,&req,REQ_SIZE,0,0);   
        perror("its:");
        ret=estab(&req.msg);        
    }while(ret!=0);
    msgsnd(mqid,&rsp,RSP_SIZE,0);
    printf("connected");

   return 0;}//end of main 


#include"v1.h"

int main(int argc, char const *argv[])
{   int mqid,ret,pid;
    struct request req;
    struct response rsp={0};
  
    req.msg="hi";
    pid=getpid();
    printf("client's pid : %d",pid);
    pid=PID;
    mqid=msgget(MSGQ_KEY,0);

    msgsnd(mqid,&req,REQ_SIZE,0);

    do{
        msgrcv(mqid,&rsp,RSP_SIZE,0,0);
      
        ret=estab(&rsp.msg);
          
    }while(ret!=0);
    printf("connected from client!");
    return 0;
}


Solution

  • The server cannot and need not know the pid of the client. The server starts first and the clients come later on. So we need to fix the parameters of ftok before coding the server and client. The function ftok is

    key_t ftok(const char *pathname, int proj_id);
    

    The first parameter, pathname, is an existing and accessible file in the file system. The second parameter, proj_id, is an integer whose last eight bits are non-zero.

    Using the same values of pathname and proj_id, we can generate the (same) key in the server and client.

    The client should also make a queue for itself for receiving the reply from the server. The client can send its message queue id in the message to the server. The server receives the message, processes it and replies on the queue id sent by the client.