From patchwork Sat Aug 10 01:00:08 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alistair Francis X-Patchwork-Id: 34035 Received: (qmail 73882 invoked by alias); 10 Aug 2019 01:03:31 -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 73793 invoked by uid 89); 10 Aug 2019 01:03:30 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.3 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_NUMSUBJECT autolearn=ham version=3.3.1 spammy= X-HELO: esa5.hgst.iphmx.com DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1565399009; x=1596935009; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ktbi7pB40rUNLXB80zo4mLQybrFsf/GCEmvk+VM6uZM=; b=prSm6lV8jLmjwkNJBZY+zrpJ443MxY1pg5Pxc1uXdzBCJ29izgoWq6J4 VKZcslnqsL4fObHG0Asb+Eu+/iic1VnJGyfTCgk0Z2q9C+V5RcaXEitAU fQ8tXEkzXjWmroFlxdpJHwfevmmAwC7MXc7tRPKMqOhgYXL/THDTkEVYW ngBBlsjUB5QRPBxLuMhQDObsP+OBCBVuKypGQn2sCVNlHKLnMi6GVGJ41 ROsGYXLQwZHeHMDC8N+km3FtxrmXnGsbneVzvPCXaWPY9xUDNYVOTWB6n ssTiJmLWUBzR+kqsEmjU6jSERot8NYZGgZ0IVeZNiNS9Vp3WCJLk3UXAU A==; IronPort-SDR: lzGgB3u8tFV25RX4LCIhR9LYCDYqX4yeRX4gSgVhkpeZQbSGt1w2N0M7gxmGnmJe/pm8LjFDia Db6wYy4Dzg12mH6+zKidc4th5HdU8Nzza2GwPoqFNpOPsCsfcsNsylPtLXbJZRKKen9elsOwIU l0A6LUB1i1JCmoJID+JIQZUJfVmne/MJsRe8LIz653wo3cvbgE7ABULkIc+QMLNh/OTL2yaq0D W6OKC4sbmcoBQPEWHQIvWOkT44hM69uUGzxaruxPcbEl42b6eNHo3xPnGy0u985wDZNCfGfH0F 0uA= IronPort-SDR: z1BsQUbf0dmX1q4khIK8OqLQnxQ6WWpTYRnA1t0SQ4QS+owbzH8g8S9LylODmzQ0+rv8S/I1Wv FYPcBixPlXqHkk0LoDib1MKUsJsIa7+K6Q+dfSv364r2UWPXp/BYYP6nVJZcSgJrL5MsIwuI39 wFBlrjjlKGqH0LltMjTxLXtVsFaOhINQtllroMjQXZ4zyDvTaT1K1ovniibDPpFWnZvygscBgO zHxyjA8fVT25ZfN/lJXgTxVhzlw2l3RsWmz34uA6HWRbnr1MZVZLD08HL/ethPWxXjCMb92z2X yseAZ6DAfPTnrh//qi4cIaMt IronPort-SDR: bqS3vsHCjeqKz/T5KdXfBtfKYx3cfvTacfYPPoWq789BQh+Gc10Qj2JYC5aSCkuAeMCaPiPHd2 /dZNXv3w3tzV2c8dDyZitEgHTwfW/H6wYTj+r8fN74tEbbjJYX92FKKgWReMpJgQlFMB6YireV Km96ylEgIkjcrz66NjQ0moV4Cf99SK0kGl+MXxnAXEfI+j4IwAH7Ytrg3XZxAWVtwSQVV6VM2x GMYsVWsJZu7WSmZj6hIWeJmT1/Cx4x4mMaJmgqFD3VwnrbK8R3Q7gKKSiH6NYMZ06YzbWXzfsI +SA= From: Alistair Francis To: libc-alpha@sourceware.org Cc: arnd@arndb.de, adhemerval.zanella@linaro.org, fweimer@redhat.com, palmer@sifive.com, macro@wdc.com, zongbox@gmail.com, alistair.francis@wdc.com, alistair23@gmail.com Subject: [RFC v4 08/24] sysdeps/stat: Copy the statx struct to stat instead of stat64 Date: Fri, 9 Aug 2019 18:00:08 -0700 Message-Id: In-Reply-To: References: MIME-Version: 1.0 When copying the statx struct to the stat stuct use the original stat struct instead of the stat64 struct. As the padding in the original is type 'unsigned short int' but the padding in the stat64 is 'unsigned int' the copy can result in misallgined data. This would then incorrectly trigger the stat_overflow() failure. This would be very obvious when using a 64-bit ino_t type on a 32-bit system, such as the RV32 port. Signed-off-by: Alistair Francis --- .../sysv/linux/generic/wordsize-32/fxstat.c | 2 +- .../sysv/linux/generic/wordsize-32/fxstatat.c | 2 +- .../sysv/linux/generic/wordsize-32/lxstat.c | 2 +- .../sysv/linux/generic/wordsize-32/xstat.c | 2 +- sysdeps/unix/sysv/linux/statx_cp.c | 24 +++++++++++++++++++ sysdeps/unix/sysv/linux/statx_cp.h | 3 +++ 6 files changed, 31 insertions(+), 4 deletions(-) diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/fxstat.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/fxstat.c index 81e137c585b..234098b5199 100644 --- a/sysdeps/unix/sysv/linux/generic/wordsize-32/fxstat.c +++ b/sysdeps/unix/sysv/linux/generic/wordsize-32/fxstat.c @@ -43,7 +43,7 @@ __fxstat (int vers, int fd, struct stat *buf) int rc = INLINE_SYSCALL (statx, 5, fd, "", AT_EMPTY_PATH, STATX_BASIC_STATS, &tmp); if (rc == 0) - __cp_stat64_statx ((struct stat64 *)buf, &tmp); + __cp_stat_statx (buf, &tmp); # endif return rc ?: stat_overflow (buf); } diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/fxstatat.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/fxstatat.c index e203260485c..bd3bfc101cd 100644 --- a/sysdeps/unix/sysv/linux/generic/wordsize-32/fxstatat.c +++ b/sysdeps/unix/sysv/linux/generic/wordsize-32/fxstatat.c @@ -44,7 +44,7 @@ __fxstatat (int vers, int fd, const char *file, struct stat *buf, int flag) AT_NO_AUTOMOUNT | flag, STATX_BASIC_STATS, &tmp); if (rc == 0) - __cp_stat64_statx ((struct stat64 *)buf, &tmp); + __cp_stat_statx (buf, &tmp); # endif return rc ?: stat_overflow (buf); } diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat.c index 2d4dfbaf527..01edf9f22cc 100644 --- a/sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat.c +++ b/sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat.c @@ -44,7 +44,7 @@ __lxstat (int vers, const char *name, struct stat *buf) AT_NO_AUTOMOUNT | AT_SYMLINK_NOFOLLOW, STATX_BASIC_STATS, &tmp); if (rc == 0) - __cp_stat64_statx ((struct stat64 *)buf, &tmp); + __cp_stat_statx (buf, &tmp); #endif return rc ?: stat_overflow (buf); } diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat.c index 5f1f53c0f3f..dea6ec525e9 100644 --- a/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat.c +++ b/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat.c @@ -42,7 +42,7 @@ __xstat (int vers, const char *name, struct stat *buf) int rc = INLINE_SYSCALL (statx, 5, AT_FDCWD, name, AT_NO_AUTOMOUNT, STATX_BASIC_STATS, &tmp); if (rc == 0) - __cp_stat64_statx ((struct stat64 *)buf, &tmp); + __cp_stat_statx (buf, &tmp); # endif return rc ?: stat_overflow (buf); } diff --git a/sysdeps/unix/sysv/linux/statx_cp.c b/sysdeps/unix/sysv/linux/statx_cp.c index 3b4e5583e9a..2574d05563c 100644 --- a/sysdeps/unix/sysv/linux/statx_cp.c +++ b/sysdeps/unix/sysv/linux/statx_cp.c @@ -46,4 +46,28 @@ __cp_stat64_statx (struct stat64 *to, struct statx *from) to->st_blocks = from->stx_blocks; to->st_blksize = from->stx_blksize; } + +void +__cp_stat_statx (struct stat *to, struct statx *from) +{ + memset (to, 0, sizeof (struct stat64)); + to->st_dev = ((from->stx_dev_minor & 0xff) | (from->stx_dev_major << 8) + | ((from->stx_dev_minor & ~0xff) << 12)); + to->st_rdev = ((from->stx_rdev_minor & 0xff) | (from->stx_rdev_major << 8) + | ((from->stx_rdev_minor & ~0xff) << 12)); + to->st_ino = from->stx_ino; + to->st_mode = from->stx_mode; + to->st_nlink = from->stx_nlink; + to->st_uid = from->stx_uid; + to->st_gid = from->stx_gid; + to->st_atime = from->stx_atime.tv_sec; + to->st_atim.tv_nsec = from->stx_atime.tv_nsec; + to->st_mtime = from->stx_mtime.tv_sec; + to->st_mtim.tv_nsec = from->stx_mtime.tv_nsec; + to->st_ctime = from->stx_ctime.tv_sec; + to->st_ctim.tv_nsec = from->stx_ctime.tv_nsec; + to->st_size = from->stx_size; + to->st_blocks = from->stx_blocks; + to->st_blksize = from->stx_blksize; +} #endif diff --git a/sysdeps/unix/sysv/linux/statx_cp.h b/sysdeps/unix/sysv/linux/statx_cp.h index f08a7a8dcc8..2bb1d0605fd 100644 --- a/sysdeps/unix/sysv/linux/statx_cp.h +++ b/sysdeps/unix/sysv/linux/statx_cp.h @@ -18,3 +18,6 @@ extern void __cp_stat64_statx (struct stat64 *to, struct statx *from) attribute_hidden; + +extern void __cp_stat_statx (struct stat *to, struct statx *from) + attribute_hidden;