mirror of
https://github.com/sheumann/hush.git
synced 2024-12-24 12:29:47 +00:00
tar: add support for PAX-encoded path=LONGFILENAME
function old new delta get_header_tar 1478 1759 +281 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
af36ba206f
commit
6111f967f5
@ -13,13 +13,13 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
|
|||||||
int res;
|
int res;
|
||||||
|
|
||||||
#if ENABLE_FEATURE_TAR_SELINUX
|
#if ENABLE_FEATURE_TAR_SELINUX
|
||||||
char *sctx = archive_handle->tar__next_file_sctx;
|
char *sctx = archive_handle->tar__sctx[PAX_NEXT_FILE];
|
||||||
if (!sctx)
|
if (!sctx)
|
||||||
sctx = archive_handle->tar__global_sctx;
|
sctx = archive_handle->tar__sctx[PAX_GLOBAL];
|
||||||
if (sctx) { /* setfscreatecon is 4 syscalls, avoid if possible */
|
if (sctx) { /* setfscreatecon is 4 syscalls, avoid if possible */
|
||||||
setfscreatecon(sctx);
|
setfscreatecon(sctx);
|
||||||
free(archive_handle->tar__next_file_sctx);
|
free(archive_handle->tar__sctx[PAX_NEXT_FILE]);
|
||||||
archive_handle->tar__next_file_sctx = NULL;
|
archive_handle->tar__sctx[PAX_NEXT_FILE] = NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -64,13 +64,13 @@ void FAST_FUNC data_extract_to_command(archive_handle_t *archive_handle)
|
|||||||
file_header_t *file_header = archive_handle->file_header;
|
file_header_t *file_header = archive_handle->file_header;
|
||||||
|
|
||||||
#if 0 /* do we need this? ENABLE_FEATURE_TAR_SELINUX */
|
#if 0 /* do we need this? ENABLE_FEATURE_TAR_SELINUX */
|
||||||
char *sctx = archive_handle->tar__next_file_sctx;
|
char *sctx = archive_handle->tar__sctx[PAX_NEXT_FILE];
|
||||||
if (!sctx)
|
if (!sctx)
|
||||||
sctx = archive_handle->tar__global_sctx;
|
sctx = archive_handle->tar__sctx[PAX_GLOBAL];
|
||||||
if (sctx) { /* setfscreatecon is 4 syscalls, avoid if possible */
|
if (sctx) { /* setfscreatecon is 4 syscalls, avoid if possible */
|
||||||
setfscreatecon(sctx);
|
setfscreatecon(sctx);
|
||||||
free(archive_handle->tar__next_file_sctx);
|
free(archive_handle->tar__sctx[PAX_NEXT_FILE]);
|
||||||
archive_handle->tar__next_file_sctx = NULL;
|
archive_handle->tar__sctx[PAX_NEXT_FILE] = NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -90,23 +90,20 @@ static unsigned long long getOctal(char *str, int len)
|
|||||||
}
|
}
|
||||||
#define GET_OCTAL(a) getOctal((a), sizeof(a))
|
#define GET_OCTAL(a) getOctal((a), sizeof(a))
|
||||||
|
|
||||||
#if ENABLE_FEATURE_TAR_SELINUX
|
/* "global" is 0 or 1 */
|
||||||
/* Scan a PAX header for SELinux contexts, via "RHT.security.selinux" keyword.
|
static void process_pax_hdr(archive_handle_t *archive_handle, unsigned sz, int global)
|
||||||
* 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)
|
|
||||||
{
|
{
|
||||||
char *buf, *p;
|
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 */
|
/* prevent bb_strtou from running off the buffer */
|
||||||
buf[sz] = '\0';
|
buf[sz] = '\0';
|
||||||
xread(archive_handle->src_fd, buf, sz);
|
|
||||||
archive_handle->offset += sz;
|
|
||||||
|
|
||||||
result = NULL;
|
|
||||||
while (sz != 0) {
|
while (sz != 0) {
|
||||||
char *end, *value;
|
char *end, *value;
|
||||||
unsigned len;
|
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)
|
* (we do not bother to check that it *was* a newline)
|
||||||
*/
|
*/
|
||||||
p[-1] = '\0';
|
p[-1] = '\0';
|
||||||
/* Is it selinux security context? */
|
|
||||||
value = end + 1;
|
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) {
|
if (strncmp(value, SELINUX_CONTEXT_KEYWORD"=", sizeof(SELINUX_CONTEXT_KEYWORD"=") - 1) == 0) {
|
||||||
value += sizeof(SELINUX_CONTEXT_KEYWORD"=") - 1;
|
value += sizeof(SELINUX_CONTEXT_KEYWORD"=") - 1;
|
||||||
result = xstrdup(value);
|
free(archive_handle->tar__sctx[global]);
|
||||||
break;
|
archive_handle->tar__sctx[global] = xstrdup(value);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
free(buf);
|
free(buf);
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
char FAST_FUNC get_header_tar(archive_handle_t *archive_handle)
|
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 'S': /* Sparse file */
|
||||||
case 'V': /* Volume header */
|
case 'V': /* Volume header */
|
||||||
#endif
|
#endif
|
||||||
#if !ENABLE_FEATURE_TAR_SELINUX
|
|
||||||
case 'g': /* pax global header */
|
case 'g': /* pax global header */
|
||||||
case 'x': /* pax extended header */
|
case 'x': { /* pax extended header */
|
||||||
#else
|
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:
|
skip_ext_hdr:
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
off_t sz;
|
off_t sz;
|
||||||
bb_error_msg("warning: skipping header '%c'", tar.typeflag);
|
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); */
|
/* return get_header_tar(archive_handle); */
|
||||||
goto again_after_align;
|
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:
|
default:
|
||||||
bb_error_msg_and_die("unknown typeflag: 0x%x", tar.typeflag);
|
bb_error_msg_and_die("unknown typeflag: 0x%x", tar.typeflag);
|
||||||
}
|
}
|
||||||
|
@ -77,19 +77,20 @@ typedef struct archive_handle_t {
|
|||||||
off_t offset;
|
off_t offset;
|
||||||
|
|
||||||
/* Archiver specific. Can make it a union if it ever gets big */
|
/* Archiver specific. Can make it a union if it ever gets big */
|
||||||
|
#define PAX_NEXT_FILE 0
|
||||||
|
#define PAX_GLOBAL 1
|
||||||
#if ENABLE_TAR || ENABLE_DPKG || ENABLE_DPKG_DEB
|
#if ENABLE_TAR || ENABLE_DPKG || ENABLE_DPKG_DEB
|
||||||
smallint tar__end;
|
smallint tar__end;
|
||||||
# if ENABLE_FEATURE_TAR_GNU_EXTENSIONS
|
# if ENABLE_FEATURE_TAR_GNU_EXTENSIONS
|
||||||
char* tar__longname;
|
char* tar__longname;
|
||||||
char* tar__linkname;
|
char* tar__linkname;
|
||||||
# endif
|
# endif
|
||||||
#if ENABLE_FEATURE_TAR_TO_COMMAND
|
# if ENABLE_FEATURE_TAR_TO_COMMAND
|
||||||
char* tar__to_command;
|
char* tar__to_command;
|
||||||
const char* tar__to_command_shell;
|
const char* tar__to_command_shell;
|
||||||
#endif
|
# endif
|
||||||
# if ENABLE_FEATURE_TAR_SELINUX
|
# if ENABLE_FEATURE_TAR_SELINUX
|
||||||
char* tar__global_sctx;
|
char* tar__sctx[2];
|
||||||
char* tar__next_file_sctx;
|
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
#if ENABLE_CPIO || ENABLE_RPM2CPIO || ENABLE_RPM
|
#if ENABLE_CPIO || ENABLE_RPM2CPIO || ENABLE_RPM
|
||||||
|
Loading…
Reference in New Issue
Block a user