* 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.
#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 */
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 */