Writing to text segment

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • rahul

    #1

    Writing to text segment

    void foo(void) {
    /* blah blah */
    }

    char buf[] = {....};
    memcpy( (void *)&foo, buf, sizeof buf);

    This thing is giving segmentation fault on RHEL 5/gcc 4.1. Is the text
    segment protected? I am assuming foo has enough space for buf.
  • Ian Collins

    #2
    Re: Writing to text segment

    rahul wrote:
    void foo(void) {
    /* blah blah */
    }
    >
    char buf[] = {....};
    memcpy( (void *)&foo, buf, sizeof buf);
    >
    This thing is giving segmentation fault on RHEL 5/gcc 4.1. Is the text
    segment protected? I am assuming foo has enough space for buf.
    I'm amazed you even managed to get it, what ever it is, to compile.

    Post real code.

    --
    Ian Collins.

    Comment

    • Antoninus Twink

      #3
      Re: Writing to text segment

      On 10 Jun 2008 at 8:29, rahul wrote:
      This thing is giving segmentation fault on RHEL 5/gcc 4.1. Is the text
      segment protected?
      $ objdump -h a

      a: file format elf32-i386

      Sections:
      Idx Name Size VMA LMA File off Algn
      [snip]
      12 .text 0000016c 080482f0 080482f0 000002f0 2**4
      CONTENTS, ALLOC, LOAD, READONLY, CODE
      [snip]

      Yes, on sane operating systems the text segment does seem to be
      read-only. Maybe your hacking attempts will fare better on Windows.

      Comment

      • Jens Thoms Toerring

        #4
        Re: Writing to text segment

        rahul <rahulsinner@gm ail.comwrote:
        void foo(void) {
        /* blah blah */
        }
        char buf[] = {....};
        memcpy( (void *)&foo, buf, sizeof buf);
        This thing is giving segmentation fault on RHEL 5/gcc 4.1. Is the text
        segment protected? I am assuming foo has enough space for buf.
        It invokes undefined behaviour by trying to write to memory you
        don't own (the code for your program belong into this category).
        (And a conversion between function and object pointers is also
        not an operation defined by the C standard). One possible result
        is that you get a segmentation fault. On a different system it
        may work. So the answer is system-specific and thus better be
        discussed in the appropriate group.

        And yes, protecting the code from getting overwritten is usually
        a good thing since it safes you from your worst mistakes. Self-
        mofifying code inherently makes your program unportable and
        thus system-specific, so it's reasonable not to bless it with
        some special permission in the C standard. If it's possible on
        a system let the implementation define the undefined behaviour.

        Regards, Jens
        --
        \ Jens Thoms Toerring ___ jt@toerring.de
        \______________ ____________ http://toerring.de

        Comment

        • rahul

          #5
          Re: Writing to text segment

          On Jun 10, 2:11 pm, Ian Collins <ian-n...@hotmail.co mwrote:
          rahul wrote:
          void foo(void) {
          /* blah blah */
          }
          >
          char buf[] = {....};
          memcpy( (void *)&foo, buf, sizeof buf);
          >
          This thing is giving segmentation fault on RHEL 5/gcc 4.1. Is the text
          segment protected? I am assuming foo has enough space for buf.
          >
          I'm amazed you even managed to get it, what ever it is, to compile.
          >
          Post real code.
          >
          --
          Ian Collins.
          The code is real, just abridged. Would you elaborate why this should
          not compile?

          Comment

          • rahul

            #6
            Re: Writing to text segment

            On Jun 10, 3:17 pm, Antoninus Twink <nos...@nospam. invalidwrote:
            On 10 Jun 2008 at 8:29, rahul wrote:
            >
            This thing is giving segmentation fault on RHEL 5/gcc 4.1. Is the text
            segment protected?
            >
            $ objdump -h a
            >
            a: file format elf32-i386
            >
            Sections:
            Idx Name Size VMA LMA File off Algn
            [snip]
            12 .text 0000016c 080482f0 080482f0 000002f0 2**4
            CONTENTS, ALLOC, LOAD, READONLY, CODE
            [snip]
            >
            Yes, on sane operating systems the text segment does seem to be
            read-only. Maybe your hacking attempts will fare better on Windows.
            Yup, objdump says .text is read only. Actually execution in .data
            segment
            generates fault in almost all architectures I have seen (including
            Windows XP
            ;starting from SP2 - its called Data Execution Prevention). So, I
            thought
            may be self-modifying code can do the trick.

            Comment

            • santosh

              #7
              Re: Writing to text segment

              rahul wrote:
              On Jun 10, 2:11 pm, Ian Collins <ian-n...@hotmail.co mwrote:
              >rahul wrote:
              void foo(void) {
              /* blah blah */
              }
              >>
              char buf[] = {....};
              memcpy( (void *)&foo, buf, sizeof buf);
              >>
              This thing is giving segmentation fault on RHEL 5/gcc 4.1. Is the
              text segment protected? I am assuming foo has enough space for buf.
              >>
              >I'm amazed you even managed to get it, what ever it is, to compile.
              >>
              >Post real code.
              The code is real, just abridged. Would you elaborate why this should
              not compile?
              Because it won't compile?

              For short programs (especially when the OP does not know the exact place
              where the bug first occurs), this group generally prefers a complete,
              compilable program to be posted. This way the regulars can compile it
              themselves; compiler diagnostics are a great help in troubleshooting .
              Except it a minority of cases, it's very hard to pinpoint errors from
              isolated code fragments, unless fortuitously, the error just happens to
              be within the fragment. Even in that case the actual observed bug may
              have been caused by other errors upstream.

              Comment

              • rahul

                #8
                Re: Writing to text segment

                On Jun 10, 6:05 pm, santosh <santosh....@gm ail.comwrote:
                rahul wrote:
                On Jun 10, 2:11 pm, Ian Collins <ian-n...@hotmail.co mwrote:
                rahul wrote:
                void foo(void) {
                /* blah blah */
                }
                >
                char buf[] = {....};
                memcpy( (void *)&foo, buf, sizeof buf);
                >
                This thing is giving segmentation fault on RHEL 5/gcc 4.1. Is the
                text segment protected? I am assuming foo has enough space for buf.
                >
                I'm amazed you even managed to get it, what ever it is, to compile.
                >
                Post real code.
                The code is real, just abridged. Would you elaborate why this should
                not compile?
                >
                Because it won't compile?
                >
                For short programs (especially when the OP does not know the exact place
                where the bug first occurs), this group generally prefers a complete,
                compilable program to be posted. This way the regulars can compile it
                themselves; compiler diagnostics are a great help in troubleshooting .
                Except it a minority of cases, it's very hard to pinpoint errors from
                isolated code fragments, unless fortuitously, the error just happens to
                be within the fragment. Even in that case the actual observed bug may
                have been caused by other errors upstream.

                /* BEGIN bar.c */
                #include <stdio.h>
                #include <stdlib.h>
                #include <string.h>

                #define SIZE 100

                /* Just allocating enough space for copying */
                int
                bar (void) {
                volatile int i = 1;
                i = 2;
                i = 3;
                i = 4;
                i = 5;
                i = 6;
                return i;
                }

                int
                main (void) {
                int fd = fopen ("foo.o", O_RDONLY);
                int nread = 0;
                int ret;
                char buf[SIZE];
                nread = read (fd, buf, SIZE);
                memcpy ( (void *)&bar, (void *)buf, SIZE);
                ret = bar();
                return 0;
                }

                /* BEGIN foo.c */
                int
                foo (void) {
                return 1;
                }
                /* foo.c compiled as Position Independent Code */

                Is it good enough for you? This thing is just the skeleton of the real
                code.

                My problem was not related to compiling or running the program. My
                question was about
                the behavior as per standards when one writes to .text segment. I
                already have got the answer.
                ..text is read-only ( at least in linux).
                And can you tell me now why it is not supposed to compile?

                Comment

                • Ian Collins

                  #9
                  Re: Writing to text segment

                  rahul wrote:
                  On Jun 10, 6:05 pm, santosh <santosh....@gm ail.comwrote:
                  >rahul wrote:
                  >>On Jun 10, 2:11 pm, Ian Collins <ian-n...@hotmail.co mwrote:
                  >>>rahul wrote:
                  >>>>void foo(void) {
                  >>>> /* blah blah */
                  >>>>}
                  >>>>char buf[] = {....};
                  >>>>memcpy( (void *)&foo, buf, sizeof buf);
                  >>>>This thing is giving segmentation fault on RHEL 5/gcc 4.1. Is the
                  >>>>text segment protected? I am assuming foo has enough space for buf.
                  >>>I'm amazed you even managed to get it, what ever it is, to compile.
                  >>>Post real code.
                  >>The code is real, just abridged. Would you elaborate why this should
                  >>not compile?
                  >Because it won't compile?
                  >>
                  >For short programs (especially when the OP does not know the exact place
                  >where the bug first occurs), this group generally prefers a complete,
                  >compilable program to be posted. This way the regulars can compile it
                  >themselves; compiler diagnostics are a great help in troubleshooting .
                  >Except it a minority of cases, it's very hard to pinpoint errors from
                  >isolated code fragments, unless fortuitously, the error just happens to
                  >be within the fragment. Even in that case the actual observed bug may
                  >have been caused by other errors upstream.
                  >
                  >
                  /* BEGIN bar.c */
                  #include <stdio.h>
                  #include <stdlib.h>
                  #include <string.h>
                  >
                  #define SIZE 100
                  >
                  /* Just allocating enough space for copying */
                  int
                  bar (void) {
                  volatile int i = 1;
                  i = 2;
                  i = 3;
                  i = 4;
                  i = 5;
                  i = 6;
                  return i;
                  }
                  >
                  int
                  main (void) {
                  int fd = fopen ("foo.o", O_RDONLY);
                  int nread = 0;
                  int ret;
                  char buf[SIZE];
                  nread = read (fd, buf, SIZE);
                  memcpy ( (void *)&bar, (void *)buf, SIZE);
                  ret = bar();
                  return 0;
                  }
                  >
                  /* BEGIN foo.c */
                  int
                  foo (void) {
                  return 1;
                  }
                  /* foo.c compiled as Position Independent Code */
                  >
                  Is it good enough for you? This thing is just the skeleton of the real
                  code.
                  >
                  No, try again.

                  x.c: In function 'main':
                  x.c:21: error: 'O_RDONLY' undeclared (first use in this function)
                  x.c:21: error: (Each undeclared identifier is reported only once
                  x.c:21: error: for each function it appears in.)
                  x.c:21: warning: initialization makes integer from pointer without a cast
                  x.c:25: warning: implicit declaration of function 'read'
                  x.c:26: warning: ISO C forbids conversion of function pointer to object
                  pointer type
                  My problem was not related to compiling or running the program. My
                  question was about
                  the behavior as per standards when one writes to .text segment. I
                  already have got the answer.
                  The behaviour is undefined, the standard makes no mention of .text
                  segments, or any other segment.

                  --
                  Ian Collins.

                  Comment

                  • pete

                    #10
                    Re: Writing to text segment

                    rahul wrote:
                    On Jun 10, 6:05 pm, santosh <santosh....@gm ail.comwrote:
                    >rahul wrote:
                    >>On Jun 10, 2:11 pm, Ian Collins <ian-n...@hotmail.co mwrote:
                    >>>rahul wrote:
                    >>>>void foo(void) {
                    >>>> /* blah blah */
                    >>>>}
                    >>>>char buf[] = {....};
                    >>>>memcpy( (void *)&foo, buf, sizeof buf);
                    >>>>This thing is giving segmentation fault on RHEL 5/gcc 4.1. Is the
                    >>>>text segment protected? I am assuming foo has enough space for buf.
                    >>>I'm amazed you even managed to get it, what ever it is, to compile.
                    >>>Post real code.
                    >>The code is real, just abridged. Would you elaborate why this should
                    >>not compile?
                    >Because it won't compile?
                    >>
                    >For short programs (especially when the OP does not know the exact place
                    >where the bug first occurs), this group generally prefers a complete,
                    >compilable program to be posted. This way the regulars can compile it
                    >themselves; compiler diagnostics are a great help in troubleshooting .
                    >Except it a minority of cases, it's very hard to pinpoint errors from
                    >isolated code fragments, unless fortuitously, the error just happens to
                    >be within the fragment. Even in that case the actual observed bug may
                    >have been caused by other errors upstream.
                    >
                    >
                    /* BEGIN bar.c */
                    #include <stdio.h>
                    #include <stdlib.h>
                    #include <string.h>
                    >
                    #define SIZE 100
                    >
                    /* Just allocating enough space for copying */
                    int
                    bar (void) {
                    volatile int i = 1;
                    i = 2;
                    i = 3;
                    i = 4;
                    i = 5;
                    i = 6;
                    return i;
                    }
                    >
                    int
                    main (void) {
                    int fd = fopen ("foo.o", O_RDONLY);
                    fd is the wrong type.

                    FILE *fopen(const char * filename, const char * mode);

                    O_RDONLY isn't a portable macro. I don't have it.
                    int nread = 0;
                    int ret;
                    char buf[SIZE];
                    nread = read (fd, buf, SIZE);
                    read() isn't a portable function. I don't have it.
                    memcpy ( (void *)&bar, (void *)buf, SIZE);
                    &bar doesn't point to an object.

                    N869
                    7.21.2 Copying functions
                    7.21.2.1 The memcpy function

                    [#2] The memcpy function copies n characters from the object
                    pointed to by s2 into the object pointed to by s1.

                    ret = bar();
                    return 0;
                    }
                    --
                    pete

                    Comment

                    • rahul

                      #11
                      Re: Writing to text segment

                      On Jun 11, 9:49 am, pete <pfil...@mindsp ring.comwrote:
                      rahul wrote:
                      On Jun 10, 6:05 pm, santosh <santosh....@gm ail.comwrote:
                      rahul wrote:
                      >On Jun 10, 2:11 pm, Ian Collins <ian-n...@hotmail.co mwrote:
                      >>rahul wrote:
                      >>>void foo(void) {
                      >>> /* blah blah */
                      >>>}
                      >>>char buf[] = {....};
                      >>>memcpy( (void *)&foo, buf, sizeof buf);
                      >>>This thing is giving segmentation fault on RHEL 5/gcc 4.1. Is the
                      >>>text segment protected? I am assuming foo has enough space for buf.
                      >>I'm amazed you even managed to get it, what ever it is, to compile.
                      >>Post real code.
                      >The code is real, just abridged. Would you elaborate why this should
                      >not compile?
                      Because it won't compile?
                      >
                      For short programs (especially when the OP does not know the exact place
                      where the bug first occurs), this group generally prefers a complete,
                      compilable program to be posted. This way the regulars can compile it
                      themselves; compiler diagnostics are a great help in troubleshooting .
                      Except it a minority of cases, it's very hard to pinpoint errors from
                      isolated code fragments, unless fortuitously, the error just happens to
                      be within the fragment. Even in that case the actual observed bug may
                      have been caused by other errors upstream.
                      >
                      /* BEGIN bar.c */
                      #include <stdio.h>
                      #include <stdlib.h>
                      #include <string.h>
                      >
                      #define SIZE 100
                      >
                      /* Just allocating enough space for copying */
                      int
                      bar (void) {
                      volatile int i = 1;
                      i = 2;
                      i = 3;
                      i = 4;
                      i = 5;
                      i = 6;
                      return i;
                      }
                      >
                      int
                      main (void) {
                      int fd = fopen ("foo.o", O_RDONLY);
                      >
                      fd is the wrong type.
                      >
                      FILE *fopen(const char * filename, const char * mode);
                      >
                      O_RDONLY isn't a portable macro. I don't have it.
                      >
                      int nread = 0;
                      int ret;
                      char buf[SIZE];
                      nread = read (fd, buf, SIZE);
                      >
                      read() isn't a portable function. I don't have it.
                      >
                      memcpy ( (void *)&bar, (void *)buf, SIZE);
                      >
                      &bar doesn't point to an object.
                      >
                      N869
                      7.21.2 Copying functions
                      7.21.2.1 The memcpy function
                      >
                      [#2] The memcpy function copies n characters from the object
                      pointed to by s2 into the object pointed to by s1.
                      >
                      ret = bar();
                      return 0;
                      }
                      >
                      --
                      pete
                      Folks,
                      I didn't compile this code. I wrote it just like that to make the
                      context clear. Forgot a few headers ,wrote "fopen" instead of "open"
                      and
                      wrote it in GNU C rather than standard C.
                      Anyways, I will mark the code as not tested the next time.

                      So, to conclude, functions aren't objects and that makes memcpy
                      undefined. Apart from that, is there anything about execution part.
                      Say I manually
                      copy the bytes to location pointed by bar and then try to execute it.

                      Comment

                      • Ian Collins

                        #12
                        Re: Writing to text segment

                        rahul wrote:
                        >
                        Folks,
                        I didn't compile this code. I wrote it just like that to make the
                        context clear. Forgot a few headers ,wrote "fopen" instead of "open"
                        and
                        wrote it in GNU C rather than standard C.
                        Anyways, I will mark the code as not tested the next time.
                        >
                        You should know better here in the home of the grumpy old men!
                        So, to conclude, functions aren't objects and that makes memcpy
                        undefined. Apart from that, is there anything about execution part.
                        Say I manually
                        copy the bytes to location pointed by bar and then try to execute it.
                        >
                        Completely undefined.

                        Some systems have code in ROM....

                        Some systems really do have incompatible function and data pointers.

                        --
                        Ian Collins.

                        Comment

                        • Willem

                          #13
                          Re: Writing to text segment

                          Ian wrote:
                          ) rahul wrote:
                          )>
                          )Folks,
                          )I didn't compile this code. I wrote it just like that to make the
                          )context clear. Forgot a few headers ,wrote "fopen" instead of "open"
                          )and
                          )wrote it in GNU C rather than standard C.
                          )Anyways, I will mark the code as not tested the next time.
                          )>
                          ) You should know better here in the home of the grumpy old men!
                          )
                          )So, to conclude, functions aren't objects and that makes memcpy
                          )undefined. Apart from that, is there anything about execution part.
                          )Say I manually
                          )copy the bytes to location pointed by bar and then try to execute it.
                          )>
                          ) Completely undefined.
                          )
                          ) Some systems have code in ROM....
                          )
                          ) Some systems really do have incompatible function and data pointers.

                          Some systems run on C interpreters, instead of compilers.


                          SaSW, Willem
                          --
                          Disclaimer: I am in no way responsible for any of the statements
                          made in the above text. For all I know I might be
                          drugged or something..
                          No I'm not paranoid. You all think I'm paranoid, don't you !
                          #EOT

                          Comment

                          • santosh

                            #14
                            Re: Writing to text segment

                            rahul wrote:

                            <snip>
                            My problem was not related to compiling or running the program. My
                            question was about the behavior as per standards when one writes
                            to .text segment.
                            That's impossible to answer because the standard makes no mention of
                            the ".text" segment or any other segment for that matter. The standard
                            places few constraints on the runtime environment.
                            I already have got the answer. .text is read-only ( at least in
                            linux).
                            Yes. The behaviour of your program will vary with each implementation
                            simply because you are relying on features and guarantees that are
                            beyond standard C. On some systems for example your program will fail
                            to compile. On some systems it may compile but trigger a fault on being
                            run. On yet other systems it will compile and execute successfully. Any
                            other behaviour is also possible.
                            And can you tell me now why it is not supposed to compile?
                            What Ian Collins said won't compile was your _code_ _fragment_ posted
                            earlier. _This_ program may or may not compile. There is no way for us
                            to say, since it invokes undefined behaviour.

                            Comment

                            • Flash Gordon

                              #15
                              Re: Writing to text segment

                              Willem wrote, On 11/06/08 09:36:
                              Ian wrote:
                              ) rahul wrote:
                              )>
                              )Folks,
                              )I didn't compile this code. I wrote it just like that to make the
                              )context clear. Forgot a few headers ,wrote "fopen" instead of "open"
                              )and
                              )wrote it in GNU C rather than standard C.
                              )Anyways, I will mark the code as not tested the next time.
                              )>
                              ) You should know better here in the home of the grumpy old men!
                              )
                              )So, to conclude, functions aren't objects and that makes memcpy
                              )undefined. Apart from that, is there anything about execution part.
                              )Say I manually
                              )copy the bytes to location pointed by bar and then try to execute it.
                              )>
                              ) Completely undefined.
                              )
                              ) Some systems have code in ROM....
                              )
                              ) Some systems really do have incompatible function and data pointers.
                              >
                              Some systems run on C interpreters, instead of compilers.
                              Some systems have completely separate memory spaces for code and data.
                              So if your function foo is at address 0x400 and you try to read address
                              0x400 using a pointer you might get the contents of array bar which just
                              happens to have the same address!

                              The C standard leaves any attempt to convert between function pointers
                              and object (data) pointers undefined, so before you get as far as trying
                              to copy a function or call an array you have to invoke undefined behaviour.

                              I.e. there is absolutely no way to get even vaguely close to what the OP
                              wants without invoking undefined behaviour.

                              I.e. the OP should give up on standard C and go individually to the
                              groups for all the systems of interest and ask in each one how to do
                              what s/he wants.
                              --
                              Flash Gordon

                              Comment

                              Working...