Re: [Tails-dev] Serious issue: fail-safe and hotplugging

Delete this message

Reply to this message
Author: intrigeri
Date:  
To: The Tails public development discussion list
New-Topics: Re: [Tails-dev] Serious issue: fail-safe and hotplugging
Subject: Re: [Tails-dev] Serious issue: fail-safe and hotplugging
Hi,

sorry for the delay, and sorry in advance for the bad mood that
probably impacts this email, I'm a bit grumpy today.

anonym wrote (31 Dec 2013 00:45:51 GMT) :
> 30/12/13 13:48, intrigeri wrote:
>> anonym wrote (29 Dec 2013 21:21:35 GMT) :
>>> 27/12/13 18:05, intrigeri wrote:
>>> Approach 1
>>> ----------
>>
>>> A seemingly obvious fix would be to move the fail-safe from its current
>>> location, tails-unblock-network, into tails-spoof-mac, which is run by
>>> the MAC spoofing udev hook when network devices are added. The fail-safe
>>> would then act on a per-device basis, and it would be closer to the
>>> spoofing, which both are nice (bonus: the problem you raised about
>>> "macchanger can't retrieve the permanent MAC address" would be really
>>> easy to fix).
>>
>> I like this approach, and I hope we can make it work fine. Let's see.
>>
>>> However, a big issue with this approach is that if NetworkManager is
>>> running when tails-spoof-mac is run by the udev hook (which will be the
>>> case every time a device is hotplugged after TG login) then there's a
>>> race: will NM spawn network activity before the fail-safe is triggered
>>> in case of a MAC spoofing error? This doesn't feel robust at all.
>>
>> Are you sure NM picks up newly added devices before udev has finished
>> adding it to the system (which, I hope, is indicated by the fact that
>> all udev rules have completed their job, which, I hope, includes
>> running all hooks)?


> I wasn't sure, but I've now verified that there indeed is *no* race with
> NM. I verified by adding a sleep(1) hooked via an udev rule, and NM is
> delayed for the duration of the sleep.


Good.

> It should be noted, though, that
> the device is fully operational during the sleep; I could get the
> network up via e.g. `dhclient eth0`. Hence, if "something else" can
> cause network activity at that time, then there's a race between that
> "something else" and the spoofing instead.


I don't think we care about this case. One can shoot themselves in the
foot by doing random things as root, no news.

> It remains to investigate why NM waits for all udev hooks as we don't
> want to depend on voodoo. Any ideas?


I had a quick look at the (Wheezy) source, and it looks like the
answer may be found with `git grep -i device_added -- src', in
src/*udev*.c, and by looking for uevent and netlink handling.
I suspect the kernel simply does not announce that the added device is
available before all udev hooks have run, which makes very much sense
to me, and does not feel like voodoo :)

> Any way, slightly off-topic, but regarding "USB doesn't do DMA" I think
> that's actually false. A quick search yielded:


OK.

>>> What to do?
>>> ===========
>>
>>> If we cannot solve the problems in Approach 1 or 2 (and cannot come up
>>> with a superior Approach 3) then I guess we will have to pick whatever
>>> we consider the least bad of those two, and perhaps document that
>>> hotplugging after TG login isn't safe w.r.t. MAC spoofing.
>>
>> Another approach (that only works for USB devices) worth looking at is
>> the Linux USB authorization support:
>>
>> * Documentation/usb/authorization.txt
>> *
>> http://www.irongeek.com/i.php?page=security/plug-and-prey-malicious-usb-devices#3.2_Locking_down_Linux_using_UDEV
>>
>> So, my current position is: if approach #1 is doable in a non-racy way
>> (i.e. if NM does not picks up a new device before udev is done with
>> it), then let's KISS and just do it. Else, either go with approach #2,
>> or with approach #1 (in a bit racy way), that both require documenting
>> the limitations in rare, edge cases.


> So for KISSing and picking Approach #1 it all boils down to whether we
> consider NM as the only possible/reasonable participant in the
> aforementioned race. I guess it is, but who knows? Given how complex a
> modern Linux system is, it's kind of hard to exhaustively rule out
> everything about anything. :)


I think we are already implicitly delegating network management to
NetworkManager, and we are not installing anything that does the same
kind of things as NM. One thing that could change this is installing
stuff that plays with the networking stack at low levels, such as
virtualization host software, VPN software or similar, but we don't
ship anything like that yet, and apart of that, really, I don't see.
I would be entirely comfortable with making the asumption that
NetworkManager is the sole piece of software responsible for this part
of Tails, and the only participant to this race.

I mean, it's about the same as our firewall configuration: we've not
proven that nothing but ferm can potentially modify it. Still, we know
this little OS called Tails well enough to be reasonably confident
that we are not installing anything else (but NM, actually) that plays
with iptables/netfilter. We are confident that we don't install
anything that plays with the browser proxy configuration but
Torbutton, FoxyProxy, and potentially a few environment variables we
set. Etc.

Perfect, good, blah... you know the deal :)

> Hmm. I just think I came up with a fix that makes Approach #1 robust (it
> can be used for Approach #2 too, but it doesn't make as much sense): we
> use ferm/iptables to drop all outgoing traffic from interfaces that have
> not been explicitly said to be "ok" by the fail-safe code.


[implementation details]

> So, all outgoing traffic is ignored, except that from interfaces listed
> by name in /tmp/good (which obviously need a better location and name).
> The only code that remains to be added is:


> * The fail-safe code would `echo $INTERFACE >> /tmp/good` after
> if has verified that MAC spoofing worked (or always do it if it's
> disabled).


> * An udev hook that on ACTION=="remove" runs
> `sed -i '/$INTERFACE/d' /tmp/good`.


You'll want to anchor the regexp here to avoid "adding eth1 => mark
eth10 as good".

> * What would a good name for /tmp/good be? /var/lib/tails/allowed_nics?


Yep.

> We may want to make all of /var/lib/tails completely inaccessible by
> non-root users to not leak that MAC spoofing is enabled in the error
> case.


I'm unsure if we're using that directory for files that non-root users
need to read. If so, I suggest creating
/var/lib/tails/for-root-eyes-only/ or something.

> So, am I just chasing ghosts (i.e. a problems that we're sure don't
> exist now or in the future) or is this something worthwhile adding? It
> may not be super-KISS, but unless I've missed anything it will be quite
> simple to fit it into Approach #1.


Frankly, I'm very unsure. The implementation of this whole feature
turns out to be quite complicated, and hard to make fit into one's
mental space and reason about, as shown by the fact that both you and
I had missed some important details like the one we're discussing.

I'm not convinced that this added code, design complexity, and thus
difficulty to audit is more likely to protect our users than the lack
of it. AIUI, the only bonus is for a corner case, which the potential
drawbacks are for everybody.

But perhaps I just want to see this branch merged ASAP in some
acceptable state, and am starting to get tired of thinking about it.
The current state + a few documented known issues + the small fixes
I've asked for a while ago, would be already much better than what our
users have in hand right now.

Cheers!
--
intrigeri
| GnuPG key @ https://gaffer.ptitcanardnoir.org/intrigeri/intrigeri.asc
| OTR fingerprint @ https://gaffer.ptitcanardnoir.org/intrigeri/otr.asc