Issue description
The IQM object loader code is assigning an unsigned int from iqmHeader->num_joints to boneCount in struct ModelSkeleton, which is an int. The compiler detects that this can potentially overflow into a negative value, which is then passed to the allocator as a size_t potentially resulting in a huge allocation.
Tested at bb96b92
The Error
[ 36%] Linking C executable models_orthographic_projection
In function 'LoadIQM',
inlined from 'LoadModel.constprop' at /home/eddy/dev/EXT/raylib/src/rmodels.c:1110:52:
/home/eddy/dev/EXT/raylib/src/rmodels.c:5014:38: error: argument 1 range [18446744071562067968, 18446744073709551615] exceeds maximum object size 9223372036854775807 [-Werror=alloc-size-larger-than=]
5014 | model.currentPose = (Transform *)RL_CALLOC(model.skeleton.boneCount, sizeof(Transform));
| ^
/usr/include/stdlib.h: In function 'LoadModel.constprop':
/usr/include/stdlib.h:675:14: note: in a call to allocation function 'calloc' declared here
675 | extern void *calloc (size_t __nmemb, size_t __size)
| ^
In function 'LoadIQM',
inlined from 'LoadModel.constprop' at /home/eddy/dev/EXT/raylib/src/rmodels.c:1110:52:
/home/eddy/dev/EXT/raylib/src/rmodels.c:5015:36: error: argument 1 range [18446744071562067968, 18446744073709551615] exceeds maximum object size 9223372036854775807 [-Werror=alloc-size-larger-than=]
5015 | model.boneMatrices = (Matrix *)RL_CALLOC(model.skeleton.boneCount, sizeof(Matrix));
| ^
/usr/include/stdlib.h: In function 'LoadModel.constprop':
/usr/include/stdlib.h:675:14: note: in a call to allocation function 'calloc' declared here
675 | extern void *calloc (size_t __nmemb, size_t __size)
| ^
In function 'LoadIQM',
inlined from 'LoadModel.constprop' at /home/eddy/dev/EXT/raylib/src/rmodels.c:1110:52:
/home/eddy/dev/EXT/raylib/src/rmodels.c:5014:38: error: argument 1 range [18446744071562067968, 18446744073709551615] exceeds maximum object size 9223372036854775807 [-Werror=alloc-size-larger-than=]
5014 | model.currentPose = (Transform *)RL_CALLOC(model.skeleton.boneCount, sizeof(Transform));
| ^
/usr/include/stdlib.h: In function 'LoadModel.constprop':
/usr/include/stdlib.h:675:14: note: in a call to allocation function 'calloc' declared here
675 | extern void *calloc (size_t __nmemb, size_t __size)
| ^
In function 'LoadIQM',
inlined from 'LoadModel.constprop' at /home/eddy/dev/EXT/raylib/src/rmodels.c:1110:52:
/home/eddy/dev/EXT/raylib/src/rmodels.c:5015:36: error: argument 1 range [18446744071562067968, 18446744073709551615] exceeds maximum object size 9223372036854775807 [-Werror=alloc-size-larger-than=]
5015 | model.boneMatrices = (Matrix *)RL_CALLOC(model.skeleton.boneCount, sizeof(Matrix));
| ^
/usr/include/stdlib.h: In function 'LoadModel.constprop':
/usr/include/stdlib.h:675:14: note: in a call to allocation function 'calloc' declared here
675 | extern void *calloc (size_t __nmemb, size_t __size)
| ^
lto1: all warnings being treated as errors
make[3]: *** [/tmp/ccsbdewr.mk:14: /tmp/cc7nxShc.ltrans6.ltrans.o] Error 1
Build
This is my build command:
EXTRA_CFLAGS="-flto=auto -fuse-linker-plugin"
cmake -DCMAKE_C_FLAGS="-march=native -mtune=native -Werror ${EXTRA_CFLAGS}" -DCMAKE_INSTALL_PREFIX=${PREFIX} \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DUSE_EXTERNAL_GLFW=ON -DGLFW_BUILD_WAYLAND=OFF \
-S $HOME/dev/EXT/raylib -B build
The fix
Proposed minimum fix:
diff --git a/src/rmodels.c b/src/rmodels.c
index 28fb3c9ec..bde056186 100644
--- a/src/rmodels.c
+++ b/src/rmodels.c
@@ -4981,7 +4981,7 @@ static Model LoadIQM(const char *fileName)
//fread(ijoint, sizeof(IQMJoint), iqmHeader->num_joints, iqmFile);
memcpy(ijoint, fileDataPtr + iqmHeader->ofs_joints, iqmHeader->num_joints*sizeof(IQMJoint));
- model.skeleton.boneCount = iqmHeader->num_joints;
+ model.skeleton.boneCount = iqmHeader->num_joints & INT_MAX;
model.skeleton.bones = (BoneInfo *)RL_CALLOC(iqmHeader->num_joints, sizeof(BoneInfo));
model.skeleton.bindPose = (Transform *)RL_CALLOC(iqmHeader->num_joints, sizeof(Transform));
Obviously a more holistic fix would also adjust the local allocations to use the capped value, but I doubt any real/non-adversarial model would ever be affected by the mask to begin with.
Workaround
Setting SUPPORT_FILEFORMAT_IQM to zero in the configuration allows the build to proceed successfully.
Issue description
The IQM object loader code is assigning an
unsigned intfromiqmHeader->num_jointstoboneCountinstruct ModelSkeleton, which is anint. The compiler detects that this can potentially overflow into a negative value, which is then passed to the allocator as asize_tpotentially resulting in a huge allocation.Tested at bb96b92
The Error
Build
This is my build command:
The fix
Proposed minimum fix:
Obviously a more holistic fix would also adjust the local allocations to use the capped value, but I doubt any real/non-adversarial model would ever be affected by the mask to begin with.
Workaround
Setting
SUPPORT_FILEFORMAT_IQMto zero in the configuration allows the build to proceed successfully.