3
int main(int argc,char* argv[]);

If there's a '\0' character in A, will it be split into 2 arguments ?

./programe "A"

I can't reproduce it easily as I can't put an '\0' into A,but there might be someone who can.

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
Je Rog
  • 5,675
  • 8
  • 39
  • 47
  • 2
    You can't? `./programe $'A\0B'` – Ignacio Vazquez-Abrams Jul 03 '11 at 02:41
  • Is this a concern for security reasons? – David Grayson Jul 03 '11 at 02:42
  • @Ignacio Vazquez-Abrams ,how does `$'A\0B' ` work here? – Je Rog Jul 03 '11 at 04:51
  • bash interprets escape sequences within `$'...'`. – Ignacio Vazquez-Abrams Jul 03 '11 at 04:58
  • 1
    It doesn't - or it does and it doesn't. I have a program, `al`, which prints its arguments one per line (instead of space-separated on a single line like `echo`). In Bash, `al $'a\0b'` generates just `a` as output. You'll have to look in the Bash manual for the exact meaning of `$'...'`, same as I will. I found that `al "a\0b"` produced `a\0b` as output, to my not very big surprise. So, even though the `$'a\0b' notation includes a null in the string, the `execve()` system call stops copying the argument at the first null, so the hard work achieved nothing useful. – Jonathan Leffler Jul 03 '11 at 05:04
  • @Jonathan Leffler,seems not the case,`argc` is `3` in this case: `./argc $'A\0B' 2n` – Je Rog Jul 03 '11 at 12:32
  • I realized that my original `al` is not convincing (to me); it would stop at the null in the argument. So, I wrote this instead: `#include int main(int argc, char **argv) { for (int i = 0; i < argc; i++) { for (int j = 0; j < 4; j++) printf("%d %c;", argv[i][j], argv[i][j]); putchar('\n'); } return 0; }` and (on MacOS X 10.6.8, GCC 4.6.0) when invoked as `./xx $'a\0b'`, it gives two lines: `46 .;47 /;120 x;120 x; ` (the command name), and `97 a;0 ;77 M;65 A;`. The `MA` is the start of the first environment variable. There was only one argument, and it did not contain `\0`. – Jonathan Leffler Jul 03 '11 at 14:54
  • @Jonathan Leffler ,I mean it will be therre if you append another argument after `./xx $'a\0b'` – Je Rog Jul 03 '11 at 15:24
  • Output from `./xx $'a\0b' z z` is: (1) `46 .;47 /;120 x;120 x;` (2) `97 a;0 ;122 z;0 ;` (3) `122 z;0 ;122 z;0 ;` (4) `122 z;0 ;77 M;65 A;`, all on MacOS X 10.6.8. You might get different results on a different platform - you should show them, then. – Jonathan Leffler Jul 03 '11 at 16:56

1 Answers1

9

Parameters are passed into programs as C strings; in particular, the execve() syscall (lowest level visible to programs and generally ether very close to or identical to the kernel API) uses C strings, so it is not possible to pass \0 within a parameter. Note that, while the usual way the parameter vector is passed into the process's address space by the kernel is contiguous, so that an embedded \0 would indeed split a parameter, the low level exec() interface uses a list of (char *)s, so an embedded \0 would simply terminate the parameter early.

geekosaur
  • 59,309
  • 11
  • 123
  • 114
  • All of the strings seem by main are null-terminated anyway. There is no way of passing '\0' because there is no way of identifying that situation from the normal case. – davep Jul 03 '11 at 15:50