Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crashes on start - malloc(): invalid next size (unsorted) #7496

Open
heirecka opened this issue Apr 10, 2019 · 5 comments
Open

Crashes on start - malloc(): invalid next size (unsorted) #7496

heirecka opened this issue Apr 10, 2019 · 5 comments

Comments

@heirecka
Copy link

@heirecka heirecka commented Apr 10, 2019

Version of OpenTTD

1.9.1, but it also happens with 1.9.0
Compiled on Linux with gcc 8.3.0 and glibc 2.29

Expected result

openttd starts fine

Actual result

malloc(): invalid next size (unsorted)
Crash encountered, generating crash log...
malloc(): invalid next size (unsorted)
zsh: abort (core dumped) openttd

Steps to reproduce

$ openttd

Backtrace (without debug symbols):
#0  0x00007ffff73bb5df in raise () from /usr/x86_64-pc-linux-gnu/lib/libc.so.6
#1  0x00007ffff73a6541 in abort () from /usr/x86_64-pc-linux-gnu/lib/libc.so.6
#2  0x00007ffff73fdbc6 in __libc_message () from /usr/x86_64-pc-linux-gnu/lib/libc.so.6
#3  0x00007ffff740445a in malloc_printerr () from /usr/x86_64-pc-linux-gnu/lib/libc.so.6
#4  0x00007ffff7407194 in _int_malloc () from /usr/x86_64-pc-linux-gnu/lib/libc.so.6
#5  0x00007ffff7409626 in calloc () from /usr/x86_64-pc-linux-gnu/lib/libc.so.6
#6  0x000055555598c23d in stredup(char const*, char const*) ()
#7  0x00005555557c7f6f in DetermineBasePaths(char const*) ()
#8  0x00005555557c81fb in DeterminePaths(char const*) ()
#9  0x00005555558b0230 in openttd_main(int, char**) ()
#10 0x00007ffff73a7c03 in __libc_start_main () from /usr/x86_64-pc-linux-gnu/lib/libc.so.6
#11 0x000055555570681e in _start ()
@nielsmh

This comment has been minimized.

Copy link
Contributor

@nielsmh nielsmh commented Apr 10, 2019

This looks strange, as far as I can tell there is no way for stredup() to attempt a zero byte allocation, since it always adds 1 to the input string length. The only other possibility I can think of would be some kind of buffer overrun causing it to attempt a far too large allocation (say multiple gigabytes).

There are multiple cases of stredup() in DetermineBasePaths(), do you think you can narrow it down?

OpenTTD/src/fileio.cpp

Lines 1053 to 1151 in b61ef7e

/**
* Determine the base (personal dir and game data dir) paths
* @param exe the path to the executable
*/
void DetermineBasePaths(const char *exe)
{
char tmp[MAX_PATH];
#if defined(WITH_XDG_BASEDIR) && defined(WITH_PERSONAL_DIR)
const char *xdg_data_home = xdgDataHome(NULL);
seprintf(tmp, lastof(tmp), "%s" PATHSEP "%s", xdg_data_home,
PERSONAL_DIR[0] == '.' ? &PERSONAL_DIR[1] : PERSONAL_DIR);
free(xdg_data_home);
AppendPathSeparator(tmp, lastof(tmp));
_searchpaths[SP_PERSONAL_DIR_XDG] = stredup(tmp);
#endif
#if defined(__MORPHOS__) || defined(__AMIGA__) || defined(DOS) || defined(OS2) || !defined(WITH_PERSONAL_DIR)
_searchpaths[SP_PERSONAL_DIR] = NULL;
#else
#ifdef __HAIKU__
BPath path;
find_directory(B_USER_SETTINGS_DIRECTORY, &path);
const char *homedir = stredup(path.Path());
#else
/* getenv is highly unsafe; duplicate it as soon as possible,
* or at least before something else touches the environment
* variables in any way. It can also contain all kinds of
* unvalidated data we rather not want internally. */
const char *homedir = getenv("HOME");
if (homedir != NULL) {
homedir = stredup(homedir);
}
if (homedir == NULL) {
const struct passwd *pw = getpwuid(getuid());
homedir = (pw == NULL) ? NULL : stredup(pw->pw_dir);
}
#endif
if (homedir != NULL) {
ValidateString(homedir);
seprintf(tmp, lastof(tmp), "%s" PATHSEP "%s", homedir, PERSONAL_DIR);
AppendPathSeparator(tmp, lastof(tmp));
_searchpaths[SP_PERSONAL_DIR] = stredup(tmp);
free(homedir);
} else {
_searchpaths[SP_PERSONAL_DIR] = NULL;
}
#endif
#if defined(WITH_SHARED_DIR)
seprintf(tmp, lastof(tmp), "%s", SHARED_DIR);
AppendPathSeparator(tmp, lastof(tmp));
_searchpaths[SP_SHARED_DIR] = stredup(tmp);
#else
_searchpaths[SP_SHARED_DIR] = NULL;
#endif
#if defined(__MORPHOS__) || defined(__AMIGA__)
_searchpaths[SP_WORKING_DIR] = NULL;
#else
if (getcwd(tmp, MAX_PATH) == NULL) *tmp = '\0';
AppendPathSeparator(tmp, lastof(tmp));
_searchpaths[SP_WORKING_DIR] = stredup(tmp);
#endif
_do_scan_working_directory = DoScanWorkingDirectory();
/* Change the working directory to that one of the executable */
if (ChangeWorkingDirectoryToExecutable(exe)) {
if (getcwd(tmp, MAX_PATH) == NULL) *tmp = '\0';
AppendPathSeparator(tmp, lastof(tmp));
_searchpaths[SP_BINARY_DIR] = stredup(tmp);
} else {
_searchpaths[SP_BINARY_DIR] = NULL;
}
if (_searchpaths[SP_WORKING_DIR] != NULL) {
/* Go back to the current working directory. */
if (chdir(_searchpaths[SP_WORKING_DIR]) != 0) {
DEBUG(misc, 0, "Failed to return to working directory!");
}
}
#if defined(__MORPHOS__) || defined(__AMIGA__) || defined(DOS) || defined(OS2)
_searchpaths[SP_INSTALLATION_DIR] = NULL;
#else
seprintf(tmp, lastof(tmp), "%s", GLOBAL_DATA_DIR);
AppendPathSeparator(tmp, lastof(tmp));
_searchpaths[SP_INSTALLATION_DIR] = stredup(tmp);
#endif
#ifdef WITH_COCOA
extern void cocoaSetApplicationBundleDir();
cocoaSetApplicationBundleDir();
#else
_searchpaths[SP_APPLICATION_BUNDLE_DIR] = NULL;
#endif
}

@LordAro

This comment has been minimized.

Copy link
Member

@LordAro LordAro commented Apr 10, 2019

(./configure --enable-debug=2 gets you debugging symbols)

@LordAro LordAro changed the title Crashes on start Crashes on start - malloc(): invalid next size (unsorted) Apr 10, 2019
@heirecka

This comment has been minimized.

Copy link
Author

@heirecka heirecka commented Apr 10, 2019

The one in 1067 apparently

(gdb) bt
#0  0x00007ffff73bb5df in raise () from /usr/x86_64-pc-linux-gnu/lib/libc.so.6
#1  0x00007ffff73a6541 in abort () from /usr/x86_64-pc-linux-gnu/lib/libc.so.6
#2  0x00007ffff73fdbc6 in __libc_message () from /usr/x86_64-pc-linux-gnu/lib/libc.so.6
#3  0x00007ffff740445a in malloc_printerr () from /usr/x86_64-pc-linux-gnu/lib/libc.so.6
#4  0x00007ffff7407194 in _int_malloc () from /usr/x86_64-pc-linux-gnu/lib/libc.so.6
#5  0x00007ffff7409626 in calloc () from /usr/x86_64-pc-linux-gnu/lib/libc.so.6
#6  0x0000555555a84ef3 in CallocT<char> (num_elements=num_elements@entry=34)
    at /var/tmp/paludis/build/games-simulation-openttd-1.9.1/work/openttd-1.9.1/src/core/alloc_func.hpp:87
#7  0x0000555555a850a5 in stredup (s=s@entry=0x7fffffffac00 "/home/heiko/.local/share/openttd/", last=last@entry=0x0)
    at /var/tmp/paludis/build/games-simulation-openttd-1.9.1/work/openttd-1.9.1/src/string.cpp:141
#8  0x00005555558c34af in DetermineBasePaths (exe=0x7fffffffe408 "/usr/x86_64-pc-linux-gnu/bin/openttd")
    at /var/tmp/paludis/build/games-simulation-openttd-1.9.1/work/openttd-1.9.1/src/fileio.cpp:1067
#9  0x00005555558c36e4 in DeterminePaths (exe=<optimized out>)
    at /var/tmp/paludis/build/games-simulation-openttd-1.9.1/work/openttd-1.9.1/src/fileio.cpp:1164
#10 0x00005555559ad22c in openttd_main (argc=<optimized out>, argv=0x7fffffffe028)
    at /var/tmp/paludis/build/games-simulation-openttd-1.9.1/work/openttd-1.9.1/src/openttd.cpp:703
#11 0x00007ffff73a7c03 in __libc_start_main () from /usr/x86_64-pc-linux-gnu/lib/libc.so.6
#12 0x0000555555816f9e in _start () at /var/tmp/paludis/build/games-simulation-openttd-1.9.1/work/openttd-1.9.1/src/fileio.cpp:1470
@JGRennison

This comment has been minimized.

Copy link
Contributor

@JGRennison JGRennison commented Apr 13, 2019

This sort of error suggests that heap corruption most likely took place before the point where the crash occurred.

CFLAGS="-fno-omit-frame-pointer -fsanitize=address -g" LDFLAGS="-fsanitize=address -g" ./configure
(all on one line)
may give you a clearer indication of where the problem is.
You may need to install libasan first.

@LordAro

This comment has been minimized.

Copy link
Member

@LordAro LordAro commented Jan 2, 2020

@heirecka Have you been able to reproduce this? No one else has seen this particular crash since...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants
You can’t perform that action at this time.