From patchwork Fri Mar 14 21:54:05 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Pluzhnikov X-Patchwork-Id: 96 Return-Path: X-Original-To: siddhesh@wilcox.dreamhost.com Delivered-To: siddhesh@wilcox.dreamhost.com Received: from homiemail-mx20.g.dreamhost.com (caibbdcaaahc.dreamhost.com [208.113.200.72]) by wilcox.dreamhost.com (Postfix) with ESMTP id C934C360180 for ; Fri, 14 Mar 2014 14:54:12 -0700 (PDT) Received: by homiemail-mx20.g.dreamhost.com (Postfix, from userid 14307373) id 7B292419131AE; Fri, 14 Mar 2014 14:54:12 -0700 (PDT) X-Original-To: glibc@patchwork.siddhesh.in Delivered-To: x14307373@homiemail-mx20.g.dreamhost.com Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by homiemail-mx20.g.dreamhost.com (Postfix) with ESMTPS id 2DF50418AACDA for ; Fri, 14 Mar 2014 14:54:12 -0700 (PDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:cc:subject:date:message-id :mime-version:content-type; q=dns; s=default; b=DTtZQntlF+ZpguKy lo5+A3UvBfB1D3V3sO8I/DHjNxitRnj+ONy5EceP18Tl/Jkq/DR4m6v45/m/fodq PAPfw1DTAPZ0JsplqZrktTQSz5vByOtgGcyxRZ2uB+viqk1Upv3sCF7mbEbc6vxz kx+Hr5ys93EJSO7HqFA62taN/8I= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:cc:subject:date:message-id :mime-version:content-type; s=default; bh=QQDeedwvdlb96FarfVvnFk h+IOk=; b=dRx+sof8rP/hB8NlPxzKnRqwkXX2ydqoIRUXLgB+JNT7LJEAidyyE3 Oe0Ckw31SygEVoJCA7NZdd0+LqLKbkDM7ImuGNQkFOrZtlVS9T6KpSOyD9pWxTg2 AdRXyxCobjZZ8+DrRArYWkHiqAMuB1Ha877rb9WUxTmJSTlk2ejKY= Received: (qmail 32395 invoked by alias); 14 Mar 2014 21:54:10 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 32386 invoked by uid 89); 14 Mar 2014 21:54:09 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.7 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW, SPF_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mail-ob0-f201.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-type; bh=GP6xbNysNoCUpg4sMUDsqcmGc6sBYovXRk61THtvj7Q=; b=Ua87TK0uRcz4JL77a1q5fSgWU/Bn5gBz+Z8x9x5hNqqMUC3X6v06oaou8SmZSijvkS zSYjPyvW6IoDI/p+GZWrOu6XZvTt34vfVgzF0mJse4GzDJz3phUUZXw/8qIXFVPq5DOa FK2QGBJyGeckuyFLEkZ/W+Yb6/cqTCoyWzG5V2HPoGW1H8c15IIBL3zr8haJGWjjekx7 RB8RCRAph8QcD4mLxmRnuLw6Z2NU7DAwT1uG/kocUz6Rl/JQE4N0vSKiQD9lypGCEAPR Q0dCGgMx6vIL9tHL6ugpcpq9qfw/VxE0vGoZskf45xekEyeRbfjR/SRn58Byp6nMR2BY x0tw== X-Gm-Message-State: ALoCoQnr0xh8ms+EJix1s2bbNgscnLPlzSY7IjwOjxvMzjaQCP1rF+6l1uW4P4o+x2bvjHXPbmfHUC+G/+cw7d0w8NVbw4/tHzhpbYulmNzf+WSHzeOArS8JmapRGAQHMhcnwnqcQ6gxzgSsS2VNwvc+aeDiBgL75On0skNdeF3wqES4tVLZAe7xGEMWx1o4h0sPnFzhGk0Tq1Sm0T79CuYUs9sNyZ1SyA== X-Received: by 10.42.230.79 with SMTP id jl15mr3503000icb.7.1394834046264; Fri, 14 Mar 2014 14:54:06 -0700 (PDT) From: Paul Pluzhnikov To: libc-alpha@sourceware.org Cc: ppluzhnikov@google.com Subject: [patch] Fix BZ #16634 -- assert in ld.so when dlopen("a.out"...) is called repeatedly. Date: Fri, 14 Mar 2014 14:54:05 -0700 Message-ID: MIME-Version: 1.0 X-DH-Original-To: glibc@patchwork.siddhesh.in Greetings, Attached patch fixes BZ #16634 by moving sanity check for dlopen()ing a.out before we call _dl_next_tls_modid() for it. Tested on Linux/x86_64; no new failures. --- 2014-03-14 Paul Pluzhnikov BZ #16634 * elf/dl-load.c (open_verify): Add mode parameter. Error early when ET_EXEC and mode does not have __RTLD_OPENEXEC. (open_path): Change from boolean 'secure' to complete flag 'mode' (_dl_map_object): Adjust. diff --git a/elf/dl-load.c b/elf/dl-load.c index 8ebc128..3f90b92 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -1667,7 +1667,7 @@ print_search_path (struct r_search_path_elem **list, user might want to know about this. */ static int open_verify (const char *name, struct filebuf *fbp, struct link_map *loader, - int whatcode, bool *found_other_class, bool free_name) + int whatcode, int mode, bool *found_other_class, bool free_name) { /* This is the expected ELF header. */ #define ELF32_CLASS ELFCLASS32 @@ -1843,6 +1843,13 @@ open_verify (const char *name, struct filebuf *fbp, struct link_map *loader, errstring = N_("only ET_DYN and ET_EXEC can be loaded"); goto call_lose; } + else if (__glibc_unlikely (ehdr->e_type == ET_EXEC + && (mode & __RTLD_OPENEXEC) == 0)) + { + /* For BZ #16634, return early. */ + errstring = N_("cannot dynamically load executable"); + goto call_lose; + } else if (__builtin_expect (ehdr->e_phentsize, sizeof (ElfW(Phdr))) != sizeof (ElfW(Phdr))) { @@ -1928,7 +1935,7 @@ open_verify (const char *name, struct filebuf *fbp, struct link_map *loader, if MAY_FREE_DIRS is true. */ static int -open_path (const char *name, size_t namelen, int secure, +open_path (const char *name, size_t namelen, int mode, struct r_search_path_struct *sps, char **realname, struct filebuf *fbp, struct link_map *loader, int whatcode, bool *found_other_class) @@ -1980,8 +1987,8 @@ open_path (const char *name, size_t namelen, int secure, if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS)) _dl_debug_printf (" trying file=%s\n", buf); - fd = open_verify (buf, fbp, loader, whatcode, found_other_class, - false); + fd = open_verify (buf, fbp, loader, whatcode, mode, + found_other_class, false); if (this_dir->status[cnt] == unknown) { if (fd != -1) @@ -2010,7 +2017,7 @@ open_path (const char *name, size_t namelen, int secure, /* Remember whether we found any existing directory. */ here_any |= this_dir->status[cnt] != nonexisting; - if (fd != -1 && __builtin_expect (secure, 0) + if (fd != -1 && __builtin_expect (mode & __RTLD_SECURE, 0) && INTUSE(__libc_enable_secure)) { /* This is an extra security effort to make sure nobody can @@ -2184,7 +2191,7 @@ _dl_map_object (struct link_map *loader, const char *name, for (l = loader; l; l = l->l_loader) if (cache_rpath (l, &l->l_rpath_dirs, DT_RPATH, "RPATH")) { - fd = open_path (name, namelen, mode & __RTLD_SECURE, + fd = open_path (name, namelen, mode, &l->l_rpath_dirs, &realname, &fb, loader, LA_SER_RUNPATH, &found_other_class); @@ -2200,7 +2207,7 @@ _dl_map_object (struct link_map *loader, const char *name, && main_map != NULL && main_map->l_type != lt_loaded && cache_rpath (main_map, &main_map->l_rpath_dirs, DT_RPATH, "RPATH")) - fd = open_path (name, namelen, mode & __RTLD_SECURE, + fd = open_path (name, namelen, mode, &main_map->l_rpath_dirs, &realname, &fb, loader ?: main_map, LA_SER_RUNPATH, &found_other_class); @@ -2208,7 +2215,7 @@ _dl_map_object (struct link_map *loader, const char *name, /* Try the LD_LIBRARY_PATH environment variable. */ if (fd == -1 && env_path_list.dirs != (void *) -1) - fd = open_path (name, namelen, mode & __RTLD_SECURE, &env_path_list, + fd = open_path (name, namelen, mode, &env_path_list, &realname, &fb, loader ?: GL(dl_ns)[LM_ID_BASE]._ns_loaded, LA_SER_LIBPATH, &found_other_class); @@ -2217,7 +2224,7 @@ _dl_map_object (struct link_map *loader, const char *name, if (fd == -1 && loader != NULL && cache_rpath (loader, &loader->l_runpath_dirs, DT_RUNPATH, "RUNPATH")) - fd = open_path (name, namelen, mode & __RTLD_SECURE, + fd = open_path (name, namelen, mode, &loader->l_runpath_dirs, &realname, &fb, loader, LA_SER_RUNPATH, &found_other_class); @@ -2267,7 +2274,8 @@ _dl_map_object (struct link_map *loader, const char *name, { fd = open_verify (cached, &fb, loader ?: GL(dl_ns)[nsid]._ns_loaded, - LA_SER_CONFIG, &found_other_class, false); + LA_SER_CONFIG, mode, &found_other_class, + false); if (__glibc_likely (fd != -1)) { realname = local_strdup (cached); @@ -2287,7 +2295,7 @@ _dl_map_object (struct link_map *loader, const char *name, && ((l = loader ?: GL(dl_ns)[nsid]._ns_loaded) == NULL || __builtin_expect (!(l->l_flags_1 & DF_1_NODEFLIB), 1)) && rtld_search_dirs.dirs != (void *) -1) - fd = open_path (name, namelen, mode & __RTLD_SECURE, &rtld_search_dirs, + fd = open_path (name, namelen, mode, &rtld_search_dirs, &realname, &fb, l, LA_SER_DEFAULT, &found_other_class); /* Add another newline when we are tracing the library loading. */ @@ -2305,7 +2313,7 @@ _dl_map_object (struct link_map *loader, const char *name, else { fd = open_verify (realname, &fb, - loader ?: GL(dl_ns)[nsid]._ns_loaded, 0, + loader ?: GL(dl_ns)[nsid]._ns_loaded, 0, mode, &found_other_class, true); if (__builtin_expect (fd, 0) == -1) free (realname);