|
@@ -90,23 +90,20 @@ static unsigned long long getOctal(char *str, int len)
|
|
|
}
|
|
|
#define GET_OCTAL(a) getOctal((a), sizeof(a))
|
|
|
|
|
|
-#if ENABLE_FEATURE_TAR_SELINUX
|
|
|
-/* Scan a PAX header for SELinux contexts, via "RHT.security.selinux" keyword.
|
|
|
- * This is what Red Hat's patched version of tar uses.
|
|
|
- */
|
|
|
-# define SELINUX_CONTEXT_KEYWORD "RHT.security.selinux"
|
|
|
-static char *get_selinux_sctx_from_pax_hdr(archive_handle_t *archive_handle, unsigned sz)
|
|
|
+/* "global" is 0 or 1 */
|
|
|
+static void process_pax_hdr(archive_handle_t *archive_handle, unsigned sz, int global)
|
|
|
{
|
|
|
char *buf, *p;
|
|
|
- char *result;
|
|
|
+ unsigned blk_sz;
|
|
|
+
|
|
|
+ blk_sz = (sz + 511) & (~511);
|
|
|
+ p = buf = xmalloc(blk_sz + 1);
|
|
|
+ xread(archive_handle->src_fd, buf, blk_sz);
|
|
|
+ archive_handle->offset += blk_sz;
|
|
|
|
|
|
- p = buf = xmalloc(sz + 1);
|
|
|
/* prevent bb_strtou from running off the buffer */
|
|
|
buf[sz] = '\0';
|
|
|
- xread(archive_handle->src_fd, buf, sz);
|
|
|
- archive_handle->offset += sz;
|
|
|
|
|
|
- result = NULL;
|
|
|
while (sz != 0) {
|
|
|
char *end, *value;
|
|
|
unsigned len;
|
|
@@ -133,19 +130,33 @@ static char *get_selinux_sctx_from_pax_hdr(archive_handle_t *archive_handle, uns
|
|
|
* (we do not bother to check that it *was* a newline)
|
|
|
*/
|
|
|
p[-1] = '\0';
|
|
|
- /* Is it selinux security context? */
|
|
|
value = end + 1;
|
|
|
+
|
|
|
+#if ENABLE_FEATURE_TAR_GNU_EXTENSIONS
|
|
|
+ if (!global && strncmp(value, "path=", sizeof("path=") - 1) == 0) {
|
|
|
+ value += sizeof("path=") - 1;
|
|
|
+ free(archive_handle->tar__longname);
|
|
|
+ archive_handle->tar__longname = xstrdup(value);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
+#if ENABLE_FEATURE_TAR_SELINUX
|
|
|
+ /* Scan for SELinux contexts, via "RHT.security.selinux" keyword.
|
|
|
+ * This is what Red Hat's patched version of tar uses.
|
|
|
+ */
|
|
|
+# define SELINUX_CONTEXT_KEYWORD "RHT.security.selinux"
|
|
|
if (strncmp(value, SELINUX_CONTEXT_KEYWORD"=", sizeof(SELINUX_CONTEXT_KEYWORD"=") - 1) == 0) {
|
|
|
value += sizeof(SELINUX_CONTEXT_KEYWORD"=") - 1;
|
|
|
- result = xstrdup(value);
|
|
|
- break;
|
|
|
+ free(archive_handle->tar__sctx[global]);
|
|
|
+ archive_handle->tar__sctx[global] = xstrdup(value);
|
|
|
+ continue;
|
|
|
}
|
|
|
+#endif
|
|
|
}
|
|
|
|
|
|
free(buf);
|
|
|
- return result;
|
|
|
}
|
|
|
-#endif
|
|
|
|
|
|
char FAST_FUNC get_header_tar(archive_handle_t *archive_handle)
|
|
|
{
|
|
@@ -418,12 +429,14 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle)
|
|
|
case 'S': /* Sparse file */
|
|
|
case 'V': /* Volume header */
|
|
|
#endif
|
|
|
-#if !ENABLE_FEATURE_TAR_SELINUX
|
|
|
case 'g': /* pax global header */
|
|
|
- case 'x': /* pax extended header */
|
|
|
-#else
|
|
|
+ case 'x': { /* pax extended header */
|
|
|
+ if ((uoff_t)file_header->size > 0xfffff) /* paranoia */
|
|
|
+ goto skip_ext_hdr;
|
|
|
+ process_pax_hdr(archive_handle, file_header->size, (tar.typeflag == 'g'));
|
|
|
+ goto again_after_align;
|
|
|
+ }
|
|
|
skip_ext_hdr:
|
|
|
-#endif
|
|
|
{
|
|
|
off_t sz;
|
|
|
bb_error_msg("warning: skipping header '%c'", tar.typeflag);
|
|
@@ -435,18 +448,6 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle)
|
|
|
/* return get_header_tar(archive_handle); */
|
|
|
goto again_after_align;
|
|
|
}
|
|
|
-#if ENABLE_FEATURE_TAR_SELINUX
|
|
|
- case 'g': /* pax global header */
|
|
|
- case 'x': { /* pax extended header */
|
|
|
- char **pp;
|
|
|
- if ((uoff_t)file_header->size > 0xfffff) /* paranoia */
|
|
|
- goto skip_ext_hdr;
|
|
|
- pp = (tar.typeflag == 'g') ? &archive_handle->tar__global_sctx : &archive_handle->tar__next_file_sctx;
|
|
|
- free(*pp);
|
|
|
- *pp = get_selinux_sctx_from_pax_hdr(archive_handle, file_header->size);
|
|
|
- goto again;
|
|
|
- }
|
|
|
-#endif
|
|
|
default:
|
|
|
bb_error_msg_and_die("unknown typeflag: 0x%x", tar.typeflag);
|
|
|
}
|