mirror of
https://git.savannah.gnu.org/git/tar.git
synced 2026-09-20 15:14:14 +00:00
Port more code to UBSan, and fix alignment bug
Problem with extract_file reported by Kirill Furman in: https://lists.gnu.org/r/bug-tar/2025-07/msg00003.html Since the UBSan thing seems to be a recurring issue, I fixed other instances of the problem that I found. Also, I noticed that the same line of code had another failure to conform to C23’s rules for pointers (an alignment issue not caught by UBSan), so I fixed that too. None of these issues matter on practical production hosts. * src/common.h (charptr): New function. * src/buffer.c (available_space_after, short_read, flush_archive) (backspace_output, try_new_volume, simple_flush_read) (_gnu_flush_read, _gnu_flush_write): * src/compare.c (read_and_process): * src/create.c (write_eot, write_gnu_long_link) (dump_regular_file, dump_dir0): * src/extract.c (extract_file): * src/incremen.c (get_gnu_dumpdir): * src/list.c (read_header): * src/sparse.c (sparse_dump_region, sparse_extract_region): * src/system.c (sys_write_archive_buffer) (sys_child_open_for_compress, sys_child_open_for_uncompress): * src/update.c (append_file, update_archive): Use it. * src/buffer.c (set_next_block_after): Arg is now void *, not union block *, since it need not be a valid union block * pointer and this can matter on unusual or debugging implementations. Turn a loop into an if so that the code is O(1) not O(N).
This commit is contained in:
+11
-11
@@ -473,7 +473,7 @@ write_eot (void)
|
||||
memset (pointer->buffer, 0, BLOCKSIZE);
|
||||
set_next_block_after (pointer);
|
||||
pointer = find_next_block ();
|
||||
memset (pointer->buffer, 0, available_space_after (pointer));
|
||||
memset (charptr (pointer), 0, available_space_after (pointer));
|
||||
set_next_block_after (pointer);
|
||||
}
|
||||
|
||||
@@ -540,16 +540,16 @@ write_gnu_long_link (struct tar_stat_info *st, const char *p, char type)
|
||||
|
||||
while (bufsize < size)
|
||||
{
|
||||
memcpy (header->buffer, p, bufsize);
|
||||
memcpy (charptr (header), p, bufsize);
|
||||
p += bufsize;
|
||||
size -= bufsize;
|
||||
set_next_block_after (header + ((bufsize - 1) >> LG_BLOCKSIZE));
|
||||
set_next_block_after (charptr (header) + bufsize - 1);
|
||||
header = find_next_block ();
|
||||
bufsize = available_space_after (header);
|
||||
}
|
||||
memcpy (header->buffer, p, size);
|
||||
memset (header->buffer + size, 0, bufsize - size);
|
||||
set_next_block_after (header + ((size - 1) >> LG_BLOCKSIZE));
|
||||
memcpy (charptr (header), p, size);
|
||||
memset (charptr (header) + size, 0, bufsize - size);
|
||||
set_next_block_after (charptr (header) + size - 1);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1047,16 +1047,16 @@ dump_regular_file (int fd, struct tar_stat_info *st)
|
||||
}
|
||||
|
||||
idx_t count = (fd <= 0 ? bufsize
|
||||
: blocking_read (fd, blk->buffer, bufsize));
|
||||
: blocking_read (fd, charptr (blk), bufsize));
|
||||
size_left -= count;
|
||||
set_next_block_after (blk + ((bufsize - 1) >> LG_BLOCKSIZE));
|
||||
set_next_block_after (charptr (blk) + bufsize - 1);
|
||||
|
||||
if (count != bufsize)
|
||||
{
|
||||
if (errno)
|
||||
read_diag_details (st->orig_file_name,
|
||||
st->stat.st_size - size_left, bufsize);
|
||||
memset (blk->buffer + count, 0, bufsize - count);
|
||||
memset (charptr (blk) + count, 0, bufsize - count);
|
||||
warnopt (WARN_FILE_SHRANK, 0,
|
||||
ngettext (("%s: File shrank by %jd byte;"
|
||||
" padding with zeros"),
|
||||
@@ -1134,10 +1134,10 @@ dump_dir0 (struct tar_stat_info *st, char const *directory)
|
||||
if (count)
|
||||
memset (blk->buffer + size_left, 0, BLOCKSIZE - count);
|
||||
}
|
||||
memcpy (blk->buffer, p_buffer, bufsize);
|
||||
memcpy (charptr (blk), p_buffer, bufsize);
|
||||
size_left -= bufsize;
|
||||
p_buffer += bufsize;
|
||||
set_next_block_after (blk + ((bufsize - 1) >> LG_BLOCKSIZE));
|
||||
set_next_block_after (charptr (blk) + bufsize - 1);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user