loslib.c patch

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view

loslib.c patch

Lee Shallis
gcc complains about tmpnam when using the -Werror option, I propose this code to rectify that:
typedef unsigned int lua_uint;
size_t u2a( char *str, size_t size, lua_uint val, lua_uint base, lua_uint small ) {
static const char bstr[] = "0123456789ABCDEF";
static const char sstr[] = "0123456789abcdef";
static const size_t min = (sizeof(int) * CHAR_BIT);
    const char *s = small ? sstr : bstr;
    size_t i = 0;
    if ( !str || !size || base < 2 || base > strlen(s) ) return 0;
    if ( size < min ) {
        memset( str, 0, size );
        return 0;
    while ( val > 0u ) {
        str[i++] = s[val % base];
        val /= base;
    str[i] = 0;
    return i;
/* Avoids unistd.h, can expect sys/stat.h on all supported systems */
#include <sys/stat.h>
size_t tmpname( char *str, size_t size ) {
    size_t i;
    struct stat m = {0};
    if ( u2a( str, --size, 0, 2, 0 ) == 0 ) return 0;
    str[0] = '_';
    do {
        i = u2a( str, size, rand(), 16, 1 );
    } while ( stat(str,&m) == 1 );
    return i;

static int os_tmpname (lua_State *L) {
  if ( tmpname(buff, LUA_TMPNAMBUFSIZE) == 0 )
    return luaL_error(L, "unable to generate a unique filename");
  lua_pushstring(L, buff);
  return 1;
Feel free to modify
Reply | Threaded
Open this post in threaded view

Re: loslib.c patch

Ivan Krylov
Hi Lee,

On Fri, 18 Jan 2019 21:09:16 +0000
Lee Shallis <[hidden email]> wrote:

> gcc complains about tmpnam when using the -Werror option

tmpnam() is only used when POSIX functions are not available. Since you
seem to be using Linux Mint, you should #define LUA_USE_POSIX to make
Lua use mkstemp() instead of tmpnam(), which is much safer.

In fact, luaconf.h already #define's LUA_USE_POSIX when it sees
defined(LUA_USE_LINUX), which you should have defined when building for
Linux. How are you building Lua?

Your proposed code does the same thing as tmpnam() (except not using
static variables, which is an improvement), so, unfortunately, it is
subject to the same race condition that tmpnam() has: there is a short
window of time between obtaining a "unique" filename and actually
opening a file descriptor to it when an attacker can create a symbolic
link with the "unique" name to a different file and cause your program
to overwrite that latter file instead of the temporary file.

What mkstemp() does instead is to keep trying to create the
randomly-named file by calling open() with O_CREAT | O_EXCL, until
either open returns a valid file descriptor, ensuring that the file has
been just created by the current process, or the number of attempts is

Best regards,