- From 7db6599772eade9267645389b68d06f424afbdf5 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Wed, 15 May 2024 15:38:33 +0200
- Subject: [PATCH 1/2] sys: nfs41_driver.sys should use non-executable
- memory+mappings
- nfs41_driver.sys should use non-executable memory (|NonPagedPoolNx|)
- and mappings (|MdlMappingNoExecute|, not NOT for read/write buffers!).
- Reported-by: Martin Wege <martin.l.wege@gmail.com>
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- sys/nfs41_driver.c | 26 ++++++++++++++------------
- 1 file changed, 14 insertions(+), 12 deletions(-)
- diff --git a/sys/nfs41_driver.c b/sys/nfs41_driver.c
- index 665745f..f35793d 100644
- --- a/sys/nfs41_driver.c
- +++ b/sys/nfs41_driver.c
- @@ -752,7 +752,8 @@ NTSTATUS marshal_nfs41_open(
- if (entry->u.Open.EaMdl) {
- entry->u.Open.EaBuffer =
- MmMapLockedPagesSpecifyCache(entry->u.Open.EaMdl,
- - UserMode, MmCached, NULL, TRUE, NormalPagePriority);
- + UserMode, MmCached, NULL, TRUE,
- + NormalPagePriority|MdlMappingNoExecute);
- if (entry->u.Open.EaBuffer == NULL) {
- print_error("marshal_nfs41_open: "
- "MmMapLockedPagesSpecifyCache() failed to "
- @@ -1012,7 +1013,8 @@ NTSTATUS marshal_nfs41_dirquery(
- __try {
- entry->u.QueryFile.mdl_buf =
- MmMapLockedPagesSpecifyCache(entry->u.QueryFile.mdl,
- - UserMode, MmCached, NULL, TRUE, NormalPagePriority);
- + UserMode, MmCached, NULL, TRUE,
- + NormalPagePriority|MdlMappingNoExecute);
- if (entry->u.QueryFile.mdl_buf == NULL) {
- print_error("marshal_nfs41_dirquery: "
- "MmMapLockedPagesSpecifyCache() failed to map pages\n");
- @@ -1514,7 +1516,7 @@ NTSTATUS nfs41_UpcallCreate(
- SECURITY_SUBJECT_CONTEXT sec_ctx;
- SECURITY_QUALITY_OF_SERVICE sec_qos;
- - entry = RxAllocatePoolWithTag(NonPagedPool, sizeof(nfs41_updowncall_entry),
- + entry = RxAllocatePoolWithTag(NonPagedPoolNx, sizeof(nfs41_updowncall_entry),
- NFS41_MM_POOLTAG_UP);
- if (entry == NULL) {
- status = STATUS_INSUFFICIENT_RESOURCES;
- @@ -1835,7 +1837,7 @@ NTSTATUS unmarshal_nfs41_open(
- *buf += sizeof(USHORT);
- cur->u.Open.symlink.Length = cur->u.Open.symlink.MaximumLength -
- sizeof(WCHAR);
- - cur->u.Open.symlink.Buffer = RxAllocatePoolWithTag(NonPagedPool,
- + cur->u.Open.symlink.Buffer = RxAllocatePoolWithTag(NonPagedPoolNx,
- cur->u.Open.symlink.MaximumLength, NFS41_MM_POOLTAG);
- if (cur->u.Open.symlink.Buffer == NULL) {
- cur->status = STATUS_INSUFFICIENT_RESOURCES;
- @@ -1944,7 +1946,7 @@ NTSTATUS unmarshal_nfs41_getacl(
- RtlCopyMemory(&buf_len, *buf, sizeof(DWORD));
- *buf += sizeof(DWORD);
- - cur->buf = RxAllocatePoolWithTag(NonPagedPool,
- + cur->buf = RxAllocatePoolWithTag(NonPagedPoolNx,
- buf_len, NFS41_MM_POOLTAG_ACL);
- if (cur->buf == NULL) {
- cur->status = status = STATUS_INSUFFICIENT_RESOURCES;
- @@ -1990,7 +1992,7 @@ NTSTATUS nfs41_downcall(
- print_hexbuf(0, (unsigned char *)"downcall buffer", buf, in_len);
- - tmp = RxAllocatePoolWithTag(NonPagedPool, sizeof(nfs41_updowncall_entry),
- + tmp = RxAllocatePoolWithTag(NonPagedPoolNx, sizeof(nfs41_updowncall_entry),
- NFS41_MM_POOLTAG_DOWN);
- if (tmp == NULL) goto out;
- @@ -2653,7 +2655,7 @@ NTSTATUS _nfs41_CreateSrvCall(
- }
- /* Let's create our own representation of the server */
- - pServerEntry = (PNFS41_SERVER_ENTRY)RxAllocatePoolWithTag(NonPagedPool,
- + pServerEntry = (PNFS41_SERVER_ENTRY)RxAllocatePoolWithTag(NonPagedPoolNx,
- sizeof(NFS41_SERVER_ENTRY), NFS41_MM_POOLTAG);
- if (pServerEntry == NULL) {
- status = STATUS_INSUFFICIENT_RESOURCES;
- @@ -3145,7 +3147,7 @@ NTSTATUS nfs41_CreateVNetRoot(
- pNetRoot->MRxNetRootState = MRX_NET_ROOT_STATE_GOOD;
- pNetRoot->DeviceType = FILE_DEVICE_DISK;
- - Config = RxAllocatePoolWithTag(NonPagedPool,
- + Config = RxAllocatePoolWithTag(NonPagedPoolNx,
- sizeof(NFS41_MOUNT_CONFIG), NFS41_MM_POOLTAG);
- if (Config == NULL) {
- status = STATUS_INSUFFICIENT_RESOURCES;
- @@ -3346,7 +3348,7 @@ NTSTATUS nfs41_CreateVNetRoot(
- if (!found_existing_mount) {
- /* create a new mount entry and add it to the list */
- nfs41_mount_entry *entry;
- - entry = RxAllocatePoolWithTag(NonPagedPool, sizeof(nfs41_mount_entry),
- + entry = RxAllocatePoolWithTag(NonPagedPoolNx, sizeof(nfs41_mount_entry),
- NFS41_MM_POOLTAG_MOUNT);
- if (entry == NULL) {
- status = STATUS_INSUFFICIENT_RESOURCES;
- @@ -3980,7 +3982,7 @@ retry_on_link:
- AbsPath.Length = DeviceObject->DeviceName.Length +
- VNetRootPrefix->Length + entry->u.Open.symlink.Length;
- AbsPath.MaximumLength = AbsPath.Length + sizeof(UNICODE_NULL);
- - AbsPath.Buffer = RxAllocatePoolWithTag(NonPagedPool,
- + AbsPath.Buffer = RxAllocatePoolWithTag(NonPagedPoolNx,
- AbsPath.MaximumLength, NFS41_MM_POOLTAG);
- if (AbsPath.Buffer == NULL) {
- status = STATUS_INSUFFICIENT_RESOURCES;
- @@ -4155,7 +4157,7 @@ retry_on_link:
- DbgP("nfs41_Create: received no delegations: srv_open=%p "
- "ctime=%llu\n", SrvOpen, entry->ChangeTime);
- #endif
- - oentry = RxAllocatePoolWithTag(NonPagedPool,
- + oentry = RxAllocatePoolWithTag(NonPagedPoolNx,
- sizeof(nfs41_fcb_list_entry), NFS41_MM_POOLTAG_OPEN);
- if (oentry == NULL) {
- status = STATUS_INSUFFICIENT_RESOURCES;
- @@ -6099,7 +6101,7 @@ void enable_caching(
- #ifdef DEBUG_TIME_BASED_COHERENCY
- DbgP("enable_caching: delegation recalled: srv_open=%p\n", SrvOpen);
- #endif
- - oentry = RxAllocatePoolWithTag(NonPagedPool,
- + oentry = RxAllocatePoolWithTag(NonPagedPoolNx,
- sizeof(nfs41_fcb_list_entry), NFS41_MM_POOLTAG_OPEN);
- if (oentry == NULL) return;
- oentry->fcb = SrvOpen->pFcb;
- --
- 2.43.0
- From bd3598400d674ec4e71bd981dfcebda21dbaad75 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Wed, 15 May 2024 17:34:37 +0200
- Subject: [PATCH 2/2] daemon: |upcall_parse()| should only init data which are
- actually used
- |upcall_parse()| should only init data which are actually used,
- otherwise we init huge chunks of memory which are not even touched
- elsewhere in the code.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- daemon/acl.c | 14 ++++++++------
- daemon/ea.c | 14 ++++++++------
- daemon/getattr.c | 7 ++++---
- daemon/lock.c | 14 ++++++++------
- daemon/mount.c | 14 ++++++++------
- daemon/open.c | 18 +++++++++---------
- daemon/readdir.c | 7 ++++---
- daemon/readwrite.c | 14 ++++++++------
- daemon/setattr.c | 7 ++++---
- daemon/symlink.c | 7 ++++---
- daemon/upcall.c | 45 +++++++++++++++++++++++++++++++++------------
- daemon/upcall.h | 1 +
- daemon/volume.c | 7 ++++---
- 13 files changed, 103 insertions(+), 66 deletions(-)
- diff --git a/daemon/acl.c b/daemon/acl.c
- index b93c319..d5d2fe1 100644
- --- a/daemon/acl.c
- +++ b/daemon/acl.c
- @@ -412,9 +412,10 @@ out:
- }
- const nfs41_upcall_op nfs41_op_getacl = {
- - parse_getacl,
- - handle_getacl,
- - marshall_getacl
- + .parse = parse_getacl,
- + .handle = handle_getacl,
- + .marshall = marshall_getacl,
- + .arg_size = sizeof(getacl_upcall_args)
- };
- static int parse_setacl(unsigned char *buffer, uint32_t length,
- @@ -922,7 +923,8 @@ static int marshall_setacl(unsigned char *buffer, uint32_t *length, nfs41_upcall
- }
- const nfs41_upcall_op nfs41_op_setacl = {
- - parse_setacl,
- - handle_setacl,
- - marshall_setacl
- + .parse = parse_setacl,
- + .handle = handle_setacl,
- + .marshall = marshall_setacl,
- + .arg_size = sizeof(setacl_upcall_args)
- };
- diff --git a/daemon/ea.c b/daemon/ea.c
- index f941e59..f9dd3e8 100644
- --- a/daemon/ea.c
- +++ b/daemon/ea.c
- @@ -681,13 +681,15 @@ out:
- const nfs41_upcall_op nfs41_op_setexattr = {
- - parse_setexattr,
- - handle_setexattr,
- - marshall_setexattr
- + .parse = parse_setexattr,
- + .handle = handle_setexattr,
- + .marshall = marshall_setexattr,
- + .arg_size = sizeof(setexattr_upcall_args)
- };
- const nfs41_upcall_op nfs41_op_getexattr = {
- - parse_getexattr,
- - handle_getexattr,
- - marshall_getexattr
- + .parse = parse_getexattr,
- + .handle = handle_getexattr,
- + .marshall = marshall_getexattr,
- + .arg_size = sizeof(getexattr_upcall_args)
- };
- diff --git a/daemon/getattr.c b/daemon/getattr.c
- index 7668a9b..9dc6f36 100644
- --- a/daemon/getattr.c
- +++ b/daemon/getattr.c
- @@ -249,7 +249,8 @@ out:
- const nfs41_upcall_op nfs41_op_getattr = {
- - parse_getattr,
- - handle_getattr,
- - marshall_getattr
- + .parse = parse_getattr,
- + .handle = handle_getattr,
- + .marshall = marshall_getattr,
- + .arg_size = sizeof(getattr_upcall_args)
- };
- diff --git a/daemon/lock.c b/daemon/lock.c
- index 9bf2868..bd99199 100644
- --- a/daemon/lock.c
- +++ b/daemon/lock.c
- @@ -358,12 +358,14 @@ static int handle_unlock(void *daemon_context, nfs41_upcall *upcall)
- const nfs41_upcall_op nfs41_op_lock = {
- - parse_lock,
- - handle_lock,
- - NULL,
- - cancel_lock
- + .parse = parse_lock,
- + .handle = handle_lock,
- + .cancel = cancel_lock,
- + .arg_size = sizeof(lock_upcall_args)
- };
- +
- const nfs41_upcall_op nfs41_op_unlock = {
- - parse_unlock,
- - handle_unlock
- + .parse = parse_unlock,
- + .handle = handle_unlock,
- + .arg_size = sizeof(unlock_upcall_args)
- };
- diff --git a/daemon/mount.c b/daemon/mount.c
- index de9bdb8..f0fa866 100644
- --- a/daemon/mount.c
- +++ b/daemon/mount.c
- @@ -209,10 +209,11 @@ static void cancel_mount(IN nfs41_upcall *upcall)
- }
- const nfs41_upcall_op nfs41_op_mount = {
- - parse_mount,
- - handle_mount,
- - marshall_mount,
- - cancel_mount
- + .parse = parse_mount,
- + .handle = handle_mount,
- + .marshall = marshall_mount,
- + .cancel = cancel_mount,
- + .arg_size = sizeof(mount_upcall_args)
- };
- @@ -234,6 +235,7 @@ static int handle_unmount(void *daemon_context, nfs41_upcall *upcall)
- }
- const nfs41_upcall_op nfs41_op_unmount = {
- - parse_unmount,
- - handle_unmount
- + .parse = parse_unmount,
- + .handle = handle_unmount,
- + .arg_size = 0
- };
- diff --git a/daemon/open.c b/daemon/open.c
- index 57dd53f..fe7e35a 100644
- --- a/daemon/open.c
- +++ b/daemon/open.c
- @@ -1203,15 +1203,15 @@ static void cleanup_close(nfs41_upcall *upcall)
- const nfs41_upcall_op nfs41_op_open = {
- - parse_open,
- - handle_open,
- - marshall_open,
- - cancel_open
- + .parse = parse_open,
- + .handle = handle_open,
- + .marshall = marshall_open,
- + .cancel = cancel_open,
- + .arg_size = sizeof(open_upcall_args)
- };
- const nfs41_upcall_op nfs41_op_close = {
- - parse_close,
- - handle_close,
- - NULL,
- - NULL,
- - cleanup_close
- + .parse = parse_close,
- + .handle = handle_close,
- + .cleanup = cleanup_close,
- + .arg_size = sizeof(close_upcall_args)
- };
- diff --git a/daemon/readdir.c b/daemon/readdir.c
- index c34eb64..83d266b 100644
- --- a/daemon/readdir.c
- +++ b/daemon/readdir.c
- @@ -882,7 +882,8 @@ static int marshall_readdir(unsigned char *buffer, uint32_t *length, nfs41_upcal
- const nfs41_upcall_op nfs41_op_readdir = {
- - parse_readdir,
- - handle_readdir,
- - marshall_readdir
- + .parse = parse_readdir,
- + .handle = handle_readdir,
- + .marshall = marshall_readdir,
- + .arg_size = sizeof(readdir_upcall_args)
- };
- diff --git a/daemon/readwrite.c b/daemon/readwrite.c
- index 3c716cc..e93eef3 100644
- --- a/daemon/readwrite.c
- +++ b/daemon/readwrite.c
- @@ -316,12 +316,14 @@ out:
- const nfs41_upcall_op nfs41_op_read = {
- - parse_rw,
- - handle_read,
- - marshall_rw
- + .parse = parse_rw,
- + .handle = handle_read,
- + .marshall = marshall_rw,
- + .arg_size = sizeof(readwrite_upcall_args)
- };
- const nfs41_upcall_op nfs41_op_write = {
- - parse_rw,
- - handle_write,
- - marshall_rw
- + .parse = parse_rw,
- + .handle = handle_write,
- + .marshall = marshall_rw,
- + .arg_size = sizeof(readwrite_upcall_args)
- };
- diff --git a/daemon/setattr.c b/daemon/setattr.c
- index 5a951e8..5540d87 100644
- --- a/daemon/setattr.c
- +++ b/daemon/setattr.c
- @@ -522,7 +522,8 @@ static int marshall_setattr(unsigned char *buffer, uint32_t *length, nfs41_upcal
- const nfs41_upcall_op nfs41_op_setattr = {
- - parse_setattr,
- - handle_setattr,
- - marshall_setattr
- + .parse = parse_setattr,
- + .handle = handle_setattr,
- + .marshall = marshall_setattr,
- + .arg_size = sizeof(setattr_upcall_args)
- };
- diff --git a/daemon/symlink.c b/daemon/symlink.c
- index 6903eb7..a015f4c 100644
- --- a/daemon/symlink.c
- +++ b/daemon/symlink.c
- @@ -293,7 +293,8 @@ out:
- const nfs41_upcall_op nfs41_op_symlink = {
- - parse_symlink,
- - handle_symlink,
- - marshall_symlink
- + .parse = parse_symlink,
- + .handle = handle_symlink,
- + .marshall = marshall_symlink,
- + .arg_size = sizeof(symlink_upcall_args)
- };
- diff --git a/daemon/upcall.c b/daemon/upcall.c
- index eef5530..a2e3520 100644
- --- a/daemon/upcall.c
- +++ b/daemon/upcall.c
- @@ -83,8 +83,19 @@ int upcall_parse(
- int status;
- const nfs41_upcall_op *op;
- DWORD version;
- + uint32_t upcall_upcode = 0;
- +
- + /*
- + * Init generic |upcall| data
- + * (Note that the |upcall->args| will be initialized before
- + * |op->parse()| below)
- + */
- + upcall->opcode = 0;
- + upcall->status = 0;
- + upcall->last_error = 0;
- + upcall->root_ref = NULL;
- + upcall->state_ref = NULL;
- - ZeroMemory(upcall, sizeof(nfs41_upcall));
- if (!length) {
- eprintf("empty upcall\n");
- upcall->status = status = 102;
- @@ -102,7 +113,6 @@ int upcall_parse(
- status = safe_read(&buffer, &length, &upcall->xid, sizeof(uint64_t));
- if (status) goto out;
- /* |sizeof(enum)| might not be the same as |sizeof(uint32_t)| */
- - uint32_t upcall_upcode = 0;
- status = safe_read(&buffer, &length, &upcall_upcode, sizeof(uint32_t));
- if (status) goto out;
- upcall->opcode = upcall_upcode;
- @@ -112,7 +122,7 @@ int upcall_parse(
- if (status) goto out;
- DPRINTF(2, ("time=%ld version=%d xid=%d opcode='%s' session=0x%x open_state=0x%x\n",
- - time(NULL), version, upcall->xid, opcode2string(upcall->opcode), upcall->root_ref,
- + time(NULL), version, upcall->xid, opcode2string(upcall_upcode), upcall->root_ref,
- upcall->state_ref));
- if (version != NFS41D_VERSION) {
- eprintf("received version %d expecting version %d\n", version, NFS41D_VERSION);
- @@ -121,8 +131,8 @@ int upcall_parse(
- }
- if (upcall_upcode >= g_upcall_op_table_size) {
- status = ERROR_NOT_SUPPORTED;
- - eprintf("upcall_parse: unrecognized upcall opcode %d!\n",
- - upcall->opcode);
- + eprintf("upcall_parse: unrecognized upcall opcode %u!\n",
- + (unsigned int)upcall_upcode);
- goto out;
- }
- @@ -133,9 +143,9 @@ int upcall_parse(
- if (upcall->state_ref != INVALID_HANDLE_VALUE) {
- if (!isvalidnfs41_open_state_ptr(upcall->state_ref)) {
- eprintf("upcall_parse: Error accessing "
- - "upcall->state_ref(=0x%p), opcode %d; "
- + "upcall->state_ref(=0x%p), opcode %u; "
- "returning ERROR_INVALID_PARAMETER\n",
- - upcall->state_ref, upcall->opcode);
- + upcall->state_ref, (unsigned int)upcall_upcode);
- /*
- * Set |upcall->state_ref| to |INVALID_HANDLE_VALUE|
- * so that we do not try to dereference it
- @@ -147,8 +157,8 @@ int upcall_parse(
- if (upcall->state_ref->ref_count == 0) {
- eprintf("upcall_parse: upcall->state_ref(=0x%p).ref_count == 0, "
- - "opcode %d; returning ERROR_INVALID_PARAMETER\n",
- - upcall->state_ref, upcall->opcode);
- + "opcode %u; returning ERROR_INVALID_PARAMETER\n",
- + upcall->state_ref, (unsigned int)upcall_upcode);
- /*
- * Set |upcall->state_ref| to |INVALID_HANDLE_VALUE|
- * so that we do not try to dereference it
- @@ -164,16 +174,27 @@ int upcall_parse(
- nfs41_open_state_ref(upcall->state_ref);
- /* parse the operation's arguments */
- - op = g_upcall_op_table[upcall->opcode];
- + op = g_upcall_op_table[upcall_upcode];
- +
- + if (op) {
- + /* |NFS41_UNMOUNT| has 0 payload */
- + if (upcall_upcode != NFS41_UNMOUNT) {
- + EASSERT_MSG(op->arg_size >= sizeof(void*),
- + ("upcall->opcode=%u\n", (unsigned int)upcall_upcode));
- + }
- + (void)memset(&upcall->args, 0, op->arg_size);
- + }
- +
- if (op && op->parse) {
- /* |NFS41_UNMOUNT| has 0 payload */
- - if (upcall->opcode != NFS41_UNMOUNT) {
- + if (upcall_upcode != NFS41_UNMOUNT) {
- EASSERT(length > 0);
- }
- +
- status = op->parse(buffer, length, upcall);
- if (status) {
- eprintf("parsing of upcall '%s' failed with %d.\n",
- - opcode2string(upcall->opcode), status);
- + opcode2string(upcall_upcode), status);
- goto out;
- }
- }
- diff --git a/daemon/upcall.h b/daemon/upcall.h
- index f8d608e..c0bbe8f 100644
- --- a/daemon/upcall.h
- +++ b/daemon/upcall.h
- @@ -242,6 +242,7 @@ typedef struct __nfs41_upcall_op {
- upcall_marshall_proc marshall;
- upcall_cancel_proc cancel;
- upcall_cleanup_proc cleanup;
- + size_t arg_size;
- } nfs41_upcall_op;
- diff --git a/daemon/volume.c b/daemon/volume.c
- index 50ac051..3793da8 100644
- --- a/daemon/volume.c
- +++ b/daemon/volume.c
- @@ -170,7 +170,8 @@ out:
- const nfs41_upcall_op nfs41_op_volume = {
- - parse_volume,
- - handle_volume,
- - marshall_volume
- + .parse = parse_volume,
- + .handle = handle_volume,
- + .marshall = marshall_volume,
- + .arg_size = sizeof(volume_upcall_args)
- };
- --
- 2.43.0
msnfs41client: Patches for driver noexec mappings+upcall init opt, 2024-05-15
Posted by Anonymous on Thu 16th May 2024 13:59
raw | new post
Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.