[mod.std.unix] TZ and TERM per process

std-unix@ut-sally.UUCP (Moderator, John Quarterman) (01/23/86)

[ I don't know if the following suggestion really solves the
problems, but I don't believe anybody has made it before.  -mod ]

From: seismo!philabs!nyit!rick@sally.UTEXAS.EDU (Rick Ace)
Date: Tue, 21 Jan 86 15:51:31 est

Objections to keeping TZ as a UNIX environment object can be
answered by putting the timezone information (to whatever
degree of precision is necessary) in the per-process context
maintained by UNIX, also called the `u.' area.  The kernel
can offer system calls to query or change the TZ of the
calling process.  Upon fork(), the child inherits its
parent's TZ.

The umask(2) syscall provides a precedent for carrying
special OS-related information in the per-process context
maintained by the kernel.  I'm tempted to propose that TERM
information should be kept there too.
-----
Rick Ace
Computer Graphics Laboratory
New York Institute of Technology
Old Westbury, NY  11568
(516) 686-7644

{decvax,seismo}!philabs!nyit!rick

Volume-Number: Volume 0, Number 0

std-unix@ut-sally.UUCP (Moderator, John Quarterman) (01/23/86)

From: pyramid!sun!guy@sally.UTEXAS.EDU (Guy Harris)
Date: Wed, 22 Jan 86 22:02:59 PST

> Objections to keeping TZ as a UNIX environment object can be
> answered by putting the timezone information (to whatever
> degree of precision is necessary) in the per-process context
> maintained by UNIX, also called the `u.' area. ...
> 
> The umask(2) syscall provides a precedent for carrying
> special OS-related information in the per-process context
> maintained by the kernel.  I'm tempted to propose that TERM
> information should be kept there too.

This dates back to PWB/UNIX; they wanted to store some per-process
information (namely, the login name, since PWB/UNIX was originally V6-based
and, given a limit of 256 user IDs, required several people to share a user
ID) and they did so in the u-area.  However, when PWB became V7ized, they
stored it - in the environment.

What benefits accrue from storing this information (timezone or terminal
type) in the u-area instead of in the environment?  This proposal implies
that the information isn't protected, since there would be system calls to
change it, so that's not one of the benefits.  (It has been argued that
terminal type information should be stored with the *terminal*, and not with
the process, so it's not clear that the u-area *or* the environment is the
proper place for this.)  The reason the umask was stored in the u-area is
probably so that programs didn't have to change to be affected by the umask;
in order for it to work with "open", it had to be accessible to the kernel,
and the most logical place for variables like that is the u-area.

The main objections I've seen to storing the time zone in the environment
are that it is subject to forgery and that there's no way to set TZ for
*every* process on the system (and even for those processes where you *can*
set it, current S3/S5 requires you to set it independently in several
places).  If the time zone information is moved from the user-mode
per-process data segment to the kernel-mode per-process data segment, this
doesn't solve the problem of forgery unless the system call to set it is
privileged (in which case it isn't really settable by most processes, so why
is it a per-user item?) and doesn't solve the problem of setting it
initially.

The best solution to both of those problems I originally saw in an article
about mixing V7 and S3 compatibility in Xenix.  Microsoft kept the old V7
"ftime" call, which gets the time zone information from the kernel (which is
set at system build time, or if you have something like an EEPROM on your
machine it can be set at boot time; there is no unprivileged system call to
set it, so it's unforgeable), and had "ctime" fetch the time zone
information from the kernel if there was no TZ environment variable.

This solves the problem of setting it initially, as the default setting is
what most programs would want to use; if a user dials in from another time
zone, the program they run as their shell will have to provide some way for
them to set TZ.  It also solves the problem of forgery, assuming the S5
"putenv" function is present.  Have "ctime" (or anybody else) use the
kernel's timezone value if TZ is present but has a null string as a value,
and have programs that want to be guaranteed to get the "official" time zone,
like "uucico", just do 'putenv("TZ=");' and wipe out the supplied time zone.

Volume-Number: Volume 5, Number 21

std-unix@ut-sally.UUCP (Moderator, John Quarterman) (01/24/86)

>From: decwrl!mips!mash@pyramid.UUCP (John Mashey)
Date: Fri, 24 Jan 86 01:22:08 pst

It was recently suggested here to make TZ & TERM into u_area variables,
with special system calls to tweak them, using umask(2) as precedent.
1) Please don't, at least not without much more thought.
2) Doing umask(2) that way was perhaps a mistake.

Let me shed some light on the history of these things, first recalling
some philosophy that UNIXers are supposed to hold dear:

Nothing goes in the kernel unless it MUST.
Don't add system calls unless you MUST.
Don't add per-process state, unless:
	a) The kernel needs convenient/efficient access to it.
	OR
	b) It must be there for protection.

Way back, PWB/UNIX added 3 per-process data items, which were given
shell variable names.  This was done only after great agonizing.
PWB also changed file creation modes (manually) everywhere to
avoid creating 0666 files; this was not elegant.

It was absolutely clear that it was NOT a good idea to keep adding
piecemeal data items to the u-area to cover every single thing
that people wanted, adding new system calls to get/set each value.
By this time [1977], there were all sorts of (different) extra such
goodies tucked away in different UNIX variants, and this was not good.

Hence, the environment feature was designed into V7 as a general
mechanism to cover all miscellaneous data, such that:
	a) the kernel never needed to access the data items directly.
	b) Users who wanted big environments could pay for them,
	without penalizing everybody by making the u_area qutie large,
	or by having extra storage mechanisms.  Note: when this was
	done, it was noted that there was "the possibility for untasteful
	expansion of the enviroonment", and this has indeed come to pass,
	as one sees multi-KB-size environments floating around.
	c) No extra system calls were needed.
	d) No protection mechanisms were needed or desired [we designed
	a horde of variants that had the environment as a kernel-protected
	list of name-value-protection tuples; every single one of them
	was ugly, expensive, incomprehensible, or a combination.]
	e) System call interface routines could, as needed, interrogate
	environment variables as needed to provide useful behavior;
	these was deemed greatly preferable to having the variable
	knowledge get wired into the kernel.  [example execvp & friends].
	This was especially true when the semantics might want to change,
	as was the case in figuring out how to use $TERM early on.

In some sense, doing umask the way we did was a mistake, since the user
can change it at will, and it could have been implemented via an environment
variable, with appropriate changes to creat.  If I had it to do over,
I'd be strongly tempted to do it this way, although it adds code to
creat(), and the reasonably efficient code wants
to look at the environment once, and cache the initial value.
This has some funny semantics, but could probably be tolerated.
In any case, umask seemed simple enough, and people were, as I recall,
generally thinking that it was tied closely enough to file protection that
it was worthwhile, so it was put in this way.

In summary, I again plead with people to seek solutions that avoid 
piecewise additions of u_area state and system calls.  If something
important cannot be done any other way, there is good justification
for doing it.  Otherwise, one is just adding to the overgrowth in there,
rather than helping keep it pruned.

[ I always thought that umask should have been per-directory, not per-process.
In 4.2BSD the group of a new file is that of its parent directory.  If umask
worked similarly, I wouldn't have to be always reminding people to use umask
before working on sources.  -mod ]

Volume-Number: Volume 5, Number 22

std-unix@ut-sally.UUCP (Moderator, John Quarterman) (01/28/86)

From: mcnc!duke!rrt@seismo.UUCP (Russ Tuck)
Date: Mon, 27 Jan 86 09:18:42 est
Organization: Duke University, Durham NC

I heartily agree that umask should be per-directory rather than per-process.
This is more natural and useful, allowing related files to be given the same
protection automatically as they are created in a directory.  

What obstacles are there to putting this behavior in Unix, and to allowing it
in the standard?

				Russ Tuck
				rrt%duke.csnet@csnet-relay
				{ihnp4,decvax,mcnc}!duke!rrt

Volume-Number: Volume 5, Number 23

std-unix@ut-sally.UUCP (Moderator, John Quarterman) (01/30/86)

>From: floyd!opus!ka@SEISMO.CSS.GOV (Kenneth Almquist)
Date: Tue, 28 Jan 86 21:46:36 EST
Organization: Bell Labs, Holmdel, NJ

This article proposes a method of handling time zones which I think
meets all the requirements that have been mentioned.

The offset from GMT of some timezones is not an integral number of
hours, so I specify this offset in seconds.  The idea of compiling a
complete list of time zone names into ctime is utopian, so I have
included the time zone name.  Finally, the only way to deal with
daylight savings time appears to be to specify a list of time inter-
vals during which it applies.  Putting this all together, we get the
following, which should be placed in /usr/include/tz.h:

#define TZNAMLEN 6
#define NTZLIM 30

struct tzlimits {
	time_t tzl_start;		/* when daylight savings time starts */
	time_t tzl_end;			/* when it ends */
};

struct tz {
	time_t tz_offset;		/* offset in seconds from GMT */
	char tz_name[TZNAMLEN];		/* regular name of this time zone */
	char tz_dstname[TZNAMLEN];	/* name during daylight savings time */
	struct tzlimits tz_dst[NTZLIM];	/* intervals when DST applies */]
};

extern struct tz tz;

/* end of tz.h */


It should be possible for a user to use a time zone other than the
system time zone, but on the other hand it should be possible for
programs like uucico to be able to use the system time zone regardless
of what the user does.  Ctime should not break just because the
environment has been zapped.  To meet these requirements I propose the
routine "gettz".

Gettz is invoked as "Gettz(flag)".  The first call to gettz fills in
the global variable tz.  Subsequent calls to gettz have no effect.

Normally gettz gets the local time for the machine, but if flag is
nonzero and the environment variable TZFILE is set, gettz reads the
contents of that file specifed by TZFILE into the variable tz instead.

The routines ctime and localtime call gettz with an argument of 1, so
that programs normally do not need to invoke gettz directly.
Programs like uucico which want to force the system time zone to be
used should call gettz with an argument of zero prior to the first
call of localtime or ctime.

Gettz returns a negative value when an error occurs and zero
otherwize.  When an error occurs, gettz will attempt to set tz to the
local time zone; if that fails it will set it to GMT.

For the benefit of users, the directory /usr/lib/tz contains files
specifying all the common timezones.  The user can also create his own
private timezone files using the utility maketz.  (These files cannot
be created with text editors because they are binary files.)  The
local time zone is linked to /usr/lib/tz/local.  Most versions of the
operating system will copy this file into the kernel at system boot
time and provide a system call to fetch the local time zone which will
be used by gettz, but this is not required.  (The last sentence is for
the benefit of very small machines that might find storing the time
zone in the kernel to be too costly; I may be worrying too much here.)

Any problems with this?  The main one is that distant times will not
be represented in daylight savings time; I don't think that this is a
problem because times before Jan 1, 1970 cannot be represented anyway,
and it is a matter for speculation what the daylight savings time rule
will be in the year 2000.
				Kenneth Almquist
				ihnp4!houxm!hropus!ka	(official name)
				ihnp4!opus!ka		(shorter path)

Volume-Number: Volume 5, Number 24

std-unix@ut-sally.UUCP (Moderator, John Quarterman) (02/02/86)

Date:    Fri, 31 Jan 86 22:48:27 PST
From: UCLA Computer Club <cc1@LOCUS.UCLA.EDU>

But with this proposal, what about the past timezone changes? The DST rules
have changed in the past. As it is, this routine will never say a past time
was DST.
			Michael Gersten
-- 
disclaimer | From out on the disk there arose such a platter | Michael Gersten

Volume-Number: Volume 5, Number 26

std-unix@ut-sally.UUCP (Moderator, John Quarterman) (02/02/86)

>From: ihnp4!mecc!sewilco (Scot E. Wilcoxon)
Date: Sat Feb  1 15:52:38 1986

U.S. Congress is concerned about election projections affecting
the results of some elections.  One of the people working on
legislation to close polls at the same time across the
nation was being interviews on NPR this week.

Because of the four-hour time zone difference across the continent,
the current proposal includes extending Daylight Savings Time
only in the west and only during (Presidential?) election years.

This proposal highlights the need for a very flexible time algorithm.
Before this, I certainly hadn't thought of election year as a
factor to consider.

(Observations about computerized forecasting affecting computerized
time probably belong in another group.)
--

Scot E. Wilcoxon  Minn. Ed. Comp. Corp.            quest!mecc!sewilco
45 03 N / 93 15 W   (612)481-3507 {ihnp4,mgnetp}!dicomed!mecc!sewilco

Volume-Number: Volume 5, Number 27

std-unix@ut-sally.UUCP (Moderator, John Quarterman) (02/03/86)

>From: pyramid!pyrcorp!ncr-sd!greg
Date: Sat, 1 Feb 86 22:45:20 pst
Subject: Re: TZ and TERM per process
Organization: NCR Corporation, Rancho Bernardo

>>From: floyd!opus!ka@SEISMO.CSS.GOV (Kenneth Almquist)
>Date: Tue, 28 Jan 86 21:46:36 EST
>Organization: Bell Labs, Holmdel, NJ
>
>This article proposes a method of handling time zones which I think
>meets all the requirements that have been mentioned.
>
> [ a scheme where timezone information is kept in a binary table
>   and read in upon demand.  Also includes a clever technique for
>   allowing users to use non-local timezones while permiting system
>   programs to still run in local time. ]
>
>Any problems with this?

An interesting idea; I'd like to see it explored further.  The impact
would not seem to be great, there are minimal changes to existing code,
it allows flexibility in the choice of timezone, and it has a system-wide
default that isn't compiled in.

There's one change I would suggest: the offset for each daylight savings
time should be specified independently; sometimes the clock shift is
not exactly one hour -- there are some areas with double daylight
savings (two hours different), for example.  The name of the zone may
have to be specified, as well.  Perhaps a better way would be to have
some entries that compactly represent the usual case (one hour offset,
standard name) and then have some provision for non-standard offsets
and names.
-- 
-- Greg Noel, NCR Rancho Bernardo    Greg@ncr-sd.UUCP or Greg@nosc.ARPA

Volume-Number: Volume 5, Number 28

std-unix@ut-sally.UUCP (Moderator, John Quarterman) (02/04/86)

From: harvard!mit-eddie!frog!rfm (Bob Mabee)
Date: Sun, 2 Feb 86 20:56:51 est
Organization: Charles River Data Systems, Framingham MA

Several posters have mentioned that a setuid program or shell script can be
compromised by suitably altering the environment list.  This is a nasty
problem because tools (the shell, library functions) are likely to develop
new dependencies on the environment as new functionality is added, and we
are not likely to think of all the possible attacks.

I suggest that the kernel should close this hole once and for all, by clearing
the environment at the point in exec() where it implements the SETUID mode.

Some programs operate incorrectly when invoked from single-user mode, or the
startup scripts, or cron, because the environment is deficient.  For example,
the time zone is likely to revert to EST.  This change forces at least the
SETUID programs to be tested (implies debugged) under such conditions.
Obviously, the time zone should default to something inappropriate for the
development site, so you notice during testing.

Instead of clearing the environment, exec() could substitute a canonical
administrative environment, from a kernel holding area or from a file.
Note that exec() is in a good position to fetch arbitrary files - it uses
high-level kernel facilities just like a user program.

				Bob Mabee @ Charles River Data Systems
				decvax!frog!rfm

Volume-Number: Volume 5, Number 31