From: Dmitry V. Levin Date: Sat, 8 Jul 2017 19:27:26 +0000 (+0000) Subject: net: accept arbitrary option length for getsockopt's SO_PEERCRED X-Git-Tag: v4.19~312 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0c4052b9ca0b423d09d3cbd9dc29feeb3f00dd50;p=strace net: accept arbitrary option length for getsockopt's SO_PEERCRED * print_fields.h (PRINT_FIELD_UID): New macro. * net.c (print_ucred): Rewrite to match the kernel behaviour. * NEWS: Mention this. --- diff --git a/NEWS b/NEWS index 947d506c..50ca640a 100644 --- a/NEWS +++ b/NEWS @@ -3,7 +3,8 @@ Noteworthy changes in release ?.?? (????-??-??) * Improvements * Enhanced decoding of optlen argument of getsockopt syscall. - * Enhanced decoding of SO_LINGER option of getsockopt and setsockopt syscalls. + * Enhanced decoding of SO_LINGER and SO_PEERCRED options + of getsockopt and setsockopt syscalls. * Implemented decoding of linux socket filter programs specified for SO_ATTACH_FILTER and SO_ATTACH_REUSEPORT_CBPF socket options. diff --git a/net.c b/net.c index 257e0df3..01f53b68 100644 --- a/net.c +++ b/net.c @@ -533,19 +533,31 @@ print_get_linger(struct tcb *const tcp, const kernel_ulong_t addr, #ifdef SO_PEERCRED static void -print_ucred(struct tcb *const tcp, const kernel_ulong_t addr, const int len) +print_ucred(struct tcb *const tcp, const kernel_ulong_t addr, unsigned int len) { struct ucred uc; - if (len != sizeof(uc) || - umove(tcp, addr, &uc) < 0) { - printaddr(addr); + if (len < sizeof(uc)) { + if (len != sizeof(uc.pid) + && len != offsetofend(struct ucred, uid)) { + printstr_ex(tcp, addr, len, QUOTE_FORCE_HEX); + return; + } } else { - tprintf("{pid=%u, uid=%u, gid=%u}", - (unsigned) uc.pid, - (unsigned) uc.uid, - (unsigned) uc.gid); + len = sizeof(uc); + } + + if (umoven(tcp, addr, len, &uc) < 0) { + printaddr(addr); + return; } + + PRINT_FIELD_D("{", uc, pid); + if (len > sizeof(uc.pid)) + PRINT_FIELD_UID(", ", uc, uid); + if (len == sizeof(uc)) + PRINT_FIELD_UID(", ", uc, gid); + tprints("}"); } #endif /* SO_PEERCRED */ diff --git a/print_fields.h b/print_fields.h index 92b8a8a1..43a26bc7 100644 --- a/print_fields.h +++ b/print_fields.h @@ -65,4 +65,13 @@ printxval((xlat_), (where_).field_, (dflt_)); \ } while (0) +#define PRINT_FIELD_UID(prefix_, where_, field_) \ + do { \ + if (sign_extend_unsigned_to_ll((where_).field_) == -1LL) \ + STRACE_PRINTF("%s%s=-1", (prefix_), #field_); \ + else \ + STRACE_PRINTF("%s%s=%llu", (prefix_), #field_, \ + zero_extend_signed_to_ull((where_).field_)); \ + } while (0) + #endif /* !STRACE_PRINT_FIELDS_H */