Discussion:
[OLPC Security] secure /tmp and /var/tmp
Albert Cahalan
2007-11-07 17:06:21 UTC
Permalink
For ages now, Linux has supported the features required to do
fully private (very secure) /tmp and /var/tmp directories.
It's time to use these features.

First, create a new namespace. As root, do this:

clone(NULL,NULL,CLONE_NEWNS,NULL); // use it like fork()

Next, bind-mount something appropriate onto /tmp and /var/tmp.
Note that /var/tmp ought to survive reboot, so it goes in nand.
Subject to proper error handling and fixes for races and such,
approximate shell commands might be:

mkdir /var/tmp/12345
mount --bind /var/tmp/12345 /var/tmp
mkdir -l /tmp
mount -t tmpfs -o mode=777 tmpfs /tmp
mount --bind /some-empty-dir /something-to-hide

...where "12345" is the UID, perhaps allocated as the PID of
the current (root) process plus 10000.

That's one less portability problem. $(SUGAR_ACTIVITY_ROOT)/tmp
can just go away.
Michael Stone
2007-11-07 19:03:30 UTC
Permalink
On Wed, Nov 07, 2007 at 12:06:21PM -0500, Albert Cahalan wrote:

Albert,

Thanks very much for your suggestions.

In fact, as you can observe in the call to CreateActivity() in rainbow's
service.py, we already install each activity we create in a new
namespace.
Post by Albert Cahalan
Next, bind-mount something appropriate onto /tmp and /var/tmp.
I talked about this with Ivan who requested, at the time, that we
continue using the $SAR directories instead of the FHS ones.

The basic idea was that we actually _do not_ want activities scribbling
all over the filesystem. Period. Certainly we could use the standard
paths, as you suggest. However, it was an intentional design decision to
break compatibility with the FHS.
Post by Albert Cahalan
...where "12345" is the UID, perhaps allocated as the PID of
the current (root) process plus 10000.
I wish it were as easy as just setting the pid to something high, but
unforunately, Sugar gets cranky when /etc/passwd and /etc/group don't
contain accurate information about the pid and and primary gid of the
program that's running.

This is quite annoying to me because /etc/passwd and /etc/group seem
difficult to modify in an atomic fashion relative to actors using a
different reservation/locking discipline.
Post by Albert Cahalan
That's one less portability problem. $(SUGAR_ACTIVITY_ROOT)/tmp
can just go away.
Do you have some examples of programs which don't listen to $TMPDIR and
which don't take explicit paths to non-volatile storage? If so, would it
not be more appropriate to make these programs even more portable by
removing assumptions they're making about the environment in which
they're running?

[I've considered setting $HOME to point to one of $SAR/instancec or
$SAR/data, but the reason for separating them is that they have
different semantics and $HOME normally fits both roles]

Michael
Albert Cahalan
2007-11-08 02:09:27 UTC
Permalink
Post by Michael Stone
Post by Albert Cahalan
Next, bind-mount something appropriate onto /tmp and /var/tmp.
I talked about this with Ivan who requested, at the time, that we
continue using the $SAR directories instead of the FHS ones.
The basic idea was that we actually _do not_ want activities scribbling
all over the filesystem. Period. Certainly we could use the standard
paths, as you suggest. However, it was an intentional design decision to
break compatibility with the FHS.
Using standard directories is not scribbling all over
the filesystem!

This anti-compatibility attitude needs to stop. It's really
hurting OLPC, needlessly making the goals harder to
achieve. Breaking compatibility is something to be done
as a last resort, when no alterative will work.

The long-term goal should be to support solid sandboxing
of true all-over-the-filesystem software installs. This may
need a unionfs filesystem so that files can be put everywhere
without the dummy files needed for file-on-file bind mounts.
Imagine if you could install any RPM, knowing that it had
no way to corrupt your OS.
Post by Michael Stone
Post by Albert Cahalan
...where "12345" is the UID, perhaps allocated as the PID of
the current (root) process plus 10000.
I wish it were as easy as just setting the pid to something high, but
unforunately, Sugar gets cranky when /etc/passwd and /etc/group don't
contain accurate information about the pid and and primary gid of the
program that's running.
Oh. Well, you don't have to work around that bug
if you fix it. :-)
Post by Michael Stone
Post by Albert Cahalan
That's one less portability problem. $(SUGAR_ACTIVITY_ROOT)/tmp
can just go away.
Do you have some examples of programs which don't listen to $TMPDIR and
which don't take explicit paths to non-volatile storage? If so, would it
not be more appropriate to make these programs even more portable by
removing assumptions they're making about the environment in which
they're running?
$TMPDIR doesn't cover /var/tmp, and vi uses /var/tmp, so I
guess that would be one.

Never minding if it would be a good idea to modify any such
programs, needlessly making them fail is a very bad idea.
Stephen John Smoogen
2007-11-08 04:15:20 UTC
Permalink
Post by Albert Cahalan
Post by Michael Stone
Post by Albert Cahalan
Next, bind-mount something appropriate onto /tmp and /var/tmp.
I talked about this with Ivan who requested, at the time, that we
continue using the $SAR directories instead of the FHS ones.
The basic idea was that we actually _do not_ want activities scribbling
all over the filesystem. Period. Certainly we could use the standard
paths, as you suggest. However, it was an intentional design decision to
break compatibility with the FHS.
Using standard directories is not scribbling all over
the filesystem!
This anti-compatibility attitude needs to stop. It's really
hurting OLPC, needlessly making the goals harder to
achieve. Breaking compatibility is something to be done
as a last resort, when no alterative will work.
The long-term goal should be to support solid sandboxing
of true all-over-the-filesystem software installs. This may
need a unionfs filesystem so that files can be put everywhere
without the dummy files needed for file-on-file bind mounts.
Imagine if you could install any RPM, knowing that it had
no way to corrupt your OS.
A couple of questions from someone who is trying to catchup on what he
might be able to do

1) How much indirection can the CPU handle via various layers (say
unionfs ontop of unionfs etc) without bogging down the system?
2) How much can the flash drive handle per throughput AND lifetime limits?
3) How much can the memory system handle? since... I don't think we
want to hit swap.

If all these are generally known and been discussed already.. sorry.
--
Stephen J Smoogen. -- CSIRT/Linux System Administrator
How far that little candle throws his beams! So shines a good deed
in a naughty world. = Shakespeare. "The Merchant of Venice"
Ivan Krstić
2007-11-08 12:11:52 UTC
Permalink
Post by Albert Cahalan
Using standard directories is not scribbling all over
the filesystem!
This anti-compatibility attitude needs to stop. It's really
hurting OLPC, needlessly making the goals harder to
achieve. Breaking compatibility is something to be done
as a last resort, when no alterative will work.
For better or for worse, compatibility has been broken, and on a
level as fundamental as file access. If an application can't even
access the user's files without being aware of the datastore, what
good is it to pretend that providing small bits of backwards
compatibility will make things substantially easier?

For us, $SAR/tmp lives in RAM and is severely limited (maybe to as
little as 1MB per application). $SAR/instance is used for transient
per-instance disk-backed storage. Since it's a given that work needs
to be done to port applications to Sugar, it's a _good_ thing that a
programmer is also confronted with the decision as to which of these
two temporary directories to use. Enabling a wrapper for /tmp would
have us make that decision for them, and as fellow Python programmers
know: explicit is better than implicit, and in the face of ambiguity,
refuse the temptation to guess.
Post by Albert Cahalan
The long-term goal should be to support solid sandboxing
of true all-over-the-filesystem software installs. This may
need a unionfs filesystem so that files can be put everywhere
without the dummy files needed for file-on-file bind mounts.
Imagine if you could install any RPM, knowing that it had
no way to corrupt your OS.
That goal is not something I'm spending much time thinking about. The
level of protection provided by Bitfrost is not something you can do
without serious compatibility breaks with how things are done at
present.

--
Ivan Krsti? <krstic at solarsail.hcs.harvard.edu> | http://radian.org
Albert Cahalan
2007-11-08 15:42:21 UTC
Permalink
Post by Ivan Krstić
Post by Albert Cahalan
Using standard directories is not scribbling all over
the filesystem!
This anti-compatibility attitude needs to stop. It's really
hurting OLPC, needlessly making the goals harder to
achieve. Breaking compatibility is something to be done
as a last resort, when no alterative will work.
For better or for worse, compatibility has been broken, and on a
level as fundamental as file access. If an application can't even
access the user's files without being aware of the datastore, what
good is it to pretend that providing small bits of backwards
compatibility will make things substantially easier?
One failure is no excuse to purposely fail in every way.

Not every application even needs access to a user's files.

The datastore has changed and apparantly will change.
Perhaps it can someday be less awkward to deal with.

In any case, yes, it is extra work and ugly code.
You're affecting every porting effort; it must be easy
to make that decision when it's somebody else's
code base getting screwed with #ifdef everywhere.
Post by Ivan Krstić
For us, $SAR/tmp lives in RAM and is severely limited (maybe to as
little as 1MB per application). $SAR/instance is used for transient
per-instance disk-backed storage. Since it's a given that work needs
to be done to port applications to Sugar, it's a _good_ thing that a
programmer is also confronted with the decision as to which of these
two temporary directories to use. Enabling a wrapper for /tmp would
have us make that decision for them, and as fellow Python programmers
know: explicit is better than implicit, and in the face of ambiguity,
refuse the temptation to guess.
This is nothing new. It's been standard on SunOS for ages.
The /tmp directory is in RAM, and /var/tmp is on disk.
You are not so special that you need to break everything.
AFAIK, this is even a common (normal?) setup on BSD.

BTW, if you're going to keep calling it $SAR, then you'd
better make that the real name of the variable.
Post by Ivan Krstić
Post by Albert Cahalan
The long-term goal should be to support solid sandboxing
of true all-over-the-filesystem software installs. This may
need a unionfs filesystem so that files can be put everywhere
without the dummy files needed for file-on-file bind mounts.
Imagine if you could install any RPM, knowing that it had
no way to corrupt your OS.
That goal is not something I'm spending much time thinking about. The
level of protection provided by Bitfrost is not something you can do
without serious compatibility breaks with how things are done at
present.
If you don't solve it, people will just turn Bitfrost off.
Jim Gettys
2007-11-08 15:51:43 UTC
Permalink
I sympathize with Albert's point here: we should be no more incompatible
than we have to be... Just because we have to break some things,
doesn't mean we have to break everything.
- Jim
Post by Albert Cahalan
Post by Ivan Krstić
Post by Albert Cahalan
Using standard directories is not scribbling all over
the filesystem!
This anti-compatibility attitude needs to stop. It's really
hurting OLPC, needlessly making the goals harder to
achieve. Breaking compatibility is something to be done
as a last resort, when no alterative will work.
For better or for worse, compatibility has been broken, and on a
level as fundamental as file access. If an application can't even
access the user's files without being aware of the datastore, what
good is it to pretend that providing small bits of backwards
compatibility will make things substantially easier?
One failure is no excuse to purposely fail in every way.
Not every application even needs access to a user's files.
The datastore has changed and apparantly will change.
Perhaps it can someday be less awkward to deal with.
In any case, yes, it is extra work and ugly code.
You're affecting every porting effort; it must be easy
to make that decision when it's somebody else's
code base getting screwed with #ifdef everywhere.
Post by Ivan Krstić
For us, $SAR/tmp lives in RAM and is severely limited (maybe to as
little as 1MB per application). $SAR/instance is used for transient
per-instance disk-backed storage. Since it's a given that work needs
to be done to port applications to Sugar, it's a _good_ thing that a
programmer is also confronted with the decision as to which of these
two temporary directories to use. Enabling a wrapper for /tmp would
have us make that decision for them, and as fellow Python programmers
know: explicit is better than implicit, and in the face of ambiguity,
refuse the temptation to guess.
This is nothing new. It's been standard on SunOS for ages.
The /tmp directory is in RAM, and /var/tmp is on disk.
You are not so special that you need to break everything.
AFAIK, this is even a common (normal?) setup on BSD.
BTW, if you're going to keep calling it $SAR, then you'd
better make that the real name of the variable.
Post by Ivan Krstić
Post by Albert Cahalan
The long-term goal should be to support solid sandboxing
of true all-over-the-filesystem software installs. This may
need a unionfs filesystem so that files can be put everywhere
without the dummy files needed for file-on-file bind mounts.
Imagine if you could install any RPM, knowing that it had
no way to corrupt your OS.
That goal is not something I'm spending much time thinking about. The
level of protection provided by Bitfrost is not something you can do
without serious compatibility breaks with how things are done at
present.
If you don't solve it, people will just turn Bitfrost off.
_______________________________________________
Security mailing list
Security at lists.laptop.org
http://lists.laptop.org/listinfo/security
--
Jim Gettys
One Laptop Per Child
Ivan Krstić
2007-11-08 16:20:21 UTC
Permalink
Post by Albert Cahalan
One failure is no excuse to purposely fail in every way.
It's not a purposeful failure. We're imposing non-obvious changes on
semantics due to restrictions in our environment, such as a strict
limitation on the size of /tmp.

I'd _much_ rather have my application break during porting when I try
to write to /tmp, at which point I go and think about where it should
be writing instead, than to have it explode in strange ways when
further writes to /tmp start erroring out because the (small amount
of) space has been exhausted.

If I'm in the minority with this sentiment, I am open to revising the
policy.
Post by Albert Cahalan
This is nothing new. It's been standard on SunOS for ages.
The /tmp directory is in RAM, and /var/tmp is on disk.
A tiny size restriction is pretty new.
Post by Albert Cahalan
You are not so special that you need to break everything.
I am a uniquely special snowflake of unique specialness.
Post by Albert Cahalan
If you don't solve it, people will just turn Bitfrost off.
Bitfrost is not a general Linux distribution security mechanism.
Sugar is not a general Linux desktop environment. These things are
designed with different goals in mind, for a different purpose, and
behave differently than the things you're used to. You can argue that
our designs are wrong and the behaviors broken, but even that's for
the most part orthogonal to the argument that the designs should be
such that everything old continues to magically work. Backwards
compatibility, quite simply, was not an OLPC design goal, and while I
am happy to not deviate from old behavior superfluously, I also have
an interest in doing the right thing for the new platform, especially
when dealing with ambiguity. At the moment, I regard the /tmp
situation as ambiguous and misleading.

--
Ivan Krsti? <krstic at solarsail.hcs.harvard.edu> | http://radian.org
Marcus Leech
2007-11-08 16:38:44 UTC
Permalink
Heh. You are way too young....
The presumption has always been you'd better keep things in /tmp pretty
small; that's why the distinction between /tmp and /var/tmp was made.
It allowed people to use RAM file systems for speed long before it would
have otherwise been feasible.
- Jim
These kids who think that 256M of physical ram is *small* :-)

My first Unix machine had 128K of MOS memory, and we supported about
10-15 interactive users on it at a time, with a 30M
disk drive that was the size of a washing machine. Having /tmp in RAM
was a newfangled thing that came along later, but
with 30M of physical disk there, /tmp had to be small anyway!

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 251 bytes
Desc: OpenPGP digital signature
Url : http://lists.laptop.org/pipermail/security/attachments/20071108/6d8f5a8e/attachment.pgp
Ivan Krstić
2007-11-08 17:00:11 UTC
Permalink
Heh. You are way too young....
It takes a long time to become young! On the upside, my work did not
give rise to xorg.conf ;)
My first Unix machine had 128K of MOS memory, and we supported about
10-15 interactive users on it
MOS memory? _MOS memory_? In my young day we started out as
apprentice binary registers. Six o'clock in the morning, come rain,
sleet, hail, or snow, we'ed be there kicking each other in the
buttocks -- right for 1, left for zero. A'course I say registers,
cause they were registers to us. But it were a stack really. None o'
this modern stack pointer rubbish, either. You used to 'ave to
remember which were t'top element in yer 'ead.

Anyway, due to vocal support, we'll preserve /tmp. I don't think it's
the best course of action, but we'll roll with it.

--
Ivan Krsti? <krstic at solarsail.hcs.harvard.edu> | http://radian.org
Jim Gettys
2007-11-08 19:24:29 UTC
Permalink
Post by Ivan Krstić
Heh. You are way too young....
It takes a long time to become young! On the upside, my work did not
give rise to xorg.conf ;)
Nor did mine. I will take no blame for that abortion, and will take
partial credit for having helped poke the community away from its use;
it is becoming less and less needed as time goes along. My happy day
will be when it is not needed what-so-ever....
- Jim
--
Jim Gettys
One Laptop Per Child
Stephen John Smoogen
2007-11-08 17:03:18 UTC
Permalink
Post by Ivan Krstić
A tiny size restriction is pretty new.
Heh. You are way too young....
The presumption has always been you'd better keep things in /tmp pretty
small; that's why the distinction between /tmp and /var/tmp was made.
It allowed people to use RAM file systems for speed long before it would
have otherwise been feasible.
- Jim
Yes.. about 17 years ago when I got into the business (and that makes
me a kid).. the first job of every jr sysadmin was to write a cleanup
script that worked better than the last cleanup script. It ran every
hour in /tmp and cleaned up anything older than an hour and anything
over 1 MB that had been around for 15 minutes.. and we still ran out
of /tmp 1 or 2 a week.

In the end, the question does breaking /tmp gain anything in security
on a system where the primary user is one person at a time, and the
malware writers still have access to the home directory.
--
Stephen J Smoogen. -- CSIRT/Linux System Administrator
How far that little candle throws his beams! So shines a good deed
in a naughty world. = Shakespeare. "The Merchant of Venice"
Bert Freudenberg
2007-11-08 17:11:18 UTC
Permalink
Though applications backwards compatibility just doesn't make sense in
this context. We consciously broke it with the high level design, both
of the user experience and of the security framework.
That's not the point. The point is how hard we make it for people to
port their apps to Sugar. And in my opinion we should not make it
unnecessarily hard.

- Bert -
Albert Cahalan
2007-11-08 17:57:26 UTC
Permalink
In some cases though it's better to break than to keep a fake
compatibility with something which is designed for a different use
case. That way the error is explicit and the activity author knows it
needs to be fixed. And I agree with Ivan that this is the case for
/tmp.
The XO /tmp is **exactly** like a SunOS /tmp. It's in RAM.
Well, one difference: it was common to have only 8 MB.

There is nothing new here. The XO is not special.

Understand that each and every #ifdef is a despised wart that
makes code less maintainable. I know it isn't YOUR code.
Please be considerate of other people's code.

BTW, it's not as if running out of RAM will fail to alert the
author. There is no problem here. One can just as well
have trouble with malloc or severe recursion.
Loading...