From c7449631a8355f9dcd17fbc0d536793674d46323 Mon Sep 17 00:00:00 2001 From: eqkter Date: Mon, 29 Apr 2024 23:39:58 +0200 Subject: auto updating site --- content/projects/C_environ.md | 72 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 content/projects/C_environ.md (limited to 'content') diff --git a/content/projects/C_environ.md b/content/projects/C_environ.md new file mode 100644 index 0000000..46bf12f --- /dev/null +++ b/content/projects/C_environ.md @@ -0,0 +1,72 @@ ++++ +title = "C: interaction with shell variables" +date = 2024-04-29 ++++ + +--- +### Fetch shell environment variables through `C` main declaration + +In the last couple of days, we can see people [talking](https://twitter.com/wangzhr4/status/1783775497492529349) about the security aspect of this behaviour. +In `C`, we can in fact easily interact with shell variables with the `char *getenv(const char *name)` standard function: + +```C +#include +#include + +int main(void) +{ + printf("PATH: %s\r\n", getenv("PATH")); + return (0); +} +``` + +But the `C` offers a way to access them directly as passing argument into the main function, just like `**argv`. +The definition of `main` can indeed have 0, 2 or 3 arguments: + +* `int main(void)` +* `int main(int argc, char **argv)` +* `int main(int argc, char **argv, char **envp)` + +The third and option argument is then our way to access shell variables, e.g.: + +```C +#include +#include + +int main(int argc, char **argv, char **envp) +{ + unsigned short timeout = 0; + while ((*envp != NULL) && (timeout++ < (1 << 15))) { + if (strncmp(*(envp++), "PATH", 4) == 0) { + printf("%s\r\n", *(envp - 1)); + return (0); + } + } + printf("Timeout error\r\n"); + return (1); +} +``` + +Note that this third definition of `main` is **not** part of the [C99 Standard](https://www.open-std.org/JTC1/sc22/wg14/www/docs/n1256.pdf) (par. 5.1.2.2.1), making it de facto POSIX-specific though widely supported. +You could however achieve the same result by overflowing the `**argv` parameter: +```C +#include +#include + +int main(int argc, char **argv) +{ + unsigned short timeout = 0; + argv += argc + 1; + while ((*argv != NULL) && (timeout++ < (1 << 15))) { + if (strncmp(*(argv++), "PATH", 4) == 0) { + printf("%s\r\n", *(argv - 1)); + return (0); + } + } + printf("Timeout error\r\n"); + return (1); +} +``` + +You can find many examples and applications of this *new* `main` argument online, sometimes with another name (e.g. `**environ`) as, again, it is not standard. + -- cgit v1.2.3