From owner-freebsd-ia64 Thu Mar 6 18:16:47 2003 Delivered-To: freebsd-ia64@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 61B2B37B405; Thu, 6 Mar 2003 18:16:42 -0800 (PST) Received: from hermes.sc.intel.com (fmr03.intel.com [143.183.121.5]) by mx1.FreeBSD.org (Postfix) with ESMTP id 66FEA43F93; Thu, 6 Mar 2003 18:16:41 -0800 (PST) (envelope-from adsharma@unix-os.sc.intel.com) Received: from petasus.sc.intel.com (petasus.sc.intel.com [10.3.253.4]) by hermes.sc.intel.com (8.11.6/8.11.6/d: outer.mc,v 1.51 2002/09/23 20:43:23 dmccart Exp $) with ESMTP id h272E7O23398; Fri, 7 Mar 2003 02:14:07 GMT Received: from unix-os.sc.intel.com (unix-os.sc.intel.com [143.183.96.244]) by petasus.sc.intel.com (8.11.6/8.11.6/d: inner.mc,v 1.28 2003/01/13 19:44:39 dmccart Exp $) with ESMTP id h272Ffm15769; Fri, 7 Mar 2003 02:15:41 GMT Received: from unix-os.sc.intel.com.intel.com (adsharma-mobl3.sc.intel.com [143.183.130.51]) by unix-os.sc.intel.com (8.11.6/8.11.2) with ESMTP id h272Gev29185; Thu, 6 Mar 2003 18:16:40 -0800 Date: Thu, 6 Mar 2003 18:16:40 -0800 Message-Id: <200303070216.h272Gev29185@unix-os.sc.intel.com> To: freebsd-ia64@freebsd.org Cc: jdp@freebsd.org Subject: Review fix for ia64/48024 From: Arun Sharma Sender: owner-freebsd-ia64@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org The following changes are proposed to: rtld-elf - factor out alloc_fptrs into a function of its own - update the fptrs array of the defining object rather than the referencing object - We use the same algorithm to index fptrs array now in make_function_pointer and reloc_non_plt_obj. Issues: - Is it possible to make an out of bounds access to the fptr array ? -Arun --- ia64/reloc.c- Fri Mar 7 02:06:30 2003 +++ ia64/reloc.c Fri Mar 7 02:06:16 2003 @@ -77,6 +77,31 @@ static struct fptr *next_fptr = &first_chunk.fptrs[0]; static struct fptr *last_fptr = &first_chunk.fptrs[FPTR_CHUNK_SIZE]; +static struct fptr ** +alloc_fptrs(const Obj_Entry *obj, Obj_Entry *obj_rtld) +{ + struct fptr **fptrs; + int fbytes = obj->nchains * sizeof(struct fptr *); + + /* + * When relocating rtld itself, we need to avoid using malloc. + */ + if (obj == obj_rtld) { + fptrs = mmap(NULL, fbytes, PROT_READ|PROT_WRITE, + MAP_ANON, -1, 0); + if (fptrs == MAP_FAILED) + fptrs = NULL; + } else { + fptrs = (struct fptr **) + malloc(obj->nchains * sizeof(struct fptr *)); + } + + if (fptrs != NULL) + memset(fptrs, 0, fbytes); + + return fptrs; +} + /* * We use static storage initially so that we don't have to call * malloc during init_rtld(). @@ -101,8 +126,9 @@ /* Relocate a non-PLT object with addend. */ static int reloc_non_plt_obj(Obj_Entry *obj_rtld, Obj_Entry *obj, const Elf_Rela *rela, - SymCache *cache, struct fptr **fptrs) + SymCache *cache) { + struct fptr **fptrs; Elf_Addr *where = (Elf_Addr *) (obj->relocbase + rela->r_offset); switch (ELF_R_TYPE(rela->r_info)) { @@ -135,9 +161,7 @@ /* * We have to make sure that all @fptr references to * the same function are identical so that code can - * compare function pointers. We actually only bother - * to ensure this within a single object. If the - * caller's alloca failed, we don't even ensure that. + * compare function pointers. */ const Elf_Sym *def; const Obj_Entry *defobj; @@ -150,18 +174,28 @@ return -1; if (def->st_shndx != SHN_UNDEF) { + int index; target = (Elf_Addr)(defobj->relocbase + def->st_value); gp = (Elf_Addr)defobj->pltgot; + fptrs = defobj->priv; + index = def - defobj->symtab; + + if (!fptrs) { + /* Need to allocate one */ + fptrs = alloc_fptrs(defobj, obj_rtld); + if (fptrs) + ((Obj_Entry*) defobj)->priv = fptrs; + } /* * Find the @fptr, using fptrs as a helper. */ if (fptrs) - fptr = fptrs[ELF_R_SYM(rela->r_info)]; + fptr = fptrs[index]; if (!fptr) { fptr = alloc_fptr(target, gp); if (fptrs) - fptrs[ELF_R_SYM(rela->r_info)] = fptr; + fptrs[index] = fptr; } } else fptr = NULL; @@ -221,7 +255,6 @@ SymCache *cache; struct fptr **fptrs; int bytes = obj->nchains * sizeof(SymCache); - int fbytes = obj->nchains * sizeof(struct fptr *); int r = -1; /* @@ -234,21 +267,9 @@ if (cache != NULL) memset(cache, 0, bytes); - /* - * When relocating rtld itself, we need to avoid using malloc. - */ - if (obj == obj_rtld) { - fptrs = mmap(NULL, fbytes, PROT_READ|PROT_WRITE, - MAP_ANON, -1, 0); - if (fptrs == MAP_FAILED) - fptrs = NULL; - } else { - fptrs = (struct fptr **) - malloc(obj->nchains * sizeof(struct fptr *)); - } + fptrs = alloc_fptrs(obj, obj_rtld); if (fptrs == NULL) goto done; - memset(fptrs, 0, fbytes); /* Perform relocations without addend if there are any: */ rellim = (const Elf_Rel *) ((caddr_t) obj->rel + obj->relsize); @@ -258,14 +279,14 @@ locrela.r_info = rel->r_info; locrela.r_offset = rel->r_offset; locrela.r_addend = 0; - if (reloc_non_plt_obj(obj_rtld, obj, &locrela, cache, fptrs)) + if (reloc_non_plt_obj(obj_rtld, obj, &locrela, cache)) goto done; } /* Perform relocations with addend if there are any: */ relalim = (const Elf_Rela *) ((caddr_t) obj->rela + obj->relasize); for (rela = obj->rela; obj->rela != NULL && rela < relalim; rela++) { - if (reloc_non_plt_obj(obj_rtld, obj, rela, cache, fptrs)) + if (reloc_non_plt_obj(obj_rtld, obj, rela, cache)) goto done; } @@ -290,10 +311,12 @@ if (cache) munmap(cache, bytes); if (fptrs) { - if (obj == obj_rtld) + if (obj == obj_rtld) { + int fbytes = obj->nchains * sizeof(struct fptr *); munmap(fptrs, fbytes); - else + } else { free(fptrs); + } } return (r); } @@ -449,9 +472,9 @@ * dlsym("dlopen"). Actually, I'm not sure it can ever * happen. */ - fptrs = (struct fptr **) - malloc(obj->nchains * sizeof(struct fptr *)); - memset(fptrs, 0, obj->nchains * sizeof(struct fptr *)); + + /* assume obj != obj_rtld */ + fptrs = alloc_fptrs((Obj_Entry *) obj, NULL); ((Obj_Entry*) obj)->priv = fptrs; } if (!fptrs[index]) { To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-ia64" in the body of the message