]> granicus.if.org Git - strace/blobdiff - ucopy.c
nlattr: add UID/GID netlink attribute decoders
[strace] / ucopy.c
diff --git a/ucopy.c b/ucopy.c
index c3be41704d59fee2adf08065ef42777078a4054c..dafc1e4ed524061ddac568c6caa884e375bce3c5 100644 (file)
--- a/ucopy.c
+++ b/ucopy.c
@@ -6,7 +6,7 @@
  * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
  *                     Linux for s390 port by D.J. Barrow
  *                    <barrow_dj@mail.yahoo.com,djbarrow@de.ibm.com>
- * Copyright (c) 1999-2017 The strace developers.
+ * Copyright (c) 1999-2018 The strace developers.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -203,6 +203,7 @@ umovestr_peekdata(const int pid, kernel_ulong_t addr, unsigned int len,
 {
        unsigned int nread = 0;
        unsigned int residue = addr & (sizeof(long) - 1);
+       void *const orig_addr = laddr;
 
        while (len) {
                addr &= -sizeof(long);          /* aligned address */
@@ -237,7 +238,7 @@ umovestr_peekdata(const int pid, kernel_ulong_t addr, unsigned int len,
                memcpy(laddr, &u.x[residue], m);
                while (residue < sizeof(long))
                        if (u.x[residue++] == '\0')
-                               return 1;
+                               return (laddr - orig_addr) + residue;
                residue = 0;
                addr += sizeof(long);
                laddr += m;
@@ -252,8 +253,7 @@ umovestr_peekdata(const int pid, kernel_ulong_t addr, unsigned int len,
  * Like `umove' but make the additional effort of looking
  * for a terminating zero byte.
  *
- * Returns < 0 on error, > 0 if NUL was seen,
- * (TODO if useful: return count of bytes including NUL),
+ * Returns < 0 on error, strlen + 1  if NUL was seen,
  * else 0 if len bytes were read but no NUL byte seen.
  *
  * Note: there is no guarantee we won't overwrite some bytes
@@ -289,8 +289,10 @@ umovestr(struct tcb *const tcp, kernel_ulong_t addr, unsigned int len,
 
                int r = vm_read_mem(pid, laddr, addr, chunk_len);
                if (r > 0) {
-                       if (memchr(laddr, '\0', r))
-                               return 1;
+                       char *nul_addr = memchr(laddr, '\0', r);
+
+                       if (nul_addr)
+                               return (nul_addr - laddr) + 1;
                        addr += r;
                        laddr += r;
                        nread += r;
@@ -304,7 +306,7 @@ umovestr(struct tcb *const tcp, kernel_ulong_t addr, unsigned int len,
                                if (!nread)
                                        return umovestr_peekdata(pid, addr,
                                                                 len, laddr);
-                               /* fall through */
+                               ATTRIBUTE_FALLTHROUGH;
                        case EFAULT: case EIO:
                                /* address space is inaccessible */
                                if (nread)