Thread: Check for read-only ptr vs buffer passed to func

  1. #1
    Old Fashioned
    Join Date
    Nov 2016
    Posts
    127

    Question Check for read-only ptr vs buffer passed to func

    Hello,
    As you probably know, we can pass either a char * pointing to read-only memory OR an address of a BUFFER which points to modifiable memory into a function whose signature is like this:

    Code:
    void my_function(char* str1, char str2[]);
    For example, we could do this:

    Code:
    char* name = "Jimmy";
    char name2[] = "Zero";
    Of course we cannot do name[3] = 'A' because we're pointing to read-only memory, but we can do name2[3] = 'A' because we're pointing to a buffer in a r/w section of memory.

    But we can also do this:
    Code:
    my_function(name2, name);
    Even if the author of my_function intended str2 to be the address of a buffer which is modifiable.

    So the question is, when we define my_function, is there anyway to inside of the function definition, check to see whether or not the passed-in arguments point to read-only or modifiable/buffer memory? Thank you.
    If I was homeless and jobless, I would take my laptop to a wifi source and write C for fun all day. It's the same thing I enjoy now!

  2. #2
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,611
    Normally read only pointers are marked const, and that is how you know.

    For instance,
    Code:
    char * strcpy(char *dest, const char *source);
    From the signature we can tell that dest is completely modifiable. Edit the characters this points to, change the address the pointer points to... it's all fine. We can also tell that the source is not completely modifiable, the characters cannot be changed.

    In this way, you mark things read only. const int *const pointer; is even more locked down. You cannot change the address or the int value. These same rules apply for more complicated layers of indirection as well, like int **ptr; or int ***ptr; the sky is the limit really.

  3. #3
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,456
    Just one thing. The function declaration
    Code:
    void my_function(char* str1, char str2[]);
    Is exactly the same as
    Code:
    void my_function(char* str1, char* str2);
    There is no difference in semantics as suggested in the first paragraph of the first post.

  4. #4
    Registered User
    Join Date
    Jun 2017
    Posts
    88
    After reading this question I remembered that string literals are stored in a different section of memory, so I began to wonder if the memory location could be deciphered for a variable which might give a clue to this. While this kind of thing is beyond me, I think I did find something interesting. The following is an excerpt I found from a stackoverflow post that deals with a similar question. Unfortunately I don't use linux so I don't recognize the linux commands.
    Code:
    #include <stdio.h>
    
    int main() {
        char *s = "abc";
        printf("%s\n", s);
        return 0;
    }
    Compile and decompile:

    gcc -ggdb -std=c99 -c main.c
    objdump -Sr main.o

    Output contains:
    char *s = "abc";
    8: 48 c7 45 f8 00 00 00 movq $0x0,-0x8(%rbp)
    f: 00
    c: R_X86_64_32S .rodata

    So the string is stored in the .rodata section.

    Then:
    readelf -l a.out
    Contains (simplified):

    Program Headers:
    Type Offset VirtAddr PhysAddr
    FileSiz MemSiz Flags Align
    [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
    LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000
    0x0000000000000704 0x0000000000000704 R E 200000

    Section to Segment mapping:
    Segment Sections...
    02 .text .rodata

    This means that the default linker script dumps both .text and .rodata into a segment that can be executed but not modified (Flags = R E). Attempting to modify such a segment leads to a segfault in Linux.

    -Ciro Santilli
    Of course this is supposed to vary by platform, but it is interesting anyway.

    ----------
    So it seems that by doing an object dump you can find out where it is stored which would give you what kind of variable it is right? .rodata for linux, .rdata for windows? Could this data be loaded into the C compiler and parsed?
    Last edited by jack jordan; 11-02-2017 at 11:07 PM.

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    37,490
    Not in any portable way.

    On *IX compatible operating systems, you could wrap a signal handler to trap segfaults around the attempt to write to the memory.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    656
    In my opinion it's better to catch these types of errors at compile time:

    Code:
    const char* name = "Jimmy";
    Always use "const" when you declare a pointer to read-only memory, such as a string literal. Then the compiler will warn you that you can't pass it to a function that takes a pointer to non-const char.

    If a function doesn't modify the string, put a "const" on the parameter:

    Code:
    void my_function(char* str1, const char* str2);
    That tells the function's callers that it's safe to pass a read-only string to the function.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Win API serial communication - how to check buffer is empty?
    By mr_monster in forum Windows Programming
    Replies: 3
    Last Post: 12-03-2012, 04:07 AM
  2. a way to check if anything is in the buffer...
    By Ash1981 in forum C Programming
    Replies: 2
    Last Post: 01-13-2006, 01:43 AM
  3. Replies: 4
    Last Post: 09-23-2005, 10:51 AM
  4. how to check if a argument passed is integer
    By powinda in forum C Programming
    Replies: 7
    Last Post: 03-07-2004, 05:26 PM

Tags for this Thread