Util-Linux package development
 help / color / mirror / Atom feed
* unshare -m and mount propagation
@ 2016-03-18  2:26 Yuriy M. Kaminskiy
  2016-04-18 11:16 ` Karel Zak
  0 siblings, 1 reply; 7+ messages in thread
From: Yuriy M. Kaminskiy @ 2016-03-18  2:26 UTC (permalink / raw)
  To: util-linux

1. User-ns, mount-ns and mount propagation.

When you create mount-ns in user-ns (or both at once), kernel
automatically breaks mount propagation from guest to host (in other
words, `forcibly downgrade "shared" mounts to "slave"`), due to obvious
security consideration (if your mount in user-ns guest will propagate
back to host, it will be disaster).

E.g. try
   unshare -r -m --prop unchanged findmnt -no TARGET,PROPAGATION|head -1
or
   unshare -r unshare --prop unchanged findmnt -no TARGET,PROPAGATION|head -1
(both will show "/ private,slave", even though unshare(1) have not tried
to change propagation flags).

Note that once propagation is broken, you cannot go back. E.g.
  unshare -r -m --propagation shared -- findmnt -no TARGET,PROPAGATION|head -1
or (basically same)
  unshare -r -m --propagation unchanged sh -c 'mount --make-rshared /;
    findmnt -no TARGET,PROPAGATION|head -1'
will results in "/ shared,slave"; that is, propagation from guest to
host is disabled, but propagation within guest is enabled.

2. Long-lived mount-ns and dangers of `--propagation private` (default in
recent util-linux).

`--propagation private` breaks unmount propagation from "host" to
"guest", so if you mount e.g. removable media in host, unshare mount
namespace and spawn long-lived process, then umount your media
in host namespace, it still remains mounted in guest namespace, and keep
device busy:

  mount /media/cdrom
  unshare -rm --prop private sleep inf &
  pid=$!
  eject /media/cdrom # oops, still locked
  grep /media/cdrom /proc/self/mounts
  (empty)
  sudo nsenter -t $pid -m grep /media/cdrom /proc/self/mounts
  # ... as it is still mounted there

If device locks mounted media (e.g. cdrom), this can be confusing to
user ("why eject does not work? I umounted it, fuser/lsof shows nothing???").

If device does not lock mounted media, and user forcibly ejects media
(e.g. cardreader or usb drive), this can result in data loss (filesystem
is not properly umounted, there can be unsynced data in cache).

`--propagation slave` does not have this problem (when host unmount
/cdrom, it is also unmounted in guest):

  mount /media/cdrom
  unshare -rm --prop slave sleep inf &
  pid=$!
  umount /media/cdrom # or eject /media/cdrom
  sudo nsenter -t $pid -m grep /media/cdrom /proc/self/mounts
(empty)

Also, once you (completely) broke propagation by `--propagation private`
[as implied by default in current util-linux], you cannot go back. E.g.

  unshare -rm sh -c 'findmnt -no TARGET,PROPAGATION|head -1;
  mount --make-rslave /;
  findmnt -no TARGET,PROPAGATION|head -1'

/ private
/ private

I think this issue should be at least documented. And, maybe, default
`--propagation` should be changed to `slave`.

=====================================================================

P.S. I'd like to note that this thing has some abuse potential. Above
scenarios suggest *accidental* case when `unshare -rm --prop private \
sleep inf &` can trigger data loss. But someone can *intentionally* try
to choose moment when it triggers most disruption to other users (and
root) work. This also affects fs/devices they cannot access (and thus
cannot normally block by chdir or opening file; besides, chdir or open
file is visible in lsof/fuser, stray sleep-in-namespace is not).

(Of course, this possible abuse is *not* a util-linux problem [and
cannot be solved within util-linux]; this is a *kernel* problem)

P.P.S. as I dig into user-ns, I'm more and more happy our debian
overlords disabled unprivileged userns by default. And lately I feel
they should've disabled it completely :-| It's a way too prone to abuse.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: unshare -m and mount propagation
  2016-03-18  2:26 unshare -m and mount propagation Yuriy M. Kaminskiy
@ 2016-04-18 11:16 ` Karel Zak
  2016-04-18 11:51   ` Yuriy M. Kaminskiy
  0 siblings, 1 reply; 7+ messages in thread
From: Karel Zak @ 2016-04-18 11:16 UTC (permalink / raw)
  To: Yuriy M. Kaminskiy; +Cc: util-linux

On Fri, Mar 18, 2016 at 05:26:25AM +0300, Yuriy M. Kaminskiy wrote:
> I think this issue should be at least documented. And, maybe, default
> `--propagation` should be changed to `slave`.

The reason why we use 'private' is that it's the kernel default for
years and it's what has been expected by users for long time before we
introduced --propagation and any unshare(1) default.

The current --propagation default unifies things and makes unshare(1) 
portable to distributions where root fs is mounted as 'shared' (e.g. 
systemd distros) and all this in backwardly compatible way for users
who have no clue about --propagation.

So, I don't think we want to change any default to corrupt scripts where
is no explicitly specified --propagation. 

    Karel


-- 
 Karel Zak  <kzak@redhat.com>
 http://karelzak.blogspot.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: unshare -m and mount propagation
  2016-04-18 11:16 ` Karel Zak
@ 2016-04-18 11:51   ` Yuriy M. Kaminskiy
  2016-04-18 12:22     ` Karel Zak
  0 siblings, 1 reply; 7+ messages in thread
From: Yuriy M. Kaminskiy @ 2016-04-18 11:51 UTC (permalink / raw)
  To: util-linux

Karel Zak <kzak@redhat.com> writes:

> On Fri, Mar 18, 2016 at 05:26:25AM +0300, Yuriy M. Kaminskiy wrote:
>> I think this issue should be at least documented. And, maybe, default
>> `--propagation` should be changed to `slave`.
>
> The reason why we use 'private' is that it's the kernel default for
> years and it's what has been expected by users for long time before we
> introduced --propagation and any unshare(1) default.
>
> The current --propagation default unifies things and makes unshare(1) 
> portable to distributions where root fs is mounted as 'shared' (e.g. 
> systemd distros) and all this in backwardly compatible way for users
> who have no clue about --propagation.
>
> So, I don't think we want to change any default to corrupt scripts where
> is no explicitly specified --propagation. 

By you already broke scripts that expected old a-la '--propagation
unchanged' behavior.
E.g. one my script did
   unshare -m sh -c 'mount --make-rslave /; ...'
Now I must check for util-linux version and either use --propagation
option, or mount --make-rslave (you cannot revert back from private to
slave).
(And as I said, 'private' breaks umount propagation and thus very bad for
long-running namespaces).


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: unshare -m and mount propagation
  2016-04-18 11:51   ` Yuriy M. Kaminskiy
@ 2016-04-18 12:22     ` Karel Zak
  2016-04-18 13:05       ` Yuriy M. Kaminskiy
  0 siblings, 1 reply; 7+ messages in thread
From: Karel Zak @ 2016-04-18 12:22 UTC (permalink / raw)
  To: Yuriy M. Kaminskiy; +Cc: util-linux

On Mon, Apr 18, 2016 at 02:51:37PM +0300, Yuriy M. Kaminskiy wrote:
> Karel Zak <kzak@redhat.com> writes:
> 
> > On Fri, Mar 18, 2016 at 05:26:25AM +0300, Yuriy M. Kaminskiy wrote:
> >> I think this issue should be at least documented. And, maybe, default
> >> `--propagation` should be changed to `slave`.
> >
> > The reason why we use 'private' is that it's the kernel default for
> > years and it's what has been expected by users for long time before we
> > introduced --propagation and any unshare(1) default.
> >
> > The current --propagation default unifies things and makes unshare(1) 
> > portable to distributions where root fs is mounted as 'shared' (e.g. 
> > systemd distros) and all this in backwardly compatible way for users
> > who have no clue about --propagation.
> >
> > So, I don't think we want to change any default to corrupt scripts where
> > is no explicitly specified --propagation. 
> 
> By you already broke scripts that expected old a-la '--propagation
> unchanged' behavior.

Only if your system uses something else that kernel default 'private'
and you depend on this non-default setting. (IMHO relatively small 
groups of users)

The old "--propagation unchanged" makes unshare useless on some 
mainstream distros where default is 'shared'.

Anyway, we will not change any default now.

    Karel

-- 
 Karel Zak  <kzak@redhat.com>
 http://karelzak.blogspot.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: unshare -m and mount propagation
  2016-04-18 12:22     ` Karel Zak
@ 2016-04-18 13:05       ` Yuriy M. Kaminskiy
  2016-04-18 17:48         ` Karel Zak
  0 siblings, 1 reply; 7+ messages in thread
From: Yuriy M. Kaminskiy @ 2016-04-18 13:05 UTC (permalink / raw)
  To: util-linux

On 18.04.2016 15:22, Karel Zak wrote:
> On Mon, Apr 18, 2016 at 02:51:37PM +0300, Yuriy M. Kaminskiy wrote:
>> Karel Zak <kzak@redhat.com> writes:
>>
>>> On Fri, Mar 18, 2016 at 05:26:25AM +0300, Yuriy M. Kaminskiy wrote:
>>>> I think this issue should be at least documented. And, maybe, default
>>>> `--propagation` should be changed to `slave`.
>>>
>>> The reason why we use 'private' is that it's the kernel default for
>>> years and it's what has been expected by users for long time before we
>>> introduced --propagation and any unshare(1) default.
>>>
>>> The current --propagation default unifies things and makes unshare(1)
>>> portable to distributions where root fs is mounted as 'shared' (e.g.
>>> systemd distros) and all this in backwardly compatible way for users

Opposite. It does not change anything for older systems, but breaks 
things for new systems.

>>> who have no clue about --propagation.

And it is *especially* harmful for users that are not aware about 
--propagation. As private (new 2.27+ default) break umount propagation, 
and results in nasty surprises (up to data loss).

>>> So, I don't think we want to change any default to corrupt scripts where
>>> is no explicitly specified --propagation.
>>
>> By you already broke scripts that expected old a-la '--propagation
>> unchanged' behavior.
>
> Only if your system uses something else that kernel default 'private'
> and you depend on this non-default setting. (IMHO relatively small
> groups of users)

All systemd systems use shared. Which is not "small group of users".

> The old "--propagation unchanged" makes unshare useless on some
> mainstream distros where default is 'shared'.

No, it is not. --propagation does not do *anything* that cannot be done 
without it. On pre-2.27 util-linux,

   unshare -m sh -c 'mount --make-rprivate /; ...'

does exactly same as `unshare -m [--propagation=private] ...` in 2.27+.

Reverse is not true! With 2.27 you *must* use new 
[backward-incompatible] options to revert to sane behavior [which is 
*slave*, not *private*].

> Anyway, we will not change any default now.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: unshare -m and mount propagation
  2016-04-18 13:05       ` Yuriy M. Kaminskiy
@ 2016-04-18 17:48         ` Karel Zak
  2016-04-18 20:35           ` Yuriy M. Kaminskiy
  0 siblings, 1 reply; 7+ messages in thread
From: Karel Zak @ 2016-04-18 17:48 UTC (permalink / raw)
  To: Yuriy M. Kaminskiy; +Cc: util-linux

On Mon, Apr 18, 2016 at 04:05:29PM +0300, Yuriy M. Kaminskiy wrote:
> On 18.04.2016 15:22, Karel Zak wrote:
> > On Mon, Apr 18, 2016 at 02:51:37PM +0300, Yuriy M. Kaminskiy wrote:
> > > Karel Zak <kzak@redhat.com> writes:
> > > 
> > > > On Fri, Mar 18, 2016 at 05:26:25AM +0300, Yuriy M. Kaminskiy wrote:
> > > > > I think this issue should be at least documented. And, maybe, default
> > > > > `--propagation` should be changed to `slave`.
> > > > 
> > > > The reason why we use 'private' is that it's the kernel default for
> > > > years and it's what has been expected by users for long time before we
> > > > introduced --propagation and any unshare(1) default.
> > > > 
> > > > The current --propagation default unifies things and makes unshare(1)
> > > > portable to distributions where root fs is mounted as 'shared' (e.g.
> > > > systemd distros) and all this in backwardly compatible way for users
> 
> Opposite. It does not change anything for older systems, but breaks things
> for new systems.
> 
> > > > who have no clue about --propagation.
> 
> And it is *especially* harmful for users that are not aware about
> --propagation. As private (new 2.27+ default) break umount propagation, and
> results in nasty surprises (up to data loss).

Well, you see only umount propagation... 

The problem is that the original implementation (try emulate by
"--propagation unchanged") makes "unshare --mount" useless at all on
systems with shared root fs.

The very old (since year 2009) and very common use-case is:

 # unshare --mount
 # mount /dev/foo /mnt

and user expects that /mnt will be visible *only* in the session
(namespace). This is the way how many users use unshare for years.

Unfortunately, after systemd installation it does not work anymore
and /mnt is visible everywhere. For users it's regression and it has
been reported many many times.

You can blame systemd, but the problem is that unshare(1) was not
robust enough. So we have forced unshare to use "private" by default
to keep the *original behavior* independently on root fs propagation
flag.

    Karel

-- 
 Karel Zak  <kzak@redhat.com>
 http://karelzak.blogspot.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: unshare -m and mount propagation
  2016-04-18 17:48         ` Karel Zak
@ 2016-04-18 20:35           ` Yuriy M. Kaminskiy
  0 siblings, 0 replies; 7+ messages in thread
From: Yuriy M. Kaminskiy @ 2016-04-18 20:35 UTC (permalink / raw)
  To: Karel Zak; +Cc: util-linux

On 18.04.2016 20:48, Karel Zak wrote:
> On Mon, Apr 18, 2016 at 04:05:29PM +0300, Yuriy M. Kaminskiy wrote:
>> On 18.04.2016 15:22, Karel Zak wrote:
>>> On Mon, Apr 18, 2016 at 02:51:37PM +0300, Yuriy M. Kaminskiy wrote:
>>>> Karel Zak <kzak@redhat.com> writes:
>>>>
>>>>> On Fri, Mar 18, 2016 at 05:26:25AM +0300, Yuriy M. Kaminskiy wrote:
>>>>>> I think this issue should be at least documented. And, maybe, default
>>>>>> `--propagation` should be changed to `slave`.
>>>>>
>>>>> The reason why we use 'private' is that it's the kernel default for
>>>>> years and it's what has been expected by users for long time before we
>>>>> introduced --propagation and any unshare(1) default.
>>>>>
>>>>> The current --propagation default unifies things and makes unshare(1)
>>>>> portable to distributions where root fs is mounted as 'shared' (e.g.
>>>>> systemd distros) and all this in backwardly compatible way for users
>>
>> Opposite. It does not change anything for older systems, but breaks things
>> for new systems.
>>
>>>>> who have no clue about --propagation.
>>
>> And it is *especially* harmful for users that are not aware about
>> --propagation. As private (new 2.27+ default) break umount propagation, and
>> results in nasty surprises (up to data loss).
>
> Well, you see only umount propagation...

Because *breaking* it causes real problems?

> The problem is that the original implementation (try emulate by
> "--propagation unchanged") makes "unshare --mount" useless at all on
> systems with shared root fs.
>
> The very old (since year 2009) and very common use-case is:
>
>   # unshare --mount

      mount --make-rslave / # or --make-rprivate or whatever

>   # mount /dev/foo /mnt

And? I've posted how this could be solved *without* changing anything in 
unshare.

> and user expects that /mnt will be visible *only* in the session
> (namespace). This is the way how many users use unshare for years.
>
> Unfortunately, after systemd installation it does not work anymore
> and /mnt is visible everywhere. For users it's regression and it has
> been reported many many times.
>
> You can blame systemd, but the problem is that unshare(1) was not
> robust enough. So we have forced unshare to use "private" by default
> to keep the *original behavior* independently on root fs propagation
> flag.

You can have same effect with *slave* as default, with exception that 
host->guest mount/unmount propagation still works.
When kernel have to get rid of shared propagation (in userns), it 
downgrades shared mounts to *slave*, not to *private*.
When systemd itself downgrades shared propagation (for running service 
in new mount namespace; Protect*/Private*/etc), it also downgrades 
*shared* propagation to *slave*, not to *private*.

P.S. For sure, *any* of propagation variants have some or other 
drawbacks and corner cases; however, without special care about 
removable media (and alike), *private* has higher chance to beat you in 
a nasty way.

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2016-04-18 20:35 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-03-18  2:26 unshare -m and mount propagation Yuriy M. Kaminskiy
2016-04-18 11:16 ` Karel Zak
2016-04-18 11:51   ` Yuriy M. Kaminskiy
2016-04-18 12:22     ` Karel Zak
2016-04-18 13:05       ` Yuriy M. Kaminskiy
2016-04-18 17:48         ` Karel Zak
2016-04-18 20:35           ` Yuriy M. Kaminskiy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox