From: Dmitry V. Levin Date: Tue, 10 May 2016 18:52:06 +0000 (+0000) Subject: Fix corner cases of xattr family syscalls decoding X-Git-Tag: v4.12~192 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ec9c31705b0540465b849b696db7bfe5245d9f69;p=strace Fix corner cases of xattr family syscalls decoding * xattr.c (print_xattr_val): Do not take insize into account, print it as unsigned long. Do not decode xattr values of size larger than XATTR_SIZE_MAX. Use static buffer for fetching xattr values. (print_xattr_list): Do not decode string when size is zero. --- diff --git a/xattr.c b/xattr.c index c47ebd6d..30a8467c 100644 --- a/xattr.c +++ b/xattr.c @@ -1,7 +1,7 @@ /* * Copyright (c) 2002-2005 Roland McGrath * Copyright (c) 2004 Ulrich Drepper - * Copyright (c) 2005-2015 Dmitry V. Levin + * Copyright (c) 2005-2016 Dmitry V. Levin * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -35,54 +35,30 @@ #include "xlat/xattrflags.h" +#ifndef XATTR_SIZE_MAX +# define XATTR_SIZE_MAX 65536 +#endif + static void print_xattr_val(struct tcb *tcp, unsigned long addr, unsigned long insize, unsigned long size) { - char *buf = NULL; - unsigned int len; + static char buf[XATTR_SIZE_MAX]; tprints(", "); - if (insize == 0) - goto done; - - len = size; - if (size != (unsigned long) len) - goto done; - - if (!len) { - tprintf("\"\", %ld", insize); - return; - } - - if (!verbose(tcp) || (exiting(tcp) && syserror(tcp))) - goto done; - - buf = malloc(len); - if (!buf) - goto done; - - if (umoven(tcp, addr, len, buf) < 0) { - free(buf); - buf = NULL; - goto done; - } - - /* Don't print terminating NUL if there is one. */ - if (buf[len - 1] == '\0') - --len; - -done: - if (buf) { - print_quoted_string(buf, len, 0); - free(buf); - } else { + if (!addr || size > sizeof(buf)) printaddr(addr); + else if (!size || !umoven_or_printaddr(tcp, addr, size, buf)) { + /* Don't print terminating NUL if there is one. */ + if (size && buf[size - 1] == '\0') + --size; + + print_quoted_string(buf, size, 0); } - tprintf(", %ld", insize); + tprintf(", %lu", insize); } SYS_FUNC(setxattr) @@ -134,13 +110,10 @@ SYS_FUNC(fgetxattr) static void print_xattr_list(struct tcb *tcp, unsigned long addr, unsigned long size) { - if (syserror(tcp)) { + if (!size || syserror(tcp)) { printaddr(addr); } else { - unsigned long len = - (size < (unsigned long) tcp->u_rval) ? - size : (unsigned long) tcp->u_rval; - printstr(tcp, addr, len); + printstr(tcp, addr, tcp->u_rval); } tprintf(", %lu", size); }