This is the mail archive of the glibc-bugs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug nss/19341] New: statically linked multi-threaded program fails to initialize ctype info in existing threads


https://sourceware.org/bugzilla/show_bug.cgi?id=19341

            Bug ID: 19341
           Summary: statically linked multi-threaded program fails to
                    initialize ctype info in existing threads
           Product: glibc
           Version: 2.21
            Status: NEW
          Severity: normal
          Priority: P2
         Component: nss
          Assignee: unassigned at sourceware dot org
          Reporter: ian at airs dot com
  Target Milestone: ---

This glibc bug report is extracted from https://golang.org/issue/13470.

If you statically link the following C program and run it on Ubuntu Wily, which
uses glibc 2.21, it will crash.

I believe that the problem is that the ctype code relies on TLS variables
initialized by __ctype_init.  The getpwuid_r function in a statically linked
program relies on opening a supporting shared library.  The supporting shared
library can not see the ctype information in the statically linked executable,
which has no dynamic symbol table, and therefore has its own copy.  That copy
is correctly initialized by a call to __ctype_init.  However, if there are any
existing threads, the shared library copy of the TLS ctype information is never
initialized.  So, if the program manages to call getpwuid_r on a thread that
existed when the shared library was opened, it crashes.

Test case:

#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <pwd.h>
#include <pthread.h>

static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

static void *thread(void *arg) {
        struct passwd pwd;
        char buf[1024];
        struct passwd *result;
        pthread_mutex_lock(&mutex);
        getpwuid_r(0, &pwd, buf, sizeof buf, &result);
        return NULL;
}

int main() {
        pthread_t tid;
        struct passwd pwd;
        char buf[1024];
        struct passwd *result;
        void *retval;
        pthread_mutex_lock(&mutex);
        pthread_create(&tid, NULL, thread, NULL);
        getpwuid_r(0, &pwd, buf, sizeof buf, &result);
        pthread_mutex_unlock(&mutex);
        pthread_join(tid, &retval);
        return 0;
}

Contents of /etc/nsswitch.conf on the failing system:

# /etc/nsswitch.conf
#
# Example configuration of GNU Name Service Switch functionality.
# If you have the `glibc-doc-reference' and `info' packages installed, try:
# `info libc "Name Service Switch"' for information about this file.

passwd:         compat
group:          compat
shadow:         compat
gshadow:        files

hosts:          files dns
networks:       files

protocols:      db files
services:       db files
ethers:         db files
rpc:            db files

netgroup:       nis

-- 
You are receiving this mail because:
You are on the CC list for the bug.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]