The following commit has been merged in the master branch:
commit d25407536dbed4cad2943187b36fbb6c92a6b5ab
Author: Guillem Jover <[email protected]>
Date: Wed Jul 28 15:06:19 2010 +0200
dpkg: Assign correct SE Linux label to non-regular files
The call to matchpathcon() was getting passed only the permission bits
of the mode argument, instead of the format type. Map the tar filetype
to the Unix mode and OR that information into the tar_entry mode member.
Closes: #587949
Based-on-patch-by: Russell Coker <[email protected]>
Signed-off-by: Guillem Jover <[email protected]>
diff --git a/debian/changelog b/debian/changelog
index 9a1248c..28d26d6 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -97,6 +97,8 @@ dpkg (1.15.8) UNRELEASED; urgency=low
* Consistently use earlier/later instead of smaller/bigger when describing
comparison relationships. Closes: #587641
* Stop exporting DPKG_LIBDIR to maintainer scripts, no need for it anymore.
+ * Assign correct SE Linux label on non-regular files. Based on a patch by
+ Russell Coker <[email protected]>. Closes: #587949
[ Updated programs translations ]
* Catalan (Guillem Jover).
diff --git a/lib/dpkg/tarfn.c b/lib/dpkg/tarfn.c
index c24e85d..c5b598d 100644
--- a/lib/dpkg/tarfn.c
+++ b/lib/dpkg/tarfn.c
@@ -22,6 +22,8 @@
#include <config.h>
#include <compat.h>
+#include <sys/stat.h>
+
#include <errno.h>
#include <string.h>
#include <pwd.h>
@@ -111,6 +113,45 @@ get_prefix_name(struct TarHeader *h)
return s;
}
+static mode_t
+get_unix_mode(struct TarHeader *h)
+{
+ mode_t mode;
+ enum tar_filetype type;
+
+ type = (enum tar_filetype)h->LinkFlag;
+
+ switch (type) {
+ case tar_filetype_file0:
+ case tar_filetype_file:
+ mode = S_IFREG;
+ break;
+ case tar_filetype_symlink:
+ mode = S_IFLNK;
+ break;
+ case tar_filetype_dir:
+ mode = S_IFDIR;
+ break;
+ case tar_filetype_chardev:
+ mode = S_IFCHR;
+ break;
+ case tar_filetype_blockdev:
+ mode = S_IFBLK;
+ break;
+ case tar_filetype_fifo:
+ mode = S_IFIFO;
+ break;
+ case tar_filetype_hardlink:
+ default:
+ mode = 0;
+ break;
+ }
+
+ mode |= OtoL(h->Mode, sizeof(h->Mode));
+
+ return mode;
+}
+
static int
DecodeTarHeader(char *block, struct tar_entry *d)
{
@@ -139,7 +180,7 @@ DecodeTarHeader(char *block, struct tar_entry *d)
else
d->name = StoC(h->Name, sizeof(h->Name));
d->linkname = StoC(h->LinkName, sizeof(h->LinkName));
- d->mode = (mode_t)OtoL(h->Mode, sizeof(h->Mode));
+ d->mode = get_unix_mode(h);
d->size = (size_t)OtoL(h->Size, sizeof(h->Size));
d->mtime = (time_t)OtoL(h->ModificationTime,
sizeof(h->ModificationTime));
diff --git a/src/archives.c b/src/archives.c
index 31c5f0c..d1daed4 100644
--- a/src/archives.c
+++ b/src/archives.c
@@ -261,6 +261,10 @@ set_selinux_path_context(const char *matchpath, const char
*path, mode_t mode)
security_context_t scontext = NULL;
int ret;
+ /* If there's no file type, just give up. */
+ if ((mode & S_IFMT) == 0)
+ return;
+
/* Set selinux_enabled if it is not already set (singleton). */
if (selinux_enabled < 0)
selinux_enabled = (is_selinux_enabled() > 0);
@@ -274,7 +278,7 @@ set_selinux_path_context(const char *matchpath, const char
*path, mode_t mode)
/* Do nothing if we can't figure out what the context is, or if it has
* no context; in which case the default context shall be applied. */
- ret = matchpathcon(matchpath, mode & ~S_IFMT, &scontext);
+ ret = matchpathcon(matchpath, mode & S_IFMT, &scontext);
if (ret == -1 || (ret == 0 && scontext == NULL))
return;
@@ -761,9 +765,7 @@ tarobject(void *ctx, struct tar_entry *ti)
internerr("unknown tar type '%d', but already checked", ti->type);
}
- set_selinux_path_context(fnamevb.buf, fnamenewvb.buf,
- nifd->namenode->statoverride ?
- nifd->namenode->statoverride->mode : ti->mode);
+ set_selinux_path_context(fnamevb.buf, fnamenewvb.buf, ti->mode);
/* CLEANUP: Now we have extracted the new object in .dpkg-new (or,
* if the file already exists as a directory and we were trying to extract
--
dpkg's main repository
--
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]