Bug #23166 Common name used in libmysqlclient: shutdown()
Submitted: 11 Oct 2006 8:23 Modified: 11 Oct 2006 8:35
Reporter: Timothy Smith Email Updates:
Status: Not a Bug Impact on me:
None 
Category:MySQL Server: C API (client library) Severity:S3 (Non-critical)
Version:any OS:Any (any)
Assigned to: Timothy Smith CPU Architecture:Any

[11 Oct 2006 8:23] Timothy Smith
Description:
Reported by a friend:

============================================
While trying to log into the server (without valid user information) I got:

Shutdown NOW!
shutdown: [pid 40292]
loggerinit[40289]: Can't connect to database server: 28000 Access denied for user 'grog'@'
localhost' (using password: NO) (1045)

It was repeatable (after rebooting), and I was able to confirm that it was really executing /sbin/shutdown, so I changed the permissions on that program, but still got a corresponding error message. Even after fixing the access permissions, it continued trying to shut down. Established it was happening in mysql_close, so set a breakpoint on fork and found:

Breakpoint 2, 0x28323bf4 in fork () from /lib/libc.so.6
(gdb) bt
#0  0x28323bf4 in fork () from /lib/libc.so.6
#1  0x282b01f5 in fork () from /usr/lib/libpthread.so.2
#2  0x282ece3f in system () from /lib/libc.so.6
#3  0x282ae346 in system () from /usr/lib/libpthread.so.2
#4  0x0804a20e in shutdown () at misc.c:357
#5  0x2823f388 in vio_close () from /usr/local/lib/mysql/libmysqlclient.so.15
#6  0x2823f02e in vio_delete () from /usr/local/lib/mysql/libmysqlclient.so.15
#7  0x2823a0cc in end_server () from /usr/local/lib/mysql/libmysqlclient.so.15
#8  0x2823b541 in mysql_close () from /usr/local/lib/mysql/libmysqlclient.so.15
#9  0x080498e8 in main (argc=1085, argv=0xbfbfe320, envp=0xbfbfe328) at loggerinit.c:289
(gdb)

That looks innocent enough. The code in vio_close is:

 if (vio->type != VIO_CLOSED)
  {
    DBUG_ASSERT(vio->sd >= 0);
    if (shutdown(vio->sd,2))
      r= -1;
    if (closesocket(vio->sd))
      r= -1;
  }

But shutdown is a system call that shuts down a socket; why is it invoking /sbin/shutdown to shut down the system? The clue is above: it's at line 357 of misc.c (the fact that it has a line number at all is a smoking gun). In our application we had:

void shutdown ()
{
  /* shut unit down */
  draw_menu_text (2, "Shutting Down");
  sleep (3);
  system ("/sbin/shutdown -p now");
}

So it's a name conflict. Changed the name to system_shutdown and all was well.
============================================

How to repeat:
2:13 ~/m/tmp/bug-greg$ head -1000 *.c Makefile
==> shutdown.c <==
#include <stdio.h>
void shutdown() {
        fputs("*\n* shutdown() called\n*\n\n", stderr);
        fflush(stderr);
}

==> t.c <==
#include <stdio.h>
#include <stdlib.h>
#include <mysql.h>
extern void shutdown();

void _die(const char *file, unsigned int line, MYSQL *dbh) {
        fprintf(stderr, "ERROR: %s:%d: %s\n", file, line, dbh ? mysql_error(dbh) : "out of memory");
        exit(EXIT_FAILURE);
}
#define die(dbh) _die(__FILE__, __LINE__, (dbh))
int main(void) {
        MYSQL *dbh = mysql_init(NULL);
        if (dbh == NULL)
                die(dbh);
        if (mysql_real_connect(dbh, NULL, "nonexistent_user", "broken_pass", NULL, 0, NULL, 0) == NULL)
                die(dbh);
        mysql_close(dbh);

        exit(EXIT_SUCCESS);
}

==> Makefile <==
CPPFLAGS = -I/usr/local/include/mysql
CFLAGS = -g -O -W -Wall
LDFLAGS = -L/usr/local/lib/mysql

t: t.o shutdown.o
        gcc -o $@ t.o shutdown.o $(LDFLAGS) -lmysqlclient -lz -lm

clean:
        rm -f *.o *core* t

Suggested fix:
rename shutdown() in vio to a less common name
[11 Oct 2006 8:35] Timothy Smith
man shutdown(2); system function.