stat function segmentation fault

stat function segmentation fault

Post by Adam Oldh » Sat, 29 Dec 2001 03:43:28



Hey people,

I have done a bit of searching on this with no solutions so far.  I am
using linux kernel 2.4.8 on an x86, with reiserfs and glibc 2.2.

I have a rather complex program that kep crashing on stat() calls (man
2 stat).

I wrote a sample program that yielded the same issue:
        #include <sys/types.h>
        #include <sys/stat.h>
        #include <unistd.h>

        main()
        {
           struct stat *statbuf=NULL;
           if(stat("a.c", statbuf) == -1)
              printf("ERROR.\n");

           printf("done.\n");
        }

I have tried few things.  If I use a nonexistant filename, stat
finished with a errno=4 (which is correct).  However, if I use ANY
valid filename (valid meaning that a fiel exists with that name) then
stat will seg fault with (from GDB):
Program received signal SIGSEGV, Segmentation fault.
0x40106715 in __xstat () from /lib/libc.so.6

I can reproduce this on 3 different systems, unfortunately, I don't
have any systems to test with that have different configurations.

Thanks hopefully,

Adam Oldham

 
 
 

stat function segmentation fault

Post by Kaz Kylhe » Sat, 29 Dec 2001 04:13:50



>Hey people,

>I have done a bit of searching on this with no solutions so far.  I am
>using linux kernel 2.4.8 on an x86, with reiserfs and glibc 2.2.

>I have a rather complex program that kep crashing on stat() calls (man
>2 stat).

>I wrote a sample program that yielded the same issue:
>        #include <sys/types.h>
>        #include <sys/stat.h>
>        #include <unistd.h>

>        main()
>        {
>           struct stat *statbuf=NULL;
>           if(stat("a.c", statbuf) == -1)
>              printf("ERROR.\n");

What do you expect when you don't allocate memory for a structure,
passing a null pointer to the library? I don't see anything in POSIX
that requires stat() to detect invalid pointers, and return an error.

That would happen if stat() were a completely naive wrapper for
a system call, which it apparently is not quite the case in glibc.

Robustess of the system interface against bad pointers is intended to
protect the system from an erroneous or malicious program, not to protect
the programmer from his own mistakes.  A segmentation fault signal is
as good a response as any.

Quote:>           printf("done.\n");
>        }

>I have tried few things.  If I use a nonexistant filename, stat
>finished with a errno=4 (which is correct).  However, if I use ANY
>valid filename (valid meaning that a fiel exists with that name) then
>stat will seg fault with (from GDB):
>Program received signal SIGSEGV, Segmentation fault.
>0x40106715 in __xstat () from /lib/libc.so.6

If you think this is a genuine issue, report it to the libc-alpha
mailing list.

 
 
 

stat function segmentation fault

Post by Floyd Davidso » Sat, 29 Dec 2001 04:16:10



>Hey people,

>I have done a bit of searching on this with no solutions so far.  I am
>using linux kernel 2.4.8 on an x86, with reiserfs and glibc 2.2.

>I have a rather complex program that kep crashing on stat() calls (man
>2 stat).

>I wrote a sample program that yielded the same issue:
>        #include <sys/types.h>
>        #include <sys/stat.h>
>        #include <unistd.h>

>        main()
>        {
>           struct stat *statbuf=NULL;

You have allocated space for a _pointer_ to a stat buffer, but
no space for said buffer.

Quote:>           if(stat("a.c", statbuf) == -1)

Calling stat() with the pointer holding NULL as the address causes
stat() to attempt to write to NULL, which should cause a seg fault.

int main(void)
{
  struct stat st;

  if (-1 == stat("a.c", &st))
     ...

--
Floyd L. Davidson         <http://www.ptialaska.net/~floyd>

 
 
 

stat function segmentation fault

Post by Robert J. Hanse » Sat, 29 Dec 2001 05:52:17


Quote:>         #include <sys/types.h>
>         #include <sys/stat.h>
>         #include <unistd.h>

>         main()
>         {
>            struct stat *statbuf=NULL;
>            if(stat("a.c", statbuf) == -1)
>               printf("ERROR.\n");

>            printf("done.\n");
>         }

> I have tried few things.  If I use a nonexistant filename, stat finished
> with a errno=4 (which is correct).  However, if I use ANY valid filename
> (valid meaning that a fiel exists with that name) then stat will seg

The problem is that while stat expects a struct stat pointer for its
second argument, it expects that pointer to point at a valid memory space.
 The reason is that the stat call overwrites the memory location with the
file's statistics.  So when you pass in a NULL, the program attempts to
dereference memory location NULL, which will always, always, segfault your
system.

Alternate ways you can do the same thing:

int main(int argc, char *argv[])
{
        struct stat *statbuf = malloc(sizeof(struct stat));
        ... rest same as before ...
        free(statbuf);
        return EXIT_SUCCESS;

Quote:}

int main(int argc, char *argv[])
{
        struct stat statbuf;
        if (stat("filename", &statbuf) == -1)
                printf("ERROR\n");
        printf("done\n");
        return EXIT_SUCCESS;

Quote:}

Either one should work fine for you.  I prefer the second, since it
eliminates the risk of memory leaks.

Also note that it's "int main(int argc, char *argv[])", not "main()".
While that notation is still accepted by some compilers, it's vastly
preferred to use an explicit return value-type and an explicit set of
arguments.

Also, you need to return a value out of main(), even though some compilers
will let you get around it.  "return 0" or "return EXIT_SUCCESS" are the
customary ways of showing that a program terminated successfully.

 
 
 

stat function segmentation fault

Post by Kasper Dupon » Sat, 29 Dec 2001 06:28:27



> dereference memory location NULL, which will always, always, segfault your
> system.

Actually not always, you could make NULL a valid pointer by
mmaping something on that address. (But that is so rarely
needed that you shouldn't even think about it, and it will
also make debugging harder.)

--
Kasper Dupont

 Notice: By sending SPAM (UCE/BCE) to this address, you are
accepting and agreeing to our charging a $1000 fee, per
email, for handling and processing, and you agree to pay any
and all costs for collecting this fee.

 
 
 

stat function segmentation fault

Post by Eric P. McC » Sat, 29 Dec 2001 07:04:03



> > dereference memory location NULL, which will always, always, segfault your
> > system.
> Actually not always, you could make NULL a valid pointer by
> mmaping something on that address. (But that is so rarely
> needed that you shouldn't even think about it, and it will
> also make debugging harder.)

I believe the CPU hardware will always trap NULL accesses.  I can't
find anything on it right now, but I remember reading that for IA32
CPUs selector zero is reserved and cannot be used without generating a
fault.

--

"I woke up this morning and realized what the game needed: pirates,
pimps, and gay furries."  - Rich "Lowtax" Kyanka

 
 
 

stat function segmentation fault

Post by Kasper Dupon » Sat, 29 Dec 2001 07:16:54




> > > dereference memory location NULL, which will always, always, segfault your
> > > system.

> > Actually not always, you could make NULL a valid pointer by
> > mmaping something on that address. (But that is so rarely
> > needed that you shouldn't even think about it, and it will
> > also make debugging harder.)

> I believe the CPU hardware will always trap NULL accesses.  I can't
> find anything on it right now, but I remember reading that for IA32
> CPUs selector zero is reserved and cannot be used without generating a
> fault.

Yes, but pointers on i386 Linux only contains the offset
not the selector. AFAIK no software on Linux uses selctors
except for runing DOS/Windows software. The compiler will
not generate code using selectors, by default any Linux
program will use the selector set up by the kernel.

This program actually works:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>

int main()
{
  mmap(NULL,getpagesize(),PROT_READ|PROT_WRITE,
       MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS,0,0);
  sprintf(NULL,"%s %s!\n","Hello","world");
  write(0,NULL,strlen(NULL));
  return 0;

Quote:}

--
Kasper Dupont

 Notice: By sending SPAM (UCE/BCE) to this address, you are
accepting and agreeing to our charging a $1000 fee, per
email, for handling and processing, and you agree to pay any
and all costs for collecting this fee.

 
 
 

stat function segmentation fault

Post by Eric P. McC » Sat, 29 Dec 2001 08:51:34



> Yes, but pointers on i386 Linux only contains the offset
> not the selector.

Duh.  I can spell-check my posts; I can grammar-check them; but I
still don't have a program that screens them for stupidity.

--

"I woke up this morning and realized what the game needed: pirates,
pimps, and gay furries."  - Rich "Lowtax" Kyanka

 
 
 

stat function segmentation fault

Post by Floyd Davidso » Sat, 29 Dec 2001 09:36:30





>> > > dereference memory location NULL, which will always, always, segfault your
>> > > system.

>> > Actually not always, you could make NULL a valid pointer by
>> > mmaping something on that address. (But that is so rarely
>> > needed that you shouldn't even think about it, and it will
>> > also make debugging harder.)

>> I believe the CPU hardware will always trap NULL accesses.  I can't
>> find anything on it right now, but I remember reading that for IA32
>> CPUs selector zero is reserved and cannot be used without generating a
>> fault.

>Yes, but pointers on i386 Linux only contains the offset
>not the selector. AFAIK no software on Linux uses selctors
>except for runing DOS/Windows software. The compiler will
>not generate code using selectors, by default any Linux
>program will use the selector set up by the kernel.

>This program actually works:

However, if it works it is totally an accident.  

You've invoked undefined behavior as far as the C compiler is
concerned.  The reason is because NULL is guaranteed to generate
a "null pointer", which the C Standard guarantees to be
*invalid* as a memory address.  Using NULL as an address for
mmap() and or later accessing memory via a NULL pointer results
in undefined behavior.  

That behavior on your particular system might result in what
appears to be the exact result you expected... but on another
system it may cause the traditional "format your hard disk" or
"demons to fly out your nose" actions used to explain what
"undefined behavior" means.

Even on your system the next upgrade to the compiler may
result in a program which no longer works the same.

Quote:>#include <stdlib.h>
>#include <stdio.h>
>#include <string.h>
>#include <unistd.h>
>#include <sys/mman.h>

>int main()
>{
>  mmap(NULL,getpagesize(),PROT_READ|PROT_WRITE,
>       MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS,0,0);
>  sprintf(NULL,"%s %s!\n","Hello","world");
>  write(0,NULL,strlen(NULL));
>  return 0;
>}

--
Floyd L. Davidson         <http://www.ptialaska.net/~floyd>

 
 
 

stat function segmentation fault

Post by Robert J. Hanse » Sat, 29 Dec 2001 10:47:58


Quote:>> dereference memory location NULL, which will always, always, segfault
>> your system.

> Actually not always, you could make NULL a valid pointer by mmaping
> something on that address. (But that is so rarely needed that you
> shouldn't even think about it, and it will also make debugging harder.)

Kasper, you've just hurt my brain by suggesting something that
braindamaged.  I'm going to stagger off and try to forget you mentioned
this.  :)
 
 
 

stat function segmentation fault

Post by John Hasle » Sat, 29 Dec 2001 11:35:08


Quote:Attribution Lost writes:
> dereference memory location NULL, which will always, always, segfault
> your system.

It didn't on the Onyx.  Lots of bugs appeared as a result when Xanadu was
ported from the Onyx to the Sun.
--
John Hasler

Dancing Horse Hill
Elmwood, WI
 
 
 

stat function segmentation fault

Post by Kasper Dupon » Sat, 29 Dec 2001 18:48:54






> >> > > dereference memory location NULL, which will always, always, segfault your
> >> > > system.

> >> > Actually not always, you could make NULL a valid pointer by
> >> > mmaping something on that address. (But that is so rarely
> >> > needed that you shouldn't even think about it, and it will
> >> > also make debugging harder.)

> >> I believe the CPU hardware will always trap NULL accesses.  I can't
> >> find anything on it right now, but I remember reading that for IA32
> >> CPUs selector zero is reserved and cannot be used without generating a
> >> fault.

> >Yes, but pointers on i386 Linux only contains the offset
> >not the selector. AFAIK no software on Linux uses selctors
> >except for runing DOS/Windows software. The compiler will
> >not generate code using selectors, by default any Linux
> >program will use the selector set up by the kernel.

> >This program actually works:

> However, if it works it is totally an accident.

How can a working program be an accident?

Quote:

> You've invoked undefined behavior as far as the C compiler is
> concerned.  The reason is because NULL is guaranteed to generate
> a "null pointer", which the C Standard guarantees to be
> *invalid* as a memory address.  Using NULL as an address for
> mmap() and or later accessing memory via a NULL pointer results
> in undefined behavior.

It is undefined in C and posibly undefined in Posix as
well. But it is well defined on Linux. This works on any
Linux system, but it is not portable to other systems.

Using the MAP_FIXED flag to mmap is rarely a good idea
and is never portable. And as I already said, you should
not mmap a page on address NULL unless you really need
to, it makes debuging harder.

Quote:

> That behavior on your particular system might result in what
> appears to be the exact result you expected... but on another
> system it may cause the traditional "format your hard disk" or
> "demons to fly out your nose" actions used to explain what
> "undefined behavior" means.

No, some of that cannot happen. Linux has a security
model so a program runing as a nonpriveleged user
cannot format the hardisk even by doing something
undefined.

Quote:

> Even on your system the next upgrade to the compiler may
> result in a program which no longer works the same.

Another compiler should also call the library functions
with the parameters i specify. But of course changing
the libraries might have an effect. mmap and write are
simple wrappers, and you shouldn't expect them to do
anything but passing the arguments to the system call.

But of course somebody might come up with the idea that
sprintf and strlen should detect NULL pointers.

- Show quoted text -

> >#include <stdlib.h>
> >#include <stdio.h>
> >#include <string.h>
> >#include <unistd.h>
> >#include <sys/mman.h>

> >int main()
> >{
> >  mmap(NULL,getpagesize(),PROT_READ|PROT_WRITE,
> >       MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS,0,0);
> >  sprintf(NULL,"%s %s!\n","Hello","world");
> >  write(0,NULL,strlen(NULL));
> >  return 0;
> >}

> --
> Floyd L. Davidson         <http://www.ptialaska.net/~floyd>


--
Kasper Dupont

 Notice: By sending SPAM (UCE/BCE) to this address, you are
accepting and agreeing to our charging a $1000 fee, per
email, for handling and processing, and you agree to pay any
and all costs for collecting this fee.

 
 
 

stat function segmentation fault

Post by Kasper Dupon » Sat, 29 Dec 2001 19:02:39



> >> dereference memory location NULL, which will always, always, segfault
> >> your system.

> > Actually not always, you could make NULL a valid pointer by mmaping
> > something on that address. (But that is so rarely needed that you
> > shouldn't even think about it, and it will also make debugging harder.)

> Kasper, you've just hurt my brain by suggesting something that
> braindamaged.  I'm going to stagger off and try to forget you mentioned
> this.  :)

Actually you sometimes need to map something on that address.
But it is very rarely needed. If you want to use the vm86
syscall on Linux you also need to have memory mapped on
address 0.

--
Kasper Dupont

 Notice: By sending SPAM (UCE/BCE) to this address, you are
accepting and agreeing to our charging a $1000 fee, per
email, for handling and processing, and you agree to pay any
and all costs for collecting this fee.

 
 
 

stat function segmentation fault

Post by Floyd Davidso » Sat, 29 Dec 2001 19:57:49



>> Even on your system the next upgrade to the compiler may
>> result in a program which no longer works the same.

>Another compiler should also call the library functions
>with the parameters i specify. But of course changing
>the libraries might have an effect. mmap and write are
>simple wrappers, and you shouldn't expect them to do
>anything but passing the arguments to the system call.

>But of course somebody might come up with the idea that
>sprintf and strlen should detect NULL pointers.

That _would_ be specific to the library.  But my point was that
the compiler could indeed change and cause your example program
to fail.  And it is a valid point too!

You are assuming that the bit pattern for a null pointer is the
address 0, with all bits 0.  The compiler might be implemented
differently in its next incarnation, and your program will fail
to accomplish the same thing it did previously.

--
Floyd L. Davidson         <http://www.ptialaska.net/~floyd>

 
 
 

stat function segmentation fault

Post by Robert J. Hanse » Sun, 30 Dec 2001 10:48:32


Quote:> 0, with all bits 0.  The compiler might be implemented differently in
> its next incarnation, and your program will fail to accomplish the same

IIRC, back when I was writing code on Apple IIgs machines, the C NULL was
defined to be -1.  So your point is definitely not a purely academic
one--there are real-world systems which define non-null NULLs.
 
 
 

1. getservbyport function - Segmentation fault

Hi,

I am trying to write a program that accesses the /proc/net/tcp and /udp
files. I am trying to translate the port numbers to their service names from
the /etc/services file. Each time I run this function, I receive an aborted
message. Here is the code of the function:

void get_service_from_hex(char *strhex, char *proto) {
     struct servent *svcport;
     int portnbr;
     char strtemp[16];
     portnbr = strtol(strhex, NULL, 16);
     setservent(0);
     /* this is to test that the varaibles are available*/
     printf("%s\t %s\t %d\n", strhex, proto, portnbr);

     svcport = getservbyport(portnbr, "tcp");
     strcpy(strtemp,svcport->s_name);
     printf("%s\n", svcport->s_name);
As far as portnbr I have tried the following:
1. Put in the actual value of an integer - failed
2. I have put htons(portnbr) - failed.
3. I have tried just using portnbr - failed.

I am really not sure what I am doing wrong. If anyone has any idea, I would
really appreciate it. I am running a PII333, with 128MBs, RH LINUX 6.1.

Thank you.

2. USB Wireless Recommendations

3. dlsym function causing segmentation fault

4. GTK-config file missing! (?)

5. Compiling *** VIM 5.3 *** Segmentation Fault..what is Seg-Fault..MEM Bounds?

6. SSH2 (Linux)

7. Page Faults/Segmentation Faults??

8. wireless drivers

9. help with kernel stats/page faults needed

10. "Segmentation fault( core dumped ) "<--- sentence is driving me mad!!!!!

11. segmentation fault ?

12. Get "Segmentation fault (core dumped)" but no core file found

13. Segmentation Faults and Bus Errors