{"componentChunkName":"component---src-templates-post-template-js","path":"/clang-envp-en","result":{"data":{"markdownRemark":{"id":"1c3901c2-190c-5380-b114-8a17007dc228","html":"<blockquote>\n<p>This page has been machine-translated from the <a href=\"/clang-envp\">original page</a>.</p>\n</blockquote>\n<h2 id=\"about-the-third-argument-envp-of-the-c-main-function\" style=\"position:relative;\"><a href=\"#about-the-third-argument-envp-of-the-c-main-function\" aria-label=\"about the third argument envp of the c main function permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>About the third argument <code class=\"language-text\">*envp[]</code> of the C <code class=\"language-text\">main</code> function</h2>\n<p>This time, I will summarize the third argument that can be used when defining the <code class=\"language-text\">main</code> function in C.</p>\n<p>The other day, while looking at the decompiled output from a certain CTF, I came across a <code class=\"language-text\">main</code> function that takes three arguments, like <code class=\"language-text\">int main(int argc, char *argv[], char *envp[])</code>.</p>\n<p>This third environment-variable argument, <code class=\"language-text\">*envp[]</code>, is defined as follows in the C standard, and it seems to store pointers to the environment variables in the execution environment.</p>\n<blockquote>\n<p>In a hosted environment, the <code class=\"language-text\">main</code> function takes a third argument, <code class=\"language-text\">char *envp[]</code>.</p>\n<p>This argument points to a null-terminated array of pointers to <code class=\"language-text\">char</code>. Each pointer to <code class=\"language-text\">char</code> points to a string that provides information about the environment in which the program is executed.</p>\n</blockquote>\n<p>The <code class=\"language-text\">main</code> function you usually see in C takes the following two arguments.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;stdio.h></span></span>\n\n<span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> argc<span class=\"token punctuation\">,</span> <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>argv<span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">printf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"%d\\n\"</span><span class=\"token punctuation\">,</span> argc<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">while</span><span class=\"token punctuation\">(</span><span class=\"token operator\">*</span>argv<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">{</span>\n        <span class=\"token function\">printf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"%s\\n\"</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">*</span>argv<span class=\"token operator\">++</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>These are, respectively, the following arguments.</p>\n<ul>\n<li>argc : Number of arguments</li>\n<li>*argv[] : Pointers to the arguments passed at execution time</li>\n</ul>\n<p>If you actually compile this source code into an executable named <code class=\"language-text\">test.o</code> and run it, you get the following output.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">$ ./test.o arg1 arg2 arg2\n<span class=\"token number\">4</span>\n./test.o\narg1\narg2\narg2</code></pre></div>\n<p>Now, take a look at the following <code class=\"language-text\">main</code> function, which takes a third argument, <code class=\"language-text\">*envp[]</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;stdio.h></span></span>\n\n<span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> argc<span class=\"token punctuation\">,</span> <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>argv<span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>envp<span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">while</span><span class=\"token punctuation\">(</span><span class=\"token operator\">*</span>envp<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">{</span>\n        <span class=\"token function\">printf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"%s\\n\"</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">*</span>envp<span class=\"token operator\">++</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>When you run this code, every environment variable is printed one per line.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">$ ./test.o \n<span class=\"token assign-left variable\"><span class=\"token environment constant\">SHELL</span></span><span class=\"token operator\">=</span>/bin/bash\n<span class=\"token assign-left variable\"><span class=\"token environment constant\">SESSION_MANAGER</span></span><span class=\"token operator\">=</span>local/parrot:@/tmp/.ICE-unix/1393,unix/parrot:/tmp/.ICE-unix/1393\n<span class=\"token punctuation\">{</span><span class=\"token punctuation\">{</span> omitted <span class=\"token punctuation\">}</span><span class=\"token punctuation\">}</span>\n<span class=\"token assign-left variable\"><span class=\"token environment constant\">PATH</span></span><span class=\"token operator\">=</span>/home/parrot/.local/bin:/snap/bin\n<span class=\"token assign-left variable\"><span class=\"token environment constant\">DBUS_SESSION_BUS_ADDRESS</span></span><span class=\"token operator\">=</span>unix:path<span class=\"token operator\">=</span>/run/user/1000/bus\n<span class=\"token assign-left variable\"><span class=\"token environment constant\">UID</span></span><span class=\"token operator\">=</span><span class=\"token number\">1000</span>\n<span class=\"token assign-left variable\">QT_SCALE_FACTOR</span><span class=\"token operator\">=</span><span class=\"token number\">1</span>\n<span class=\"token assign-left variable\">_</span><span class=\"token operator\">=</span>./test.o\n<span class=\"token assign-left variable\"><span class=\"token environment constant\">OLDPWD</span></span><span class=\"token operator\">=</span>/home/parrot</code></pre></div>\n<p>This is equivalent to the output you get by running the <code class=\"language-text\">env</code> command.</p>\n<p>By the way, if you ignore all environment variables with <code class=\"language-text\">env -i</code>, explicitly set an environment variable named <code class=\"language-text\">Test=Test</code> at execution time, and then run it, only <code class=\"language-text\">Test=Test</code> is printed.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">$ <span class=\"token function\">env</span> -i <span class=\"token assign-left variable\">Test</span><span class=\"token operator\">=</span>Test ./test.o \n<span class=\"token assign-left variable\">Test</span><span class=\"token operator\">=</span>Test</code></pre></div>\n<p>From this, you can see that the third argument <code class=\"language-text\">*envp[]</code> is an argument for retrieving the environment variables of the environment in which the program is executed.</p>\n<h2 id=\"envp-in-secure-coding\" style=\"position:relative;\"><a href=\"#envp-in-secure-coding\" aria-label=\"envp in secure coding permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code class=\"language-text\">*envp[]</code> in secure coding</h2>\n<p>While looking into the third argument <code class=\"language-text\">*envp[]</code>, I found an interesting article.</p>\n<blockquote>\n<p>If the environment is modified in some way, the environment’s memory area may be reallocated, and as a result <code class=\"language-text\">envp</code> may end up pointing to the wrong location.</p>\n<p>Reference: <a href=\"https://www.jpcert.or.jp/sc-rules/c-env31-c.html\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">ENV31-C. Do not reference an environment pointer following an operation that may invalidate it</a></p>\n</blockquote>\n<p>As the JPCERT/CC article above explains, if the environment variables are modified in some way after the program starts, the memory area used by <code class=\"language-text\">*envp[]</code> to refer to the environment variables is reallocated.</p>\n<p>In other words, if you change the environment in some way and then use the pointer from the third argument <code class=\"language-text\">*envp[]</code>, it may cause problems.</p>\n<p>Based on the above, when using environment variables inside a program, it seems recommended to use <code class=\"language-text\">extern char **environ;</code> on Linux, or <code class=\"language-text\">_CRTIMP extern char **_environ;</code> on Windows, if those are defined.</p>\n<h2 id=\"summary\" style=\"position:relative;\"><a href=\"#summary\" aria-label=\"summary permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Summary</h2>\n<p>This was the first time I had learned about this feature, so I went back and reread <a href=\"https://amzn.to/3wlYyLJ\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Even Cats Can Understand C Programming</a>, which is personally my favorite introductory C book. However, the section on <code class=\"language-text\">main</code> function arguments only discussed <code class=\"language-text\">argc</code> and <code class=\"language-text\">*argv[]</code>, and did not mention the third argument <code class=\"language-text\">*envp[]</code> at all.</p>\n<p>Maybe it is a slightly niche feature that does not show up at the beginner-book level.</p>\n<h3 id=\"update-july-7-2021\" style=\"position:relative;\"><a href=\"#update-july-7-2021\" aria-label=\"update july 7 2021 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Update (July 7, 2021)</h3>\n<p>In fact, <a href=\"http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">J.5 Common extensions</a>, which defines the third environment-variable argument <code class=\"language-text\">*envp[]</code>, is not strictly part of the C language specification itself, but is defined as an extension, so it does not seem to be portable across all implementations.</p>\n<p>There are still parts I do not fully understand, but it seems my understanding that this was part of “the C language specification” was incorrect.</p>","fields":{"slug":"/clang-envp-en","tagSlugs":["/tag/c-en/","/tag/english/"]},"frontmatter":{"date":"2021-10-01","description":"This article explains the third argument that can be used when defining the `main` function in C.","tags":["C (en)","English"],"title":"Using the third argument *envp[] of the main function to read environment variables","socialImage":{"publicURL":"/static/dc4d8b7f8795f3c3d3489d9957d155f2/no-image.png"}}}},"pageContext":{"slug":"/clang-envp-en"}},"staticQueryHashes":["251939775","401334301","825871152"]}