summaryrefslogtreecommitdiff
path: root/content/projects
diff options
context:
space:
mode:
Diffstat (limited to 'content/projects')
-rw-r--r--content/projects/C_environ.md72
1 files changed, 72 insertions, 0 deletions
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 <stdio.h>
+#include <stdlib.h>
+
+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 <stdio.h>
+#include <string.h>
+
+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 <stdio.h>
+#include <string.h>
+
+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.
+