bullet3 icon indicating copy to clipboard operation
bullet3 copied to clipboard

ERROR: global-buffer-overflow for test_invdyn_bullet.cpp

Open DUT-ShiLongYu opened this issue 4 months ago • 0 comments

Bug Report

Environment

Description

  • Expected behavior: executing code doesn't crash
  • Actual behavior: a global-buffer-overflow problem occurs

Steps to reproduce

When testing test_invdyn_bullet.cpp, assertion failure and memory overflow errors occurred. The memory overflow error needs to be an intermittent segmentation fault.

/// create a bullet btMultiBody model of a tree structured multibody system,
/// convert that model to a MultiBodyTree model.
/// Then - run inverse dynamics on random input data (q, u, dot_u) to get forces
///      - run forward dynamics on (q,u, forces) to get accelerations
///      - compare input accelerations to inverse dynamics to output from forward dynamics

#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <functional>
#include <string>

#include <btBulletDynamicsCommon.h>
#include <btMultiBodyTreeCreator.hpp>
#include <BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h>
#include <BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h>
#include <BulletDynamics/Featherstone/btMultiBodyPoint2Point.h>
#include <BulletDynamics/Featherstone/btMultiBodyLinkCollider.h>
#include <gtest/gtest.h>
#include "../../examples/CommonInterfaces/CommonGUIHelperInterface.h"
#include "../../examples/Importers/ImportURDFDemo/BulletUrdfImporter.h"
#include "../../examples/Importers/ImportURDFDemo/URDF2Bullet.h"
#include "../../examples/Importers/ImportURDFDemo/MyMultiBodyCreator.h"
#include "../../examples/Importers/ImportURDFDemo/URDF2Bullet.h"
#include "../../examples/Utils/b3ResourcePath.h"
#include <invdyn_bullet_comparison.hpp>
#include <btMultiBodyFromURDF.hpp>
#include <MultiBodyTreeCreator.hpp>
#include <MultiBodyTreeDebugGraph.hpp>
#include "Bullet3Common/b3CommandLineArgs.h"
#include "Bullet3Common/b3Random.h"

using namespace btInverseDynamics;

bool FLAGS_verbose = false;

static btVector3 gravity(0, 0, -10);
static const bool kBaseFixed = false;
static const char kUrdfFile[] = "r2d2.urdf";

/// this test loads the a urdf model with fixed, floating, prismatic and rotational joints,
/// converts in to an inverse dynamics model and compares forward to inverse dynamics for
/// random input
TEST(InvDynCompare, bulletUrdfR2D2)
{
	MyBtMultiBodyFromURDF mb_load(gravity, kBaseFixed);

	char relativeFileName[1024];

	ASSERT_TRUE(b3ResourcePath::findResourcePath(kUrdfFile, relativeFileName, 1024,0));

	mb_load.setFileName(relativeFileName);
	mb_load.init();

	btMultiBodyTreeCreator id_creator;
	btMultiBody *btmb = mb_load.getBtMultiBody();
	ASSERT_EQ(id_creator.createFromBtMultiBody(btmb), 0);

	MultiBodyTree *id_tree = CreateMultiBodyTree(id_creator);
	ASSERT_EQ(0x0 != id_tree, true);

	vecx q(id_tree->numDoFs());
	vecx u(id_tree->numDoFs());
	vecx dot_u(id_tree->numDoFs());
	vecx joint_forces(id_tree->numDoFs());

	const int kNLoops = 10;
	double max_pos_error = 0;
	double max_acc_error = 0;

	b3Srand(0);

	for (int loop = 0; loop < kNLoops; loop++)
	{
		for (int i = 0; i < q.size(); i++)
		{
			q(i) = b3RandRange(-B3_PI, B3_PI);
			u(i) = b3RandRange(-B3_PI, B3_PI);
			dot_u(i) = b3RandRange(-B3_PI, B3_PI);
		}

		double pos_error;
		double acc_error;
		btmb->clearForcesAndTorques();
		id_tree->clearAllUserForcesAndMoments();
		// call inverse dynamics once, to get global position & velocity of root body
		// (fixed, so q, u, dot_u arbitrary)
		EXPECT_EQ(id_tree->calculateInverseDynamics(q, u, dot_u, &joint_forces), 0);

		EXPECT_EQ(compareInverseAndForwardDynamics(q, u, dot_u, gravity, FLAGS_verbose, btmb, id_tree,
												   &pos_error, &acc_error),
				  0);

		if (pos_error > max_pos_error)
		{
			max_pos_error = pos_error;
		}
		if (acc_error > max_acc_error)
		{
			max_acc_error = acc_error;
		}
	}

	if (FLAGS_verbose)
	{
		printf("max_pos_error= %e\n", max_pos_error);
		printf("max_acc_error= %e\n", max_acc_error);
	}

	EXPECT_LT(max_pos_error, std::numeric_limits<idScalar>::epsilon() * 1e4);
	EXPECT_LT(max_acc_error, std::numeric_limits<idScalar>::epsilon() * 1e5);
}

int main(int argc, char **argv)
{
	b3CommandLineArgs myArgs(argc, argv);
	FLAGS_verbose = myArgs.CheckCmdLineFlag("verbose");
	::testing::InitGoogleTest(&argc, argv);
	return RUN_ALL_TESTS();
}


Output

Here is what the output shows:

/root/UTopia/exp/bullet3/test/InverseDynamics/test_invdyn_bullet.cpp:111: Failure
Value of: b3ResourcePath::findResourcePath(kUrdfFile, relativeFileName, autofuzz30,0)
  Actual: false
Expected: true
#268    REDUCE cov: 774 ft: 869 corp: 19/2157b lim: 4096 exec/s: 0 rss: 94Mb L: 118/272 MS: 1 CustomCrossOver-
/root/UTopia/exp/bullet3/test/InverseDynamics/test_invdyn_bullet.cpp:111: Failure
Value of: b3ResourcePath::findResourcePath(kUrdfFile, relativeFileName, autofuzz30,0)
  Actual: false
Expected: true
/root/UTopia/exp/bullet3/test/InverseDynamics/test_invdyn_bullet.cpp:111: Failure
Value of: b3ResourcePath::findResourcePath(kUrdfFile, relativeFileName, autofuzz30,0)
  Actual: false
Expected: true
/root/UTopia/exp/bullet3/test/InverseDynamics/test_invdyn_bullet.cpp:111: Failure
Value of: b3ResourcePath::findResourcePath(kUrdfFile, relativeFileName, autofuzz30,0)
  Actual: false
Expected: true
=================================================================
==1070050==ERROR: AddressSanitizer: global-buffer-overflow on address 0x0000010c642a at pc 0x0000005ee6be bp 0x7fff6c1ebdd0 sp 0x7fff6c1eb590
READ of size 11 at 0x0000010c642a thread T0
    #0 0x5ee6bd in fopen (/root/UTopia/exp/bullet3/output/fuzzers/InvDynCompare_bulletUrdfR2D2_Test+0x5ee6bd)
    #1 0x661c7e in b3FileUtils::findFile(char const*, char*, int) /root/UTopia/exp/bullet3/test/InverseDynamics/../../src/Bullet3Common/b3FileUtils.h:21:7
    #2 0x6621c3 in b3ResourcePath::findResourcePath(char const*, char*, int, bool (*)(void*, char const*, char*, int), void*) /root/UTopia/exp/bullet3/examples/Utils/b3ResourcePath.cpp:104:13
    #3 0x64b9ac in InvDynCompare_bulletUrdfR2D2_Test::TestBody() /root/UTopia/exp/bullet3/test/InverseDynamics/test_invdyn_bullet.cpp:111:2
    #4 0x650e75 in enterAutofuzz::AutofuzzTest::runTest() /root/UTopia/exp/bullet3/test/InverseDynamics/test_invdyn_bullet.cpp:203:9
    #5 0x650a6c in enterAutofuzz /root/UTopia/exp/bullet3/test/InverseDynamics/test_invdyn_bullet.cpp:214:10
    #6 0xd9e2b6 in TestOneProtoInput(AutoFuzz::FuzzArgsProfile const&) /root/UTopia/exp/bullet3/test/InverseDynamics/fuzz_entry.cc:91:3
    #7 0xd9d9cc in LLVMFuzzerTestOneInput /root/UTopia/exp/bullet3/test/InverseDynamics/fuzz_entry.cc:59:1
    #8 0x553081 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/root/UTopia/exp/bullet3/output/fuzzers/InvDynCompare_bulletUrdfR2D2_Test+0x553081)
    #9 0x5527c5 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*) (/root/UTopia/exp/bullet3/output/fuzzers/InvDynCompare_bulletUrdfR2D2_Test+0x5527c5)
    #10 0x554a67 in fuzzer::Fuzzer::MutateAndTestOne() (/root/UTopia/exp/bullet3/output/fuzzers/InvDynCompare_bulletUrdfR2D2_Test+0x554a67)
    #11 0x555765 in fuzzer::Fuzzer::Loop(std::__Fuzzer::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) (/root/UTopia/exp/bullet3/output/fuzzers/InvDynCompare_bulletUrdfR2D2_Test+0x555765)
    #12 0x54411e in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/root/UTopia/exp/bullet3/output/fuzzers/InvDynCompare_bulletUrdfR2D2_Test+0x54411e)
    #13 0x56cf62 in main (/root/UTopia/exp/bullet3/output/fuzzers/InvDynCompare_bulletUrdfR2D2_Test+0x56cf62)
    #14 0x78edf7ec3082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082)
    #15 0x518e9d in _start (/root/UTopia/exp/bullet3/output/fuzzers/InvDynCompare_bulletUrdfR2D2_Test+0x518e9d)

0x0000010c642a is located 0 bytes to the right of global variable 'kUrdfFile' defined in '/root/UTopia/exp/bullet3/test/InverseDynamics/test_invdyn_bullet.cpp:100:13' (0x10c6420) of size 10
SUMMARY: AddressSanitizer: global-buffer-overflow (/root/UTopia/exp/bullet3/output/fuzzers/InvDynCompare_bulletUrdfR2D2_Test+0x5ee6bd) in fopen
Shadow bytes around the buggy address:
  0x000080210c30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x000080210c40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x000080210c50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x000080210c60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x000080210c70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x000080210c80: 00 00 00 00 00[02]f9 f9 f9 f9 f9 f9 00 00 00 00
  0x000080210c90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x000080210ca0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x000080210cb0: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
  0x000080210cc0: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
  0x000080210cd0: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==1070050==ABORTING
MS: 6 InsertRepeatedBytes-Custom-CustomCrossOver-CopyPart-Custom-CustomCrossOver-; base unit: dc15c9a1e05137db1c07d46f92cefd6312ad73a7
artifact_prefix='./'; Test unit written to ./crash-8dba9035c836f8946291d62e4c90c3632bf27e98

DUT-ShiLongYu avatar Sep 30 '24 11:09 DUT-ShiLongYu