NetBSD-Users archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: Silly shell question
On Tue, 22 Mar 2016, Eric Haszlakiewicz wrote:
The special OS glue/magic that happens is that the kernel takes the list
of environment variables passed to the execve() system call, and copies
them to the stack of the newly executing binary (kern_exec.c if you want
to go look).
Thank you, Eric. Your information is spot-on. Similar to what Manuel and
Johnny gave me. I read quite a bit of source code, yesterday. The key for
me was looking at the args to execve() just like you suggest. However,
there were bits in the bourne shell source that also helped me to
understand how and when the list was unrolled and used by the child shell.
Then, the code that runs before main() (which comes from
crt0.o and automatically gets included in your program when you link)
Ahh, this is low-level and also interesting. I like learning about things
we all take for granted sometimes. I've been coding in C for a while, and
I never even knew about how the linker creates this and that it runs
before main() etc... In the wikipedia page it says 'crt0' stands for "C
runtime" and the zero means "very first!". Neat.
If your program (/bin/sh in this case) calls one of the exec* functions
that don't take an explicit environ pointer, the implementation in libc
(e.g. execl.c) actually calls execve() and passes along the current
environment for you (which is available as the global variable
"environ").
I noticed that in the shell source (var.c and others) that the shell takes
some pretty strict measures on how to unpack all the data that it gets
from the array of character pointers it gets passed as "envp". I'm now
understanding how you could get yourself into a real mess by not taking
great care with sanity checking what you get. It appears to be a bit of a
pain in the butt.
Shell local variables aren't stored in environ at all and aren't passed
along to the execve() call when the shell forks+execs some new process,
they're just arbitrary data that the shell process keeps in its memory
Just for fun I was hunting around in the bourne shell code for what kind
of data structure it uses to store the fact that "hey, this variable has
been exported". I'm guessing it's a linked list of pointer addresses
somewhere signifying "These are special. If you fork() or execve()
something, pass this stuff along." Since they are pointers, the data
changes appropriately as needed without any copies being involved (I'm
guessing).
Actually, there's no reason that the shell needs to store even exported
variables in its own environ global variable either, it just needs to
make sure that it generates an appropriate array of variables when it
starts a new process and calls execve().
Yes, I believe you and from what I'm seeing in the source, that's exactly
what happens. I remember that there used to be some security problems with
'sudo' (and also others with telnet) because it didn't properly sanitize
some of the environment that it accepted from the parent process. Now, I
believe I understand more of the why.
Thanks to everyone who was gracious enough to explain what is probably
really elementary stuff to most of you. I just wanted a "lower level"
understanding of what was going on. Now I have it (or at least enough
hubris to believe I do)!
-Swift
Home |
Main Index |
Thread Index |
Old Index