Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I am using the following in openssh/telnet code, which sets the user environment.

setenv("TEST_ENV", "testing", 1);

But this can be modified by the user, is there anyway to make it readonly env variable?

share|improve this question
Using [t]csh? – jordanm Mar 2 '13 at 6:19
No, I am doing it in openssh code. – Ram Mar 2 '13 at 6:21
Then no, you can't restrict child processes from modifying things in it's own environment. – jordanm Mar 2 '13 at 6:28
The answer is to find a different approach to your problem that doesn't require relying on environment variables for security. That's not their purpose. A configuration file like you mention sounds like a sensible solution. – jordanm Mar 2 '13 at 6:35
What are you trying to achieve? – Johan Mar 2 '13 at 10:15

There's nothing in the conventional process environment to make a variable read only, only shells have that concept for their own environment/variables (the two overlap in ways, but they must be understood as distinct). The same applies for type properties like integer, array, function etc.

Have you considered using a restricted shell, like rbash? You could set rbash up to run readonly TEST_ENV) in its startup script. rbash may be too restrictive though, but it addresses to a good extent the issues raise in the comments.

The environment is a read/write part of each process (see here and here for details), not only can a process write directly to the data part (via environ[]), it can change the pointers to it. You might be able to do something with this (i.e. relocate to a read-only page) if you are proficient in assembly and can find your way around the crt startup code, but I don't recommend it ;-)

If there are specific commands that users run that must have a certain environment you may be able to set only group-execute and use sudo to set the correct variables (e.g. via /etc/environment or env_file directive) and run the command as the specific group (preserving uid). Recent versions support noexec on most platforms which can be used to prevent running a new shell (though can can break programs which legitimately fork() and exec()).

As a last option you may be able to use LD_PRELOAD and your own library to set a controlled environment for some/all user processes by wrapping the relevant libc functions (getenv() putenv() etc.). libfaketime does exactly this for time related libc functions. There's a less well known tool called timetravel that does similar, but also hooks setenv() and getenv() so as to keep control of LD_PRELOAD in the face of adversity.

The most robust approach is to filter the setenv() unsetenv() putenv() (and possibly clearnv()) calls to prevent modification, and filter getenv() so that it always returns the required value (possibly from a file). This approach won't prevent direct manipulation of the environment memory via environ[], but as long as you are in control of getenv() any process which relies on the libc API should see your value. bash uses environ[] directly when it initialises, but also calls getenv().

share|improve this answer

Readonly variables can be set in POSIX compliant shells using the readonly command.

readonly VAR=foo   # POSIX
declare -r VAR=foo # bash
export VAR

This is in no way a security feature to prevent the user from changing it. The user can always spawn a new shell and change the variable.

share|improve this answer
yeah, that is a thing to worry about :( – Ram Mar 2 '13 at 6:33
Note that zsh allows typeset +r VAR to turn the readonly attribute off. – Stéphane Chazelas Mar 2 '13 at 7:48
Also note that AT&T implementations of ksh export the readonly attribute of exported variables to the environment via the A__z special variable, so in a newly started ksh, the variable will still be read-only (though if you have access to env, or perl or any other shell or tool that can modify an environment variable, that won't stop you from doing things like env VAR=new-value ksh – Stéphane Chazelas Mar 2 '13 at 8:20

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.