diff --git a/src/viced/afsfileprocs.c b/src/viced/afsfileprocs.c index cfebe61673..631cd34eeb 100644 --- a/src/viced/afsfileprocs.c +++ b/src/viced/afsfileprocs.c @@ -3078,6 +3078,36 @@ printableACL(struct AFSOpaque *AccessList) return s; } +/** + * Check if the given ACL blob is okay to use. + * + * If the given ACL is 0-length, or doesn't contain a NUL byte, return an error + * and refuse the process the given ACL. The ACL must contain a NUL byte, + * otherwise ACL-processing code may run off the end of the buffer and process + * uninitialized memory. + * + * If there is any data beyond the NUL byte, just ignore it and return success. + * We won't look at any post-NUL data, but theoretically clients could send + * such an ACL to us, since historically it's been allowed. + * + * @param[in] AccessList The ACL blob to check + * + * @returns errno error code to abort the call with + * @retval 0 ACL is okay to use + */ +static afs_int32 +check_acl(struct AFSOpaque *AccessList) +{ + if (AccessList->AFSOpaque_len == 0) { + return EINVAL; + } + if (memchr(AccessList->AFSOpaque_val, '\0', + AccessList->AFSOpaque_len) == NULL) { + return EINVAL; + } + return 0; +} + static afs_int32 common_StoreACL(afs_uint64 opcode, struct rx_call * acall, struct AFSFid * Fid, @@ -3104,6 +3134,11 @@ common_StoreACL(afs_uint64 opcode, if ((errorCode = CallPreamble(acall, ACTIVECALL, Fid, &tcon, &thost))) goto Bad_StoreACL; + errorCode = check_acl(AccessList); + if (errorCode != 0) { + goto Bad_StoreACL; + } + /* Get ptr to client data for user Id for logging */ t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key); logHostAddr.s_addr = rxr_HostOf(tcon);