From patchwork Wed Nov 12 07:09:29 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Siddhesh Poyarekar X-Patchwork-Id: 409863 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org 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 ozlabs.org (Postfix) with ESMTPS id 3255E140079 for ; Wed, 12 Nov 2014 18:09:48 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:date:from:to:cc:subject:message-id:references :mime-version:content-type:in-reply-to; q=dns; s=default; b=j6hf bqYFPpuHXy5UIZGGQqIpM1p5hCWaV1k6qE7pA955wxGJtbMWLnlQ7ILMZqu8WzMX NtpBVnallNEklbSoXW6AIjlwxMRCCwXyyOJzLmZtO7vHkt+8NDaY5mP5c9+ECr6/ /ypWenYBBpjwt4AyxRELhyiZp8l5GmybCDOFg24= 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:date:from:to:cc:subject:message-id:references :mime-version:content-type:in-reply-to; s=default; bh=EcJzOkXYFb LS3IgOKl1x9ooc4fs=; b=xO/yQINHlWpuv1SwyVVTkvEdJ6HFDdXThJlYqbyjmw HeGVZ628VfsQEu29j6rq73+hrKypn2phTxg6M5OJb6O/Xr5U/tW9cDqI63vbuAE9 xqqfm+vG7xyzgQkxkqhXLQ5zQeYz68HEW/90pY4re6QOvkL0iGfejc5h4uRgp1i2 s= Received: (qmail 29088 invoked by alias); 12 Nov 2014 07:09:43 -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 29073 invoked by uid 89); 12 Nov 2014 07:09:42 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.6 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Date: Wed, 12 Nov 2014 12:39:29 +0530 From: Siddhesh Poyarekar To: "Carlos O'Donell" Cc: Andreas Krebbel , Richard Henderson , GNU C Library , stli@linux.vnet.ibm.com Subject: Re: Misaligned stack on 32-bit s390? Message-ID: <20141112070929.GR2086@spoyarek.pnq.redhat.com> References: <54619F3E.8080306@redhat.com> <5461D6CA.9030902@twiddle.net> <5461DBC4.9090508@redhat.com> <5462231E.3050502@linux.vnet.ibm.com> <5462DB6B.8060405@redhat.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <5462DB6B.8060405@redhat.com> User-Agent: Mutt/1.5.22.1-rc1 (2013-10-16) On Tue, Nov 11, 2014 at 11:00:43PM -0500, Carlos O'Donell wrote: > Please note that the patch I posted is incomplete, it fails to > readjust _dl_argv which is cached by the loader and needs to be > changed if argv is moved. Simple fix though. Here's the updated patch that adjusts _dl_argv. As a result now, _dl_argv is no longer relro on s390. Tested to verify that there are no new failures on s390. OK to commit? Siddhesh * sysdeps/s390/s390-32/dl-machine.h (_dl_start_user): Move argv and envp down instead of moving argc up. * sysdeps/s390/s390-32/dl-sysdep.h: New file. commit b4b885c804fa494a7346794a2d8f54186a8af828 Author: Siddhesh Poyarekar Date: Wed Nov 12 12:37:51 2014 +0530 Fix stack alignment when loader is invoked directly The s390 ABI requires the stack pointer to be aligned at 8-bytes. When a program is invoked as an argument to the dynamic linker, _dl_start_user adjusts the stack to remove the dynamic linker arguments so that the program sees only its name and arguments. This may result in the stack being misaligned since each argument shift is only a word and not a double-word. This is now fixed shifting argv and envp down instead of shifting argc up and reclaiming the stack. This requires _dl_argv to be adjusted and hence, is no longer relro. diff --git a/sysdeps/s390/s390-32/dl-machine.h b/sysdeps/s390/s390-32/dl-machine.h index c56185c..fba8d60 100644 --- a/sysdeps/s390/s390-32/dl-machine.h +++ b/sysdeps/s390/s390-32/dl-machine.h @@ -166,18 +166,49 @@ _dl_start_user:\n\ # See if we were run as a command with the executable file\n\ # name as an extra leading argument.\n\ l %r1,_dl_skip_args@GOT12(0,%r12)\n\ - l %r1,0(%r1) # load _dl_skip_args\n\ + l %r1,0(%r1) # load _dl_skip_args\n\ + ltr %r1,%r1\n\ + je .L4 # Skip the arg adjustment if there were none.\n\ # Get the original argument count.\n\ l %r0,96(%r15)\n\ # Subtract _dl_skip_args from it.\n\ sr %r0,%r1\n\ - # Adjust the stack pointer to skip _dl_skip_args words.\n\ - sll %r1,2\n\ - ar %r15,%r1\n\ - # Set the back chain to zero again\n\ - xc 0(4,%r15),0(%r15)\n\ # Store back the modified argument count.\n\ st %r0,96(%r15)\n\ + # Copy argv and envp forward to account for skipped argv entries.\n\ + # We skipped at least one argument or we would not get here.\n\ + la %r6,100(%r15) # Destination pointer i.e. &argv[0]\n\ + lr %r5,%r6\n\ + lr %r0,%r1\n\ + sll %r0,2\n # Number of skipped bytes.\n\ + ar %r5,%r0 # Source pointer = Dest + Skipped args.\n\ + # argv copy loop:\n\ +.L1: l %r7,0(%r5) # Load a word from the source.\n\ + st %r7,0(%r6) # Store the word in the destination.\n\ + ahi %r5,4\n\ + ahi %r6,4\n\ + ltr %r7,%r7\n\ + jne .L1 # Stop after copying the NULL.\n\ + # envp copy loop:\n\ +.L2: l %r7,0(%r5) # Load a word from the source.\n\ + st %r7,0(%r6) # Store the word in the destination.\n\ + ahi %r5,4\n\ + ahi %r6,4\n\ + ltr %r7,%r7\n\ + jne .L2 # Stop after copying the NULL.\n\ + # Now we have to zero out the envp entries after NULL to allow\n\ + # start.S to properly find auxv by skipping zeroes.\n\ + # zero out loop:\n\ + lhi %r7,0\n\ +.L3: st %r7,0(%r6) # Store zero.\n\ + ahi %r6,4 # Advance dest pointer.\n\ + ahi %r1,-1 # Subtract one from the word count.\n\ + ltr %r1,%r1\n\ + jne .L3 # Keep copying if the word count is non-zero.\n\ + # Adjust _dl_argv\n\ + la %r6,100(%r15)\n\ + l %r1,_dl_argv@GOT12(0,%r12)\n\ + st %r6,0(%r1)\n\ # The special initializer gets called with the stack just\n\ # as the application's entry point will see it; it can\n\ # switch stacks if it moves these contents over.\n\ @@ -185,7 +216,7 @@ _dl_start_user:\n\ # Call the function to run the initializers.\n\ # Load the parameters:\n\ # (%r2, %r3, %r4, %r5) = (_dl_loaded, argc, argv, envp)\n\ - l %r2,_rtld_local@GOT(%r12)\n\ +.L4: l %r2,_rtld_local@GOT(%r12)\n\ l %r2,0(%r2)\n\ l %r3,96(%r15)\n\ la %r4,100(%r15)\n\ diff --git a/sysdeps/s390/s390-32/dl-sysdep.h b/sysdeps/s390/s390-32/dl-sysdep.h new file mode 100644 index 0000000..b992778 --- /dev/null +++ b/sysdeps/s390/s390-32/dl-sysdep.h @@ -0,0 +1,23 @@ +/* System-specific settings for dynamic linker code. S/390 version. + Copyright (C) 2014 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#include_next + +/* _dl_argv cannot be attribute_relro, because _dl_start_user + might write into it after _dl_start returns. */ +#define DL_ARGV_NOT_RELRO 1