Bug#1056279: Looks like the systemctl links are gone but not the pm-utils ones

2023-12-12 Thread Helmut Grohne
Control: tags -1 + patch

On Fri, Dec 01, 2023 at 05:50:29PM +0100, Helmut Grohne wrote:
> I am very sorry to break this promise. It's complicated.

Almost two weeks later, I'm back with what I hope is a solution.

> So there will be no patch for now, because there still are unsolved
> problems. While looking into Emilio's problem and fixing the version
> constraints, I figured that test cases are failing. In particular, there
> are situations where dpkg unpacks systemd-sysv from unstable at a time
> where molly-guard from bookworm is still unpacked. This causes files
> from systemd-sysv to be irrevocably lost. I fear we're going back to the
> drawing board. If you want details, try #1057199, but I caution that
> it's not for the faint of heart and I already have apt and dpkg
> developers assist, which is awesome.

This has also resulted in systemd-sysv bug #1057220. I've considered the
options forwards and backwards. Since this loss scenario does not
involve a trixie molly-guard at all, it needs a solution in systemd
only. Discussions have resulted in two key insights:
 * If working with apt (rather than dpkg directly), this scenario can
   only happen if molly-guard and systemd-sysv have a mutual conflict
   (or breaks). We should avoid this, see below.
 * We cannot really prevent this from happening otherwise as the unpack
   of the lost file and the loss happen in the same unpack phase.

At the time of this writing, my preferred solution is restoring the lost
files in postinst. Fortunately, they are all symlinks in the case of
systemd-sysv, so restoring them is a rather simple matter. And this is
what the attached systemd patch does.

> Among the ideas circulated by multiple DDs, the one that seems most
> promising to me was from Julian Andres Klode. He suggests that we add a
> "barrier" package "usrmerge-support". It would have versioned Conflicts
> with molly-guard and systemd-sysv would declare Pre-Depends on
> usrmerge-support. This approach can be used to emulate the semantics
> that I hoped to get from Conflicts, because Pre-Depends imply that at
> the time usrmerge-support.postinst runs, molly-guard must be removed or
> upgraded and systemd-sysv is not yet unpacked. Totally untested though.
> 
> I fear there is not much you can do at this point.

This is not the option I'm going for now. Rather, given that systemd can
paper over the loss we can make the loss very unlikely by having
molly-guard not declare Breaks against systemd-sysv. As a result, apt no
longer sees a mutual conflict and no longer schedules temporary removal.
Thus, the loss scenario (usually) does not happen (though systemd-sysv
still mitigates it).

Not having Breaks comes at a cost though. Now the trixie molly-guard
must work with the bookworm systemd-sysv that still places the diverted
files in /sbin rather than /sbin. Remember that we earlier learned that
the diversion targets must differ in more than aliasing, so molly-guard
must now deal with locating diverted tools in two distinct locations,
which kinda is ugly, but practically works.

This also implies that the duplicated diversions are not as temporary as
we wished. We cannot just delete the aliased ones in postinst. We have
to keep them throughout the trixie release. Without loss of generality,
we'll divert tools like this:

/usr/sbin/halt -> /usr/sbin/halt.no-molly-guard
/sbin/halt -> /sbin/halt.no-molly-guard.usr-is-merged

The latter of these can be removed after trixie and the former is
permanent.

Emilio noticed that we must call the diverted tools by their true name.
While systemd uses strstr and this happens to work, sysvinit-core uses
strcmp, so we need to provide the exact argv[0]. Unfortunately "exec -a"
is as bash feature not supported by POSIX shells such as dash. I've
refrained from changing the shell interpreter from sh to bash and
instead invoke bash for the purpose of performing that "exec -a".
Changing it to become a bash script would also work.

Testing. I've significantly improved my earlier tests to understand many
of the situations. I've also significantly changed the test scenarios
(given that we also have to test a changed systemd-sysv now). All of
these pass now. None of the tests invoke the systemd mitigation (as
expected since molly-guard no longer Breaks). I've run molly-guard
through piuparts and installed it into a VM and manually performed these
tests:
 * local poweroff
 * poweroff via ssh asks for hostname
 * poweroff --help # verified output
 * poweroff --invalidarg # proper error message
 * poweroff '--invalid --arg' # no accidental word splitting
Finally, I ran the reproducer from #1057220 and verified that the
mitigation in systemd-sysv actually is invoked and works.

So now I am attaching the result of my work. I invite people to review
it (even though I understand that this is a complex matter). In
particular, I am also interested in what kind of tests I should be
performing in addition. I also encourage you to upload these 

Bug#1056279: Looks like the systemctl links are gone but not the pm-utils ones

2023-12-01 Thread Helmut Grohne
Hi Francois,

On Mon, Nov 27, 2023 at 04:05:55PM -0800, Francois Marier wrote:
> On 2023-11-27 at 03:54:16, Helmut Grohne (hel...@subdivi.de) wrote:
> > I don't have time to update the patch right now. Let me promise an update
> > this week, ok?

I am very sorry to break this promise. It's complicated.

> My apologies for not responding earlier, but this is a rather thorny problem
> to solve and I have not had the mental "bandwidth" to dig into this yet.
> 
> I wanted however to express my sincere appreciation for all of the work you
> have put into both understanding this problem and coming up with a solution.

Well, in essence I am driving the completion of the /usr-merge
transition. You may argue that I have caused all this trouble even if
that is an oversimplification. The way you support solving this matter
is appreciated. I fully understand that fixing this requires significant
effort that you cannot just provide spontaneously.

So there will be no patch for now, because there still are unsolved
problems. While looking into Emilio's problem and fixing the version
constraints, I figured that test cases are failing. In particular, there
are situations where dpkg unpacks systemd-sysv from unstable at a time
where molly-guard from bookworm is still unpacked. This causes files
from systemd-sysv to be irrevocably lost. I fear we're going back to the
drawing board. If you want details, try #1057199, but I caution that
it's not for the faint of heart and I already have apt and dpkg
developers assist, which is awesome.

Among the ideas circulated by multiple DDs, the one that seems most
promising to me was from Julian Andres Klode. He suggests that we add a
"barrier" package "usrmerge-support". It would have versioned Conflicts
with molly-guard and systemd-sysv would declare Pre-Depends on
usrmerge-support. This approach can be used to emulate the semantics
that I hoped to get from Conflicts, because Pre-Depends imply that at
the time usrmerge-support.postinst runs, molly-guard must be removed or
upgraded and systemd-sysv is not yet unpacked. Totally untested though.

I fear there is not much you can do at this point.

Let me also clarify that I am not really looking into this for
molly-guard's sake. For one thing, molly-guard provides an instance of a
problem class repeated multiple times in the archive. I hope that once
we get molly-guard right, the other instances become easier. For
another, your responsiveness and care is appreciated.

Stay tuned

Helmut



Bug#1056279: Looks like the systemctl links are gone but not the pm-utils ones

2023-11-27 Thread Francois Marier
On 2023-11-27 at 03:54:16, Helmut Grohne (hel...@subdivi.de) wrote:
> I don't have time to update the patch right now. Let me promise an update
> this week, ok?

Hi Helmut,

My apologies for not responding earlier, but this is a rather thorny problem
to solve and I have not had the mental "bandwidth" to dig into this yet.

I wanted however to express my sincere appreciation for all of the work you
have put into both understanding this problem and coming up with a solution.

Francois



Bug#1056279: Looks like the systemctl links are gone but not the pm-utils ones

2023-11-27 Thread Helmut Grohne
Hi,

On Sat, Nov 25, 2023 at 12:50:26AM +0100, Helmut Grohne wrote:
> Hope this is good. Would you mind uploading it to experimental?

I sat down with Emilio and had him review (big thanks!) my patch and
while he thinks that my problem analysis and diversion management will
now work, he figured another problem.

A major change is that we now rename the diverted files in the same
directory rather than keeping the name in a different directory to avoid
breaking symbolic links. Unfortunately, systemctl uses the program name
to figure out what it should be doing and it has no clue what
"halt.no-molly-guard" is supposed to mean. So when we run the original
program, we need to now run it with exec -a $cmd $cmd.no-molly-guard. I
don't have time to update the patch right now. Let me promise an update
this week, ok?

Helmut



Bug#1056279: Looks like the systemctl links are gone but not the pm-utils ones

2023-11-24 Thread Helmut Grohne
Hi,

On Mon, Nov 20, 2023 at 04:05:31PM +0100, Helmut Grohne wrote:
> I've attached the prospective change to this mail. It passes piuparts
> and it passes my own test cases. I definitely think it should be
> reviewed before uploaded. One thing I already see for possible
> improvement is that since we declare Breaks against all providers of
> /sbin/halt, this diversion does not actually have to persist beyond
> postinst. Once molly-guard is configured, we know that any broken
> package is no longer installed nor unpacked. A molly-guard.postinst
> could remove the diversion of /sbin/halt to
> /sbin/halt.no-molly-guard.usr-is-merged. Then we are only left with one
> diversion per command which also makes this a lot less confusing.

I have implemented the removal of unnecessary diversions in postinst and
attach an updated patch. It still passes all of the tests from my
earlier mail and also piuparts.

> More fundamentally, I'll also have to rework the DEP17 section M18 as it
> doesn't work the way it is currently pictured.

I updated it.

Hope this is good. Would you mind uploading it to experimental?

Helmut
diff -Nru molly-guard-0.8.1/debian/changelog 
molly-guard-0.8.1+nmu1/debian/changelog
--- molly-guard-0.8.1/debian/changelog  2023-11-11 23:02:55.0 +0100
+++ molly-guard-0.8.1+nmu1/debian/changelog 2023-11-20 09:18:25.0 
+0100
@@ -1,3 +1,10 @@
+molly-guard (0.8.1+nmu1) UNRELEASED; urgency=medium
+
+  * Non-maintainer upload.
+  * Attempt to fix the /usr-merge fallout. (Closes: #1056279)
+
+ -- Helmut Grohne   Mon, 20 Nov 2023 09:18:25 +0100
+
 molly-guard (0.8.1) unstable; urgency=medium
 
   * Upload to unstable
diff -Nru molly-guard-0.8.1/debian/control molly-guard-0.8.1+nmu1/debian/control
--- molly-guard-0.8.1/debian/control2023-11-11 23:02:55.0 +0100
+++ molly-guard-0.8.1+nmu1/debian/control   2023-11-20 09:18:25.0 
+0100
@@ -23,6 +23,7 @@
   systemd,
   sysvinit,
   upstart
+Breaks: systemd-sysv (<< 255), sysvinit-core, finit-sysv, runit-init
 Description: protects machines from accidental shutdowns/reboots
  The package installs a shell script that overrides the existing
  shutdown/reboot/halt/poweroff/coldreboot/pm-hibernate/pm-suspend* commands
diff -Nru molly-guard-0.8.1/debian/molly-guard.postinst 
molly-guard-0.8.1+nmu1/debian/molly-guard.postinst
--- molly-guard-0.8.1/debian/molly-guard.postinst   1970-01-01 
01:00:00.0 +0100
+++ molly-guard-0.8.1+nmu1/debian/molly-guard.postinst  2023-11-20 
09:18:25.0 +0100
@@ -0,0 +1,14 @@
+#!/bin/sh
+set -e
+
+# begin-remove-after: trixie
+if test "$1" = configure; then
+for cmd in halt poweroff reboot shutdown coldreboot; do
+dpkg-divert --package molly-guard --no-rename --remove "/sbin/$cmd"
+done
+fi
+# end-remove-after
+
+#DEBHELPER#
+
+exit 0
diff -Nru molly-guard-0.8.1/debian/molly-guard.postrm 
molly-guard-0.8.1+nmu1/debian/molly-guard.postrm
--- molly-guard-0.8.1/debian/molly-guard.postrm 2023-11-11 23:02:55.0 
+0100
+++ molly-guard-0.8.1+nmu1/debian/molly-guard.postrm2023-11-20 
09:18:25.0 +0100
@@ -16,18 +16,19 @@
 # for details, see http://www.debian.org/doc/debian-policy/ or
 # the debian-policy package
 
-
+# begin-remove-after: trixie
 case "$1" in
-remove)
-for cmd in halt poweroff reboot shutdown coldreboot ; do
-dpkg-divert --package molly-guard --no-rename --remove /sbin/$cmd
-dpkg-divert --package molly-guard --no-rename --remove 
"/usr/sbin/$cmd"
-   if test -e "/usr/lib/molly-guard/$cmd"; then
-mv "/usr/lib/molly-guard/$cmd" "/usr/sbin/$cmd"
-fi
+abort-install|abort-upgrade|failed-upgrade)
+for cmd in halt poweroff shutdown coldreboot; do
+dpkg-divert --package molly-guard --rename --remove "/sbin/$cmd"
 done
+;;
+esac
+# end-remove-after
 
-for cmd in pm-hibernate pm-suspend pm-suspend-hybrid ; do
+case "$1" in
+remove)
+for cmd in halt poweroff reboot shutdown coldreboot pm-hibernate 
pm-suspend pm-suspend-hybrid ; do
 dpkg-divert --package molly-guard --rename --remove /usr/sbin/$cmd
 done
 
diff -Nru molly-guard-0.8.1/debian/molly-guard.preinst 
molly-guard-0.8.1+nmu1/debian/molly-guard.preinst
--- molly-guard-0.8.1/debian/molly-guard.preinst2023-11-11 
23:02:55.0 +0100
+++ molly-guard-0.8.1+nmu1/debian/molly-guard.preinst   2023-11-20 
09:18:25.0 +0100
@@ -14,35 +14,55 @@
 
 case "$1" in
 install|upgrade)
-mkdir -p /usr/lib/molly-guard
-
 # Cleanup erroneous diversions added in 0.6.0
 for cmd in pm-hibernate pm-suspend pm-suspend-hybrid ; do
 dpkg-divert --package molly-guard --rename --remove /sbin/$cmd
 done
 
 for cmd in halt poweroff reboot shutdown coldreboot ; do
-dpkg-divert --package molly-guard --divert 
"/usr/lib/molly-guard/$cmd" --no-rename --add 

Bug#1056279: Looks like the systemctl links are gone but not the pm-utils ones

2023-11-20 Thread Helmut Grohne
Hi,

I've spend the better part of today on this thanks to Freexian.

On Mon, Nov 20, 2023 at 12:35:58AM +0100, Helmut Grohne wrote:
> Different reproducer:
> 
> mmdebstrap trixie /dev/null http://deb.debian.org/debian 
> --include=systemd-sysv,molly-guard --customize-hook='sed -i -e s/trixie/sid/ 
> $1/etc/apt/sources.list' --chrooted-customize-hook='apt-get update' 
> --customize-hook='test -e $1/lib/molly-guard/reboot' 
> --chrooted-customize-hook='apt-get -y install systemd-sysv' 
> --customize-hook='ls -l $1/lib/molly-guard/'

> I've dug into dpkg and usually when it moves a file from / to /usr,
> it'll first unpack the new file (unknowingly replacing the existing old
> one) and then removes the old one (via pkg_remove_old_files). During
> that removal, it has a check to see whether the file to be removed
> happens to match one of the files it just installed and skips the
> removal in that case. For some reason, this safety check does not work
> when the file is diverted.

I retried this a few times and still think it is correct. As a
consequence, the original approach of duplicating diversions cannot work
at all. As soon as we have two diversions whose targets equal up to
aliasing, we run into this problem and to make matters worse, we are
loosing a file that we just unpacked. We have no way of keeping (and
later restoring) it via any kind of maintainer scripts. Therefore we
really cannot do the duplicate diversion approach. It was a nice idea,
but doesn't work. Back to the drawing board.

We still must have two diversions to as unpacking either of the
locations from another package would clobber the location we want
diverted. What changes is that the diversion targets must differ in more
than aliasing.

I think an example would help. Say we divert /sbin/halt. We must divert
both /sbin/halt and /usr/sbin/halt or we risk clobbering our copy. If we
divert the latter to /usr/lib/molly-guard/halt, we must not divert the
former to /lib/molly-guard/halt or the file will be lost in unpack. So
the later might become /lib/molly-guard/halt.usr-is-merged or something.

This is fairly inconvenient as molly-guard doesn't know about
halt.usr-is-merged. I think there is three possible ways to deal with
this:
 a) molly-guard tries both locations.
 b) We add a dpkg-trigger on /sbin/halt such that when
/usr/lib/molly-guard/halt is missing but
/lib/molly-guard/halt.usr-is-merged is not, we can add a symlink.
 c) We give up on supporting /sbin/halt (as opposed to /usr/sbin/halt)
and simply declare Breaks against any provider of /sbin/halt.

I argue that we should be selecting that last option, because /sbin/halt
is something that we want to go away entirely. When we release trixie,
we want all of them moved to /usr/sbin/halt. So we'd have versioned
Breaks for systemd-sysv, sysvinit-core, runit-init and finit-sysv. Note
that since Breaks does not prevent concurrent unpack, we must still
install the extra diversion. Note that since the other package must
declare Conflicts with molly-guard, molly-guard cannot use Conflicts
without impacting upgrades. The mutual conflict would require apt to
temporarily remove molly-guard (or /sbin/init!) and that is known to
impact upgrades.  Also note that since sysvinit-core and others have not
yet moved, molly-guard must now declare unversioned Breaks for all of
them for as long as they have not moved and once they moved, it can add
a version to the Breaks.

So I went ahead an implemented this. Since I didn't want to fall into my
trap of too little testing again, I wrote some test cases (attached) and
to my surprise found another problem!

/sbin/halt actually is a symbolic link to /bin/systemctl. In 255,
/usr/sbin/halt becomes a symlink to ../bin/systemctl. Observe how we
turned an absolute symlink into a relative once since we no longer
cross a toplevel directory in line with policy. As we move this relative
symlink to /usr/lib/molly-guard, it becomes a broken symbolic link. So
if you now install molly-guard and systemd-sysv in unstable, these links
are gone. You may then reinstall systemd-sysv and see them reinstated.
And now they're broken.

There is no easy way to fix this beyond moving these programs to a
different name in the same directory. I suggest
/usr/sbin/halt.no-molly-guard. Appending a suffix is what most
diversions do and this avoids breaking symlinks.

I've attached the prospective change to this mail. It passes piuparts
and it passes my own test cases. I definitely think it should be
reviewed before uploaded. One thing I already see for possible
improvement is that since we declare Breaks against all providers of
/sbin/halt, this diversion does not actually have to persist beyond
postinst. Once molly-guard is configured, we know that any broken
package is no longer installed nor unpacked. A molly-guard.postinst
could remove the diversion of /sbin/halt to
/sbin/halt.no-molly-guard.usr-is-merged. Then we are only left with one
diversion per command which also 

Bug#1056279: Looks like the systemctl links are gone but not the pm-utils ones

2023-11-19 Thread Helmut Grohne
Control: tags -1 + confirmed
Control: clone -1 -2
Control: reassign -2 systemd-sysv
Control: found -2 255-rc2-1
Control: retitle -2 duplicated diversions are still broken by moved files

On Sun, Nov 19, 2023 at 02:08:35PM -0800, Francois Marier wrote:
> I'm also a little confused by the diverts. Perhaps something changed in
> systemd (which owns the ultimate underlying symlinks)?

I was sure I had this properly tested and yet it doesn't work as
expected. I'm sorry for having gotten this wrong.

Reproducer:

mmdebstrap bookworm /dev/null http://deb.debian.org/debian 
--include=systemd-sysv,molly-guard --customize-hook='sed -i -e s/bookworm/sid/ 
$1/etc/apt/sources.list' --chrooted-customize-hook='apt-get update' 
--chrooted-customize-hook='apt-get -y install systemd-sysv' 
--customize-hook='ls -l $1/lib/molly-guard/'

Different reproducer:

mmdebstrap trixie /dev/null http://deb.debian.org/debian 
--include=systemd-sysv,molly-guard --customize-hook='sed -i -e s/trixie/sid/ 
$1/etc/apt/sources.list' --chrooted-customize-hook='apt-get update' 
--customize-hook='test -e $1/lib/molly-guard/reboot' 
--chrooted-customize-hook='apt-get -y install systemd-sysv' 
--customize-hook='ls -l $1/lib/molly-guard/'

Specifically, the files vanish on upgrading systemd-sysv such that
/sbin/reboot moves to /usr/sbin/reboot. I should have seen this failure
in earlier tests.

I've dug into dpkg and usually when it moves a file from / to /usr,
it'll first unpack the new file (unknowingly replacing the existing old
one) and then removes the old one (via pkg_remove_old_files). During
that removal, it has a check to see whether the file to be removed
happens to match one of the files it just installed and skips the
removal in that case. For some reason, this safety check does not work
when the file is diverted.

So I have a vague understanding of what is wrong here, but no solution
yet. For the time being, I duplicate this into a blocker bug for
systemd-sysv to prevent it from migrating to testing until we figure out
a solution.

Sorry for the inconvenience.

Helmut



Bug#1056279: Looks like the systemctl links are gone but not the pm-utils ones

2023-11-19 Thread Francois Marier
CCing Helmut who wrote the initial patch for systemd 255+ support (see
Bug#1055510).

I also see the same thing:

$ ls -lh /usr/lib/molly-guard/
Permissions Size User Group Date Modified Name
.rwxr-xr-x  3,4k root root  11 nov 14:02  molly-guard*
lrwxrwxrwx31 root root  14 nov  2019  pm-hibernate -> 
/usr/lib/pm-utils/bin/pm-action*
lrwxrwxrwx31 root root  14 nov  2019  pm-suspend -> 
/usr/lib/pm-utils/bin/pm-action*
lrwxrwxrwx31 root root  14 nov  2019  pm-suspend-hybrid -> 
/usr/lib/pm-utils/bin/pm-action*

$ sudo reboot --help
E: not a regular file: /usr/lib/molly-guard/reboot

I'm also a little confused by the diverts. Perhaps something changed in
systemd (which owns the ultimate underlying symlinks)?

Francois

-- 
https://fmarier.org/