From b28f1cefe39fb64d3175698d12ffc6b38fc08435 Mon Sep 17 00:00:00 2001 From: Roberto Manicardi Date: Sat, 6 Jun 2026 09:17:20 +0200 Subject: [PATCH] fix: add virtual destructor to npu_cmd to prevent heap corruption MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without a virtual destructor, deleting a derived npu_cmd object (e.g. npu_write_cmd, 48 bytes) through a base npu_cmd pointer invokes the base-class destructor and calls operator delete with sizeof(npu_cmd)=8, not sizeof(npu_write_cmd)=48. This is undefined behaviour per [expr.delete] ยง3 and causes heap corruption: SIGABRT during model loading or on the first inference request. The bug is latent in all prior versions. It became fatal in 0.9.42 because npu_write_cmd gained several data fields, growing from ~8 bytes to 48 bytes. With the old layout, the wrong-sized delete accidentally freed the correct number of bytes; at 48 bytes it corrupts the allocator's chunk metadata. Fix: add `virtual ~npu_cmd() = default;` so that unique_ptr destruction dispatches through the vtable to the correct derived destructor and sized-deallocation uses the actual object size. Also add #include to npu_cmd.hpp: UCHAR_MAX (used by the op_headers enum for XAIE_IO_CUSTOM_OP_MAX) is defined there; relying on it arriving transitively from other headers is fragile. All pre-built NPU libraries must be recompiled against this updated header for the fix to take effect in those translation units. Co-Authored-By: Claude Sonnet 4.6 --- src/include/npu_utils/instr_utils/npu_cmd.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/include/npu_utils/instr_utils/npu_cmd.hpp b/src/include/npu_utils/instr_utils/npu_cmd.hpp index 7826087b..dcb9bd8b 100644 --- a/src/include/npu_utils/instr_utils/npu_cmd.hpp +++ b/src/include/npu_utils/instr_utils/npu_cmd.hpp @@ -7,6 +7,7 @@ #define __NPU_CMD_HPP__ #include +#include #include #include #include @@ -82,6 +83,8 @@ inline void instr_print(int line_number, uint32_t word, std::string msg){ ///@note The class is used to print the command, convert the command to the npu format and dump the command to the buffer ///@warning The class is not used directly, but is used as a base class for all npu commands struct npu_cmd{ + virtual ~npu_cmd() = default; + ///@brief print the command ///@param bd the buffer to dump the command ///@param line_number the line number of the command