From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 7247 invoked by alias); 8 Nov 2006 15:27:14 -0000 Received: (qmail 7229 invoked by uid 22791); 8 Nov 2006 15:27:14 -0000 X-Spam-Check-By: sourceware.org Received: from sunsite.ms.mff.cuni.cz (HELO sunsite.mff.cuni.cz) (195.113.15.26) by sourceware.org (qpsmtpd/0.31) with ESMTP; Wed, 08 Nov 2006 15:27:03 +0000 Received: from sunsite.mff.cuni.cz (sunsite.mff.cuni.cz [127.0.0.1]) by sunsite.mff.cuni.cz (8.13.1/8.13.1) with ESMTP id kA8FQw0W004346; Wed, 8 Nov 2006 16:26:58 +0100 Received: (from jj@localhost) by sunsite.mff.cuni.cz (8.13.1/8.13.1/Submit) id kA8FQws9004343; Wed, 8 Nov 2006 16:26:58 +0100 Date: Wed, 08 Nov 2006 15:27:00 -0000 From: Jakub Jelinek To: Ulrich Drepper Cc: Glibc hackers Subject: [PATCH] Fix --inhibit-rpath Message-ID: <20061108152658.GI5868@sunsite.mff.cuni.cz> Reply-To: Jakub Jelinek Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.4.1i Mailing-List: contact libc-hacker-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-hacker-owner@sourceware.org X-SW-Source: 2006-11/txt/msg00003.txt.bz2 Hi! As http://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=214569 testcase shows, ld.so segfaults when --inhibit-rpath is used. The problem is that for objects on the inhibit_rpath list, decompose_rpath sets dirs to a one entry array containing NULL, but for this cache_rpath returns there is rpath and open_path and add_path both rely that the NULL terminated array of pointers (sps->dirs) contains at least one element (both use do ... while (*dirs != NULL) style loops etc.). sps->dirs = (void *) -1 is used elsewhere to say the rpath has been cached, but is unavailable. But, even cache_rpath which called decompose_rpath needs to return false in that case. Alternatively, we could analyze all places where sps->dirs is used and make it handle sps->dirs != NULL && sps->dirs != (void *) -1 && sps->dirs[0] == NULL case the same way as sps->dirs == (void *) -1. But, having two different ways to tell the same thing sounds wrong to me. 2006-11-08 Jakub Jelinek * elf/dl-load.c (decompose_rpath): Return bool rather than void. If l->l_name is on inhibit_rpath list, set sps->dirs to -1 and return false, otherwise return true. (cache_rpath): Return decompose_rpath return value. --- libc/elf/dl-load.c.jj 2006-10-31 23:08:30.000000000 +0100 +++ libc/elf/dl-load.c 2006-11-08 16:14:44.000000000 +0100 @@ -511,7 +511,7 @@ fillin_rpath (char *rpath, struct r_sear } -static void +static bool internal_function decompose_rpath (struct r_search_path_struct *sps, const char *rpath, struct link_map *l, const char *what) @@ -546,19 +546,8 @@ decompose_rpath (struct r_search_path_st { /* This object is on the list of objects for which the RUNPATH and RPATH must not be used. */ - result = calloc (1, sizeof *result); - if (result == NULL) - { - signal_error_cache: - errstring = N_("cannot create cache for search path"); - signal_error: - _dl_signal_error (ENOMEM, NULL, NULL, errstring); - } - - sps->dirs = result; - sps->malloced = 1; - - return; + sps->dirs = (void *) -1; + return false; } while (*inhp != '\0') @@ -588,7 +577,11 @@ decompose_rpath (struct r_search_path_st result = (struct r_search_path_elem **) malloc ((nelems + 1 + 1) * sizeof (*result)); if (result == NULL) - goto signal_error_cache; + { + errstring = N_("cannot create cache for search path"); + signal_error: + _dl_signal_error (ENOMEM, NULL, NULL, errstring); + } fillin_rpath (copy, result, ":", 0, what, where); @@ -599,6 +592,7 @@ decompose_rpath (struct r_search_path_st sps->dirs = result; /* The caller will change this value if we haven't used a real malloc. */ sps->malloced = 1; + return true; } /* Make sure cached path information is stored in *SP @@ -623,10 +617,9 @@ cache_rpath (struct link_map *l, } /* Make sure the cache information is available. */ - decompose_rpath (sp, (const char *) (D_PTR (l, l_info[DT_STRTAB]) - + l->l_info[tag]->d_un.d_val), - l, what); - return true; + return decompose_rpath (sp, (const char *) (D_PTR (l, l_info[DT_STRTAB]) + + l->l_info[tag]->d_un.d_val), + l, what); } Jakub