Bug#969076: dpkg: Fails if package containing symlink to network FS is upgraded

2020-09-04 Thread Sven Mueller
Guillem Jover  schrieb am Fr., 4. Sept. 2020, 00:28:

> Hi!
>
> On Thu, 2020-08-27 at 09:19:52 +0200, Sven Mueller wrote:
> > Package: dpkg
> > Version: 1.19.7
> > Tags: patch
>
> > When a package contains a symlink that reaches into a filesystem that
> can't
> > be accessed by root (due to missing key, errno=ENOKEY), installation
> works,
> > removal works, but upgrade or reinstallation of the package doesn't work
> > and fails because dpkg fails to stat the link target.
>
> OOC, why is a pathname that is reference by a .deb, within a
> filesystem that currently has a missing key?
>

Think of Kerberos authenticated NFS. Root (especially in cron jobs) doesn't
have a ticket with access to the link target. Most actual users of the
system do have access.

>
> Patch attached, which fixes this issue, though I suspect other locations
> > should possibly use a similar logic.
> >
> > As far as I understand (also mentioned in the header of the patch), this
> is
> > to avoid unpacking a link into a directory the link originally pointed
> to.
> > If that is the case, the patch should be fine, but I wonder if this
> > shouldn't be handled differently. But I would need to dig into the code
> > much more than I am comfortable with, given that this is C and I don't
> > usually use C. _If_ dpkg unpacks the package into some temporary
> directory
> > first and then moves the files into place, then there should be other
> > options to avoid the behavior mentioned.
>
> I'm not sure this is correct for the general case though, as that
> makes the check inert, which seems wrong?
>

No, it is not inert. It covers the case the test wants to protect against:
if the link target is a directory (as far as root is concerned), unpacking
and archive containing anything that is intended to replace the symlink
would instead unpacking into the directory the link points to. However if
the link points to something root had no access to, unpacking behaves the
same way as if the symlink was dangling (target doesn't exist). Which is
also why I named the patch this way: on overwrite of the symlink, the
kennel behaves the same way as if the target didn't even exist, so dpkg
should do the same.

Cheers,
Sven

>


Bug#969076: dpkg: Fails if package containing symlink to network FS is upgraded

2020-09-03 Thread Guillem Jover
Hi!

On Thu, 2020-08-27 at 09:19:52 +0200, Sven Mueller wrote:
> Package: dpkg
> Version: 1.19.7
> Tags: patch

> When a package contains a symlink that reaches into a filesystem that can't
> be accessed by root (due to missing key, errno=ENOKEY), installation works,
> removal works, but upgrade or reinstallation of the package doesn't work
> and fails because dpkg fails to stat the link target.

OOC, why is a pathname that is reference by a .deb, within a
filesystem that currently has a missing key?

> Patch attached, which fixes this issue, though I suspect other locations
> should possibly use a similar logic.
> 
> As far as I understand (also mentioned in the header of the patch), this is
> to avoid unpacking a link into a directory the link originally pointed to.
> If that is the case, the patch should be fine, but I wonder if this
> shouldn't be handled differently. But I would need to dig into the code
> much more than I am comfortable with, given that this is C and I don't
> usually use C. _If_ dpkg unpacks the package into some temporary directory
> first and then moves the files into place, then there should be other
> options to avoid the behavior mentioned.

I'm not sure this is correct for the general case though, as that
makes the check inert, which seems wrong?

Thanks,
Guillem



Bug#969076: dpkg: Fails if package containing symlink to network FS is upgraded

2020-08-27 Thread Sven Mueller
Package: dpkg
Version: 1.19.7
Tags: patch

When a package contains a symlink that reaches into a filesystem that can't
be accessed by root (due to missing key, errno=ENOKEY), installation works,
removal works, but upgrade or reinstallation of the package doesn't work
and fails because dpkg fails to stat the link target.

Patch attached, which fixes this issue, though I suspect other locations
should possibly use a similar logic.

As far as I understand (also mentioned in the header of the patch), this is
to avoid unpacking a link into a directory the link originally pointed to.
If that is the case, the patch should be fine, but I wonder if this
shouldn't be handled differently. But I would need to dig into the code
much more than I am comfortable with, given that this is C and I don't
usually use C. _If_ dpkg unpacks the package into some temporary directory
first and then moves the files into place, then there should be other
options to avoid the behavior mentioned.

Kind regards,
Sven
Description: When overwriting existing symlinks, treat ENOKEY like ENOENT.
 When trying to overwrite existing symlinks, dpkg tries to stat the target of
 the symlink to check if it points to a directory. Treate ENOKEY like ENOENT,
 as the point of the check is to ensure that the new file doesn't end up in the
 directory the symlink could be pointing to.
Author: Sven Mueller 
Last-Update: 2020-08-26
---
Index: dpkg-1.19.7/src/archives.c
===
--- dpkg-1.19.7.orig/src/archives.c
+++ dpkg-1.19.7/src/archives.c
@@ -626,7 +626,8 @@ linktosameexistingdir(const struct tar_e
 
   statr= stat(fname, );
   if (statr) {
-if (!(errno == ENOENT || errno == ELOOP || errno == ENOTDIR))
+if (!(errno == ENOENT || errno == ELOOP || errno == ENOTDIR ||
+  errno == ENOKEY))
   ohshite(_("failed to stat (dereference) existing symlink '%.250s'"),
   fname);
 return false;