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.
This commit is contained in:
Дмитрий Левин 2017-07-08 19:27:26 +00:00
parent 004a776777
commit 0c4052b9ca
3 changed files with 31 additions and 9 deletions

3
NEWS
View File

@ -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.

28
net.c
View File

@ -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 */

View File

@ -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 */