From 66d4ea8e0b252d3e029f8172fe28308a49ab023b Mon Sep 17 00:00:00 2001 From: Casey Bodley Date: Tue, 12 Oct 2010 10:06:45 -0400 Subject: [PATCH] max_path: static buffer for symlink path added nfs41_abs_path symlink to struct open_upcall_args. we can't write the symlink target back to args->path anymore, since it's a pointer into the upcall buffer Signed-off-by: Casey Bodley --- daemon/open.c | 30 ++++++++++++++++-------------- daemon/upcall.h | 3 ++- sys/nfs41_driver.c | 2 +- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/daemon/open.c b/daemon/open.c index f1762b6..6fc291c 100644 --- a/daemon/open.c +++ b/daemon/open.c @@ -303,9 +303,15 @@ static int follow_link( path_offset = (state->parent.name.name + state->parent.name.len) - state->path.path; - /* update the path with the results from link */ - status = abs_path_link(&args->path, - args->path.path + path_offset, link, link_len); + /* copy the path and update it with the results from link */ + args->symlink.len = state->path.len; + if (FAILED(StringCchCopyNA(args->symlink.path, NFS41_MAX_PATH_LEN, + state->path.path, state->path.len))) { + status = ERROR_BUFFER_OVERFLOW; + goto out; + } + status = abs_path_link(&args->symlink, + args->symlink.path + path_offset, link, link_len); if (status) { eprintf("abs_path_link() failed with %d\n", status); status = ERROR_PATH_NOT_FOUND; @@ -448,20 +454,16 @@ int marshall_open(unsigned char *buffer, uint32_t *length, nfs41_upcall *upcall) status = safe_write(&buffer, length, &args->changeattr, sizeof(args->changeattr)); if (status) goto out; if (upcall->last_error == ERROR_REPARSE) { - /* convert args->path to wchar */ - WCHAR wpath[NFS41_MAX_PATH_LEN]; - unsigned short len = (unsigned short)MultiByteToWideChar( - CP_UTF8, 0, args->path.path, args->path.len, wpath, NFS41_MAX_PATH_LEN); - if (len == 0) { + unsigned short len = (args->symlink.len + 1) * sizeof(WCHAR); + status = safe_write(&buffer, length, &len, sizeof(len)); + if (status) goto out; + /* convert args->symlink to wchar */ + if (*length <= len || !MultiByteToWideChar(CP_UTF8, 0, + args->symlink.path, args->symlink.len, + (LPWSTR)buffer, len / sizeof(WCHAR))) { status = ERROR_BUFFER_OVERFLOW; goto out; } - wpath[len++] = L'\0'; - len *= sizeof(WCHAR); - dprintf(2, "ERROR_REPARSE -> '%S' [%u]\n", wpath, len); - status = safe_write(&buffer, length, &len, sizeof(len)); - if (status) goto out; - status = safe_write(&buffer, length, wpath, len); } dprintf(2, "NFS41_OPEN: passing open_state=0x%p mode %o changeattr 0x%x\n", args->state, args->mode, args->changeattr); diff --git a/daemon/upcall.h b/daemon/upcall.h index b7dee3f..e07bd91 100644 --- a/daemon/upcall.h +++ b/daemon/upcall.h @@ -40,9 +40,10 @@ typedef struct __unmount_upcall_args { } unmount_upcall_args; typedef struct __open_upcall_args { - const char *path; + nfs41_abs_path symlink; FILE_BASIC_INFO basic_info; FILE_STANDARD_INFO std_info; + const char *path; nfs41_root *root; nfs41_open_state *state; ULONG access_mask; diff --git a/sys/nfs41_driver.c b/sys/nfs41_driver.c index 875cc7d..08f3964 100644 --- a/sys/nfs41_driver.c +++ b/sys/nfs41_driver.c @@ -2568,7 +2568,7 @@ NTSTATUS nfs41_Create( goto out; } - if (entry->errno == ERROR_REPARSE) { + if (entry->status == NO_ERROR && entry->errno == ERROR_REPARSE) { /* symbolic link handling. when attempting to open a symlink when the * FILE_OPEN_REPARSE_POINT flag is not set, replace the filename with * the symlink target's by calling RxPrepareToReparseSymbolicLink()