LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Why do i get a Segmentation fault (https://www.linuxquestions.org/questions/programming-9/why-do-i-get-a-segmentation-fault-264532/)

laclac01 12-09-2004 12:56 PM

Why do i get a Segmentation fault
 
Why do i get a segmentation fault with the following code?
[code]
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/if.h>
#include <linux/if_tun.h>
#include <errno.h>

int tun_alloc(char *dev)
{
struct ifreq ifr;
int fd, err;

if( (fd = open("/dev/net/tun", O_RDWR )) < 0 )
//return tun_alloc_old(dev);
printf("error");
memset(&ifr, 0, sizeof(ifr));

/* Flags: IFF_TUN - TUN device (no Ethernet headers)
* IFF_TAP - TAP device
*
* IFF_NO_PI - Do not provide packet information
*/
ifr.ifr_flags = IFF_TUN;
if( *dev )
strncpy(ifr.ifr_name, dev, IFNAMSIZ);

if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ){
close(fd);
return err;
}
strcpy(dev, ifr.ifr_name);
return fd;
}
int main()
{
int tunfd;
char *dev="tap";
printf("testing tun");
tunfd=tun_alloc(dev);
return 0;
}

[code]

On both gentoo and redhat and
On both 2.4 and 2.6 kernels.

acid_kewpie 12-09-2004 01:25 PM

what line is giving you the grief? what does gdb say about the segfault?

laclac01 12-09-2004 01:40 PM

Not sure which line is bad. when i run it i get the error.

acid_kewpie 12-09-2004 01:43 PM

ever thought about putting in some debug fprintf's then?? if you can't even get it down to a particular line...

i'm a little lost as to why you'd be trying to compile this piece of pretty cryptic code without being able to debug it a little yourself...

mcleodnine 12-09-2004 01:45 PM

Moved: This thread is more suitable in Programming and has been moved accordingly to help your thread/question get the exposure it deserves.

jwstric2 12-09-2004 03:01 PM

just looking at your code, i think its the way you define the char *. The pointer may be modified to point else where but the results of modifying or lookiing at its contents may be undefined. Define it as char dev[] and reply back if this was it.

dave_starsky 12-09-2004 04:48 PM

char *dev="tap";

you need to malloc() some space before you can just force a string into a char *, and you need to use strcpy() or something to that effect

perfect_circle 12-09-2004 05:04 PM

Quote:

Originally posted by dave_starsky
char *dev="tap";

you need to malloc() some space before you can just force a string into a char *, and you need to use strcpy() or something to that effect

Thats not true.
When you declare a pointer (and only the time you declare it) you may also initialize it.

Code:

char dev[]="tap";
char dev[]={'t','a','p','\0'};

Both are correct

Dextrose 12-09-2004 05:15 PM

Re: Why do i get a Segmentation fault
 
Quote:

ifr.ifr_flags = IFF_TUN;
if( *dev )
strncpy(ifr.ifr_name, dev, IFNAMSIZ);

if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ){
close(fd);
return err;
}
strcpy(dev, ifr.ifr_name);
return fd;
I'm willing to be that one or both of those two lines that I bolded for you are causing the problem. You need to ENSURE that the length of dev "strlen(dev)" is less than or equal to the length of ifr.ifr_name and the other way around must hold true as well since you copy back from ifr.ifr_name into dev. I guess I should say it's one or the other lines, but not both since only one buffer can be shorter than the other.

So, you need to find out which one is shorter and fix it. Or code accordingly... if( strlen(dev) <= strlen(ifr.ifr_name) ) { memcpy(); } etc...

perfect_circle 12-09-2004 05:17 PM

Wait! Maybe i got it.

Code:

#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/if.h>
#include <linux/if_tun.h>
#include <errno.h>

int tun_alloc(char *dev)
{
struct ifreq ifr;
int fd, err;

if( (fd = open("/dev/net/tun", O_RDWR )) < 0 )
//return tun_alloc_old(dev);
printf("error");
memset(&ifr, 0, sizeof(ifr));  <--------ifr_name pointer
will be set to NULL and wont point to
the space allocated for the string any
more, the strncpy will cause a segmentation fault then,
 because it will try to write to unallocated space.


/* Flags: IFF_TUN - TUN device (no Ethernet headers)
* IFF_TAP - TAP device
*
* IFF_NO_PI - Do not provide packet information
*/
ifr.ifr_flags = IFF_TUN;
if( *dev )
strncpy(ifr.ifr_name, dev, IFNAMSIZ);

if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ){
close(fd);
return err;
}
strcpy(dev, ifr.ifr_name);
return fd;
}
int main()
{
int tunfd;
char *dev="tap";
printf("testing tun");
tunfd=tun_alloc(dev);
return 0;
}

I think this is it, but it's just a guess. use fprintf(stderr,........) to find were you get the error.

Dextrose 12-09-2004 05:27 PM

Quote:

Originally posted by perfect_circle
I think this is it, but it's just a guess. use fprintf(stderr,........) to find were you get the error.
Good call...I missed that one. In fact, I'll GUARENTEE that's it. :tisk:

itsme86 12-09-2004 05:27 PM

memset() doesn't alter the address of the destination buffer. It would just fill the allocated memory with 0's, not change the pointer to NULL.

EDIT: I see what you're saying now, and that would make sense, but I checked the structure and ifr_name isn't a pointer, it's just an array so it can't be true:
Code:

struct ifreq
{
#define IFHWADDRLEN    6
#define IFNAMSIZ        16
        union
        {
                char    ifrn_name[IFNAMSIZ];
        } ifr_ifrn;


Dextrose 12-09-2004 05:31 PM

Quote:

Originally posted by itsme86
memset() doesn't alter the address of the destination buffer. It would just fill the allocated memory with 0's, not change the pointer to NULL.
Actually, you're right too. Now that I think about it, he's zeroing out the memory for that struct. But, I can only assume that the string contained within that struct is initialize as such char pString[xx] for example.

Memsetting the struct to zero like you said will not cause the address of that string to go to zero...it will simply zero the memory of that string. Hmmm....

I'm going with what I originally said. I bet it's one of the strcpy calls.

perfect_circle 12-09-2004 05:51 PM

Quote:

ifr_name isn't a pointer, it's just an array so it can't be true
Any array
Code:

char s[10];
is a pointer pointing to a statically allocated memory.
i think if u do :
Code:

char s[10];
s = NULL;

will make you loose the allocated memory.
I don't remember how memset works
but s is still just a pointer.

perfect_circle 12-09-2004 06:18 PM

well ... it's not memset and it's not strncpy or strcpy(unless ioctl() is altering ifr).


:scratch:


All times are GMT -5. The time now is 12:07 AM.