From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 371 invoked by alias); 17 May 2012 20:54:05 -0000 Received: (qmail 341 invoked by uid 22791); 17 May 2012 20:54:03 -0000 X-SWARE-Spam-Status: No, hits=-2.2 required=5.0 tests=AWL,BAYES_00,NO_DNS_FOR_FROM,TW_EG,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from wb-fw1.tilera.com (HELO gx-1.internal.tilera.com) (12.216.194.146) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 17 May 2012 20:53:46 +0000 Received: from gx-1.internal.tilera.com (localhost [127.0.0.1]) by gx-1.internal.tilera.com (8.14.4/8.14.4) with ESMTP id q4HKrk2w035039 for ; Thu, 17 May 2012 16:53:46 -0400 Received: (from cmetcalf@localhost) by gx-1.internal.tilera.com (8.14.4/8.14.4/Submit) id q4HKrjdU035038; Thu, 17 May 2012 16:53:45 -0400 Message-Id: <201205172053.q4HKrjdU035038@gx-1.internal.tilera.com> From: Chris Metcalf Date: Thu, 17 May 2012 20:54:00 -0000 Subject: [PATCH] tilegx: provide a setxid.h to handle negative uids To: libc-ports@sourceware.org X-IsSubscribed: yes Mailing-List: contact libc-ports-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: libc-ports-owner@sourceware.org X-SW-Source: 2012-05/txt/msg00105.txt.bz2 We observed a bug where setreuid(-1, -1) was becoming setreuid(4294967295, 4294967295) instead, and therefore failing, instead of doing nothing and returning success. The problem is that normally, tilegx64 converts uint32_t to 64 bits by sign extending. This is counter-intuitive, but does allow for some simplifications of the comparison instructions in the generated code. So for a normal setreuid() call, the compiler would see the uint32_t (aka uid_t) type for the function, and sign-extend for the SYSCALL macro. However, with the pthread setxid mechanism, we store the arguments in an array of int64_t. When we put the values into the array, the compiler zero-extends them, and then they would be passed to the kernel unchanged since they were already 64-bit types. The result is the value 4294967295L, which is different from -1U. To make this work properly on tilegx, we have to add a cast to (int32_t) on the path so that whatever 32-bit values are put in the array of longs get properly sign-extended. --- This change is obviously accompanied by a change in the core nptl/sysdeps/pthread/setxid.h file; we put an #ifndef __SETXID_1 around the chunk of code that #defines __SETXID_1 through __SETXID_3. If the idea, and this change, seem acceptable, I'll send the patch for the core file as well. ChangeLog.tile | 2 + sysdeps/unix/sysv/linux/tile/nptl/setxid.h | 43 ++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 0 deletions(-) create mode 100644 sysdeps/unix/sysv/linux/tile/nptl/setxid.h diff --git a/ChangeLog.tile b/ChangeLog.tile index 0befa86..baebcce 100644 --- a/ChangeLog.tile +++ b/ChangeLog.tile @@ -1,5 +1,7 @@ 2012-05-17 Chris Metcalf + * sysdeps/unix/sysv/linux/tile/nptl/setxid.h: New file. + * sysdeps/tile/fegetenv.c: Version fegetenv() like fesetenv(). * sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/nptl/libm.abilist: Add fegetenv. diff --git a/sysdeps/unix/sysv/linux/tile/nptl/setxid.h b/sysdeps/unix/sysv/linux/tile/nptl/setxid.h new file mode 100644 index 0000000..8a4902b --- /dev/null +++ b/sysdeps/unix/sysv/linux/tile/nptl/setxid.h @@ -0,0 +1,43 @@ +/* Override nptl/sysdeps/pthread/setxid.h for tilegx64. + Copyright (C) 2012 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 + +/* On tilegx, we sign-extend 32-bit unsigned values to set the high 32 + bits in a 64-bit register. Thus, a -1U value and a -1UL value are + represented the same way in a register. This allows some compiler + optimizations where we don't have to explicitly clear the high bits + and can use native 64-bit instructions for 32-bit values. However, + this means that if we are trying to pass a -1U value into the "long + int" fields of the xid_command.id[] fields, we need to explicitly + sign-extend the values before placing them in the fields, since we + eventually make the syscall using INTERNAL_SYSCALL_NCS(), at which + point the register values need to be in the correct ABI format. */ + +#if __WORDSIZE == 64 +# define __SETXID_1(cmd, arg1) \ + cmd.id[0] = (sizeof (arg1) == 4) ? (int) arg1 : (long int) arg1 +# define __SETXID_2(cmd, arg1, arg2) \ + __SETXID_1 (cmd, arg1); \ + cmd.id[1] = (sizeof (arg2) == 4) ? (int) arg2 : (long int) arg2 +# define __SETXID_3(cmd, arg1, arg2, arg3) \ + __SETXID_2 (cmd, arg1, arg2); \ + cmd.id[2] = (sizeof (arg3) == 4) ? (int) arg3 : (long int) arg3 +#endif + +#include_next -- 1.7.1