[1878] in linux-net channel archive

home help back first fref pref prev next nref lref last post

general protection violation in sendmsg

daemon@ATHENA.MIT.EDU (Joerg Lenneis)
Wed Feb 7 14:37:06 1996

From: lenneis@statrix2.wu-wien.ac.at (Joerg Lenneis)
To: linux-net@vger.rutgers.edu
Date: 	Wed, 7 Feb 1996 19:46:45 +0100 (MET)

I think there is a bug somewhere in the implementation of the sendmsg system
call. I get the following error from the kernel (1.3.59 plus Mark 6 patches from
Alan Cox):

general protection: 0000
CPU:    0
EIP:    0010:[<001546da>]
EFLAGS: 00010212
eax: bffff7f4   ebx: bffff7f4   ecx: 00000000   edx: 00e1e60c
esi: 00e1e60c   edi: 00000000   ebp: 00000000   esp: 00c7ae0c
ds: 0018   es: 0018   fs: 0018   gs: 002b   ss: 0018
Process sender (pid: 102, process nr: 21, stackpage=00c7a000)
Stack: 0000002b 00e5a018 00c7aeb4 00000400 00000400 00000000 00e5a000 00e1e60c 
       00154837 00e1e60c 00e5a018 00000400 00000000 00000000 bffff7f4 00000010 
       00e1e60c 00000000 00000000 00000400 001567b1 00e1e60c 00c7aeb4 00000400 
Call Trace: [<00154837>] [<001567b1>] [<00156700>] [<0013ca9b>] [<0013bca1>] [<0013d15a>] [<0015583a>] 
       [<0013c847>] [<0013cf9e>] [<0010abbe>] 
Code: 66 8b 03 66 85 c0 74 06 66 83 f8 02 75 07 66 83 7b 02 00 75 


This happens in the function udp_sendto in the code section

	...........
        if (usin) 
        {
       
                if (addr_len < sizeof(sin)) 
                        return(-EINVAL);
                if (usin->sin_family && usin->sin_family != AF_INET) 
                        return(-EINVAL);
                if (usin->sin_port == 0) 
                        return(-EINVAL);
        } 
        else 
	...........


usin is a struct sockaddr_in *. As soon as it is accessed in "if (usin)" the
error occurs. I have tried the same piece of code using the sendto system call
and that works, so I guess somewhere along the calling sequence something weird
happens to the usin argument. The following piece of source reproduces the error:

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/uio.h>
#include <stdlib.h>
#include <string.h>

#define BUFSIZE 128


main () {
     struct sockaddr_in sa;
     struct sockaddr_in ta;

     char buf1[BUFSIZE];
     char buf2[BUFSIZE];
     
     int s;

     struct msghdr msg;
     struct iovec iov[2];

     if (( s = socket ( AF_INET, SOCK_DGRAM, 0 )) < 0 ) {
	  perror ("socket");
	  exit(1);
     }

     bzero ( (char*) &sa, sizeof(sa)); 
     sa.sin_family=AF_INET;
     sa.sin_addr.s_addr= inet_addr("137.208.6.45");
     sa.sin_port =  htons(9998);

     bzero ( (char*) &ta, sizeof(sa)); 
     ta.sin_family=AF_INET;
     ta.sin_addr.s_addr= inet_addr("137.208.6.33");
     ta.sin_port =  htons(9999);

     if (bind(s, (struct sockaddr* )&sa, sizeof(sa))<0){
	  perror("bind");
	  exit(1);
     }

     msg.msg_name = (char *) &ta; 
     msg.msg_namelen =  sizeof(ta);
     msg.msg_iov = iov; 
     msg.msg_iovlen = 2;
     msg.msg_accrights = NULL;

     iov[0].iov_base = buf1;
     iov[0].iov_len = BUFSIZE;
     iov[1].iov_base = buf2;
     iov[1].iov_len = BUFSIZE;

     if(sendmsg(s, &msg, 0) < 0) {
	  perror ( "Sendmsg");
	  exit(1);
     }
}


-- 
Joerg Lenneis

University of Economics and Business Adminstration
Department for Applied Statistics and Data Processing
Augasse 2-6, 1090 Vienna, Austria

Tel. *43/1/31336 4758
email: lenneis@wu-wien.ac.at


home help back first fref pref prev next nref lref last post