C - why should someone copy argv string to a buffer?
Asked Answered
C

4

6

I'm learning about buffer overflows today and I came across many examples of programs which are vulnerable. The thing which makes me curious is, if there is any reason to work with program's arguments like this:

int main(int argc, char *argv[])
{
    char argument_buffer[100];
    strcpy(argument_buffer, argv[1]);

    if(strcmp(argument_buffer, "testArg") == 0)
    {
        printf("Hello!\n");
    }
    // ...
}

Instead of simply:

int main(int argc, char *argv[])
{
    if(strcmp(argv[1], "testArg") == 0)
    {
        printf("Hello!\n");
    }
}

Please notice that I know about cons of strcpy etc. - it's just an example. My question is - is there any true reason for using temporary buffers to store arguments from argv? I assume there isn't any, but therefore I'm curious, why is it present in overflow examples, while in the reality it is never used? Maybe because of pure theory.

Clausius answered 20/4, 2012 at 15:25 Comment(3)
Where exactly do you see this kind of code? Some context might explain why the programmer chose to do this.Composite
Maybe they're going to be modified (by a parser or something) but the original values are needed later in the program.Magnificat
@Composite In several examples in a book. There are simple programs, but every of them in buffer overflows section has this vulnerability. It really seems that there is no reason, but I'm curious if someone has ever met a situation, where it would be a positive.Clausius
M
1

IIRC argv and its contents were not guaranteed to be writable and stable on all platforms, in the old times. C89 / C90 / ANSI-C standarized some of the existing practices. Similar for envp[]. Could also be that the routine of copying was inspired by the absence of memory protection on older platforms (such as MS-DOS). Normally (and nowadays) the OS and/or CRT takes care of copying the args form the caller's memory to the process's private memory arena.

Minsk answered 20/4, 2012 at 15:55 Comment(0)
E
2

One possible real-world example: a program that renames *.foo to *.bar; you'll need both the original file name and a copy of it with the .foo part changed to .bar for the call to rename().

Exemplar answered 20/4, 2012 at 15:42 Comment(0)
Y
1

Some programs prepend filenames with default paths:

void OpenLogFile (const char *fileName) {
  char pathName[256];
  sprintf(pathName, "/var/log/%s", fileName);
  logFd = open(pathName, ...);
  ...
}

int main (int argc, char **argv) {
  ...
  OpenLogFile(argv[i]);
  ...
}

If the entity that invokes the program passes in a name longer than 255-9 or so, sprintf overwrites past the end of pathName, and boom.

Yaya answered 20/4, 2012 at 15:53 Comment(0)
M
1

IIRC argv and its contents were not guaranteed to be writable and stable on all platforms, in the old times. C89 / C90 / ANSI-C standarized some of the existing practices. Similar for envp[]. Could also be that the routine of copying was inspired by the absence of memory protection on older platforms (such as MS-DOS). Normally (and nowadays) the OS and/or CRT takes care of copying the args form the caller's memory to the process's private memory arena.

Minsk answered 20/4, 2012 at 15:55 Comment(0)
S
0

I am not answering this in terms of buffer overflow or security, but am answering strictly on why someone might want to make a copy of argv's contents.

If your program accepts a lot of arguments, like flags that would change execution path or processing mode, you might want to transfer argv's contents either directly to a log file, or store it temporarily in a buffer. If all decisions made on argv's contents occur in main and you still want to log argv's contents, you probably would not need to copy to a buffer.

If you depended on dispatched threads, processes, or even a subroutine making decisions based on the argv contents, you would probably want the argv values placed in a buffer, so you could pass them around.

Edit:

If you are worried about passing around a pointer, copy argv's contents to a fixed size buffer.

Significs answered 20/4, 2012 at 15:36 Comment(4)
OK, but even in multithreading application, it would be more a matter of "better safe than sorry" than a matter of "it has to be done this way, or it won't work", alright? Otherwise argv can be always passed as a pointer.Clausius
I am missing the main point of your question. Are you concerned about security or having access to argv's contents? I suggest your editing your original question to reflect one or the other.Significs
Well, basically my question is that mentioned in the question - why would someone copy argv string to a buffer at all - I mean the reason.Clausius
That's in my answer. The application designer might want to log how the program was called.Significs

© 2022 - 2024 — McMap. All rights reserved.