From 2412c8ed80e1283657c97d156061beac04849eb5 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Fri, 17 May 2013 23:25:42 -0500 Subject: [PATCH 1/1] Win32: Fix reparse point fixup bugs --- include/wimlib/reparse.h | 3 ++- src/reparse.c | 9 ++++++--- src/win32_apply.c | 15 +++++++-------- src/win32_capture.c | 6 ++---- 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/include/wimlib/reparse.h b/include/wimlib/reparse.h index ff422a1d..577e932a 100644 --- a/include/wimlib/reparse.h +++ b/include/wimlib/reparse.h @@ -58,7 +58,8 @@ parse_reparse_data(const u8 * restrict rpbuf, u16 rpbuflen, extern int make_reparse_buffer(const struct reparse_data * restrict rpdata, - u8 * restrict rpbuf); + u8 * restrict rpbuf, + u16 * restrict rpbuflen_ret); extern int wim_inode_get_reparse_data(const struct wim_inode * restrict inode, diff --git a/src/reparse.c b/src/reparse.c index b097212a..46590017 100644 --- a/src/reparse.c +++ b/src/reparse.c @@ -215,7 +215,8 @@ out_invalid: */ int make_reparse_buffer(const struct reparse_data * restrict rpdata, - u8 * restrict rpbuf) + u8 * restrict rpbuf, + u16 * restrict rpbuflen_ret) { struct reparse_buffer_disk *rpbuf_disk = (struct reparse_buffer_disk*)rpbuf; @@ -252,6 +253,7 @@ make_reparse_buffer(const struct reparse_data * restrict rpdata, *(utf16lechar*)data = cpu_to_le16(0); data += 2; rpbuf_disk->rpdatalen = cpu_to_le16(data - rpbuf - 8); + *rpbuflen_ret = data - rpbuf; return 0; } @@ -399,6 +401,7 @@ wim_inode_set_symlink(struct wim_inode *inode, utf16lechar *name_utf16le; size_t name_utf16le_nbytes; int ret; + u16 rpbuflen; DEBUG("Creating reparse point data buffer for UNIX " "symlink target \"%s\"", target); @@ -481,11 +484,11 @@ wim_inode_set_symlink(struct wim_inode *inode, rpdata.rpflags = SYMBOLIC_LINK_RELATIVE; } - ret = make_reparse_buffer(&rpdata, (u8*)&rpbuf_disk); + ret = make_reparse_buffer(&rpdata, (u8*)&rpbuf_disk, &rpbuflen); if (ret == 0) { ret = inode_set_unnamed_stream(inode, (u8*)&rpbuf_disk + 8, - le16_to_cpu(rpbuf_disk.rpdatalen), + rpbuflen - 8, lookup_table); } FREE(name_utf16le); diff --git a/src/win32_apply.c b/src/win32_apply.c index c91315cf..010b9bee 100644 --- a/src/win32_apply.c +++ b/src/win32_apply.c @@ -57,6 +57,7 @@ L"If you are not running this program as the administrator, you may\n" static int win32_extract_try_rpfix(u8 *rpbuf, + u16 *rpbuflen_p, const wchar_t *extract_root_realpath, unsigned extract_root_realpath_nchars) { @@ -74,8 +75,7 @@ win32_extract_try_rpfix(u8 *rpbuf, size_t new_print_name_nchars; utf16lechar *p; - ret = parse_reparse_data(rpbuf, 8 + le16_to_cpu(*(u16*)(rpbuf + 4)), - &rpdata); + ret = parse_reparse_data(rpbuf, *rpbuflen_p, &rpdata); if (ret) return ret; @@ -119,12 +119,10 @@ win32_extract_try_rpfix(u8 *rpbuf, *p++ = extract_root_realpath[1]; } /* Copy the rest of the extract root */ - wmemcpy(p, extract_root_realpath + 2, extract_root_realpath_nchars - 2); - p += extract_root_realpath_nchars - 2; + p = wmempcpy(p, extract_root_realpath + 2, extract_root_realpath_nchars - 2); /* Append the stripped target */ - wmemcpy(p, stripped_target, stripped_target_nchars); - p += stripped_target_nchars; + p = wmempcpy(p, stripped_target, stripped_target_nchars); new_target_nchars = p - new_target; new_print_name_nchars = p - new_print_name; @@ -138,7 +136,7 @@ win32_extract_try_rpfix(u8 *rpbuf, rpdata.substitute_name_nbytes = new_target_nchars * sizeof(utf16lechar); rpdata.print_name = new_print_name; rpdata.print_name_nbytes = new_print_name_nchars * sizeof(utf16lechar); - return make_reparse_buffer(&rpdata, rpbuf); + return make_reparse_buffer(&rpdata, rpbuf, rpbuflen_p); } /* Wrapper around the FSCTL_SET_REPARSE_POINT ioctl to set the reparse data on @@ -151,7 +149,7 @@ win32_set_reparse_data(HANDLE h, struct apply_args *args) { int ret; - u8 rpbuf[REPARSE_POINT_MAX_SIZE]; + u8 rpbuf[REPARSE_POINT_MAX_SIZE] _aligned_attribute(8); DWORD bytesReturned; u16 rpbuflen; @@ -167,6 +165,7 @@ win32_set_reparse_data(HANDLE h, !inode->i_not_rpfixed) { ret = win32_extract_try_rpfix(rpbuf, + &rpbuflen, args->target_realpath, args->target_realpath_len); if (ret) diff --git a/src/win32_capture.c b/src/win32_capture.c index c05eb192..a2d67976 100644 --- a/src/win32_capture.c +++ b/src/win32_capture.c @@ -506,12 +506,10 @@ win32_capture_try_rpfix(u8 *rpbuf, u16 *rpbuflen_p, const wchar_t *path) { struct reparse_data rpdata; - DWORD rpbuflen; int ret; enum rp_status rp_status; - rpbuflen = *rpbuflen_p; - ret = parse_reparse_data(rpbuf, rpbuflen, &rpdata); + ret = parse_reparse_data(rpbuf, *rpbuflen_p, &rpdata); if (ret) return -ret; @@ -535,7 +533,7 @@ win32_capture_try_rpfix(u8 *rpbuf, u16 *rpbuflen_p, rpdata.print_name += 4; rpdata.print_name_nbytes -= 8; } - ret = make_reparse_buffer(&rpdata, rpbuf); + ret = make_reparse_buffer(&rpdata, rpbuf, rpbuflen_p); if (ret == 0) ret = rp_status; else -- 2.43.0