/* Params are pointed to by u_arg[0], offset is in bytes */
int
sys_old_mmap(struct tcb *tcp)
{
	long u_arg[6];
#if defined(IA64)
	/*
	 * IA64 processes never call this routine, they only use the
	 * new 'sys_mmap' interface. Only IA32 processes come here.
	 */
	int i;
	unsigned narrow_arg[6];
	if (umoven(tcp, tcp->u_arg[0], sizeof(narrow_arg), (char *) narrow_arg) == -1)
		return 0;
	for (i = 0; i < 6; i++)
		u_arg[i] = (unsigned long) narrow_arg[i];
#elif defined(X86_64)
	/* We are here only in personality 1 (i386) */
	int i;
	unsigned narrow_arg[6];
	if (umoven(tcp, tcp->u_arg[0], sizeof(narrow_arg), (char *) narrow_arg) == -1)
		return 0;
	for (i = 0; i < 6; ++i)
		u_arg[i] = (unsigned long) narrow_arg[i];
#else
	if (umoven(tcp, tcp->u_arg[0], sizeof(u_arg), (char *) u_arg) == -1)
		return 0;
#endif
	return print_mmap(tcp, u_arg, (unsigned long) u_arg[5]);
}
Exemple #2
0
static void
printargv(struct tcb *tcp, long addr)
{
	union {
		unsigned int p32;
		unsigned long p64;
		char data[sizeof(long)];
	} cp;
	const char *sep;
	unsigned int n = 0;
	unsigned wordsize = current_wordsize;

	cp.p64 = 1;
	for (sep = ""; !abbrev(tcp) || n < max_strlen / 2; sep = ", ", ++n) {
		if (umoven(tcp, addr, wordsize, cp.data) < 0) {
			tprintf("%#lx", addr);
			return;
		}
		if (wordsize == 4)
			cp.p64 = cp.p32;
		if (cp.p64 == 0)
			break;
		tprints(sep);
		printstr(tcp, cp.p64, -1);
		addr += wordsize;
	}
	if (cp.p64)
		tprintf("%s...", sep);
}
Exemple #3
0
void
print_sigset_addr_len(struct tcb *tcp, long addr, long len)
{
	char mask[NSIG / 8];

	if (!addr) {
		tprints("NULL");
		return;
	}
	/* Here len is usually equals NSIG / 8 or current_wordsize.
	 * But we code this defensively:
	 */
	if (len < 0) {
 bad:
		tprintf("%#lx", addr);
		return;
	}
	if (len >= NSIG / 8)
		len = NSIG / 8;
	else
		len = (len + 3) & ~3;

	if (umoven(tcp, addr, len, mask) < 0)
		goto bad;
	tprints(sprintsigmask_n("", mask, len));
}
Exemple #4
0
static void
decode_socket_subcall(struct tcb *tcp)
{
	unsigned long addr;
	unsigned int n;

	if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= SYS_socket_nsubcalls)
		return;

	tcp->scno = SYS_socket_subcall + tcp->u_arg[0];
	tcp->qual_flg = qual_flags[tcp->scno];
	tcp->s_ent = &sysent[tcp->scno];
	addr = tcp->u_arg[1];
	n = tcp->s_ent->nargs;
	if (sizeof(tcp->u_arg[0]) == current_wordsize) {
		memset(tcp->u_arg, 0, n * sizeof(tcp->u_arg[0]));
		(void) umoven(tcp, addr, n * sizeof(tcp->u_arg[0]), tcp->u_arg);
	} else {
		unsigned int args[n];
		unsigned int i;

		memset(args, 0, sizeof(args));
		(void) umove(tcp, addr, &args);
		for (i = 0; i < n; ++i)
			tcp->u_arg[i] = args[i];
	}
}
static int
do_pipe(struct tcb *tcp, int flags_arg)
{
	if (exiting(tcp)) {
		if (syserror(tcp)) {
			tprintf("%#lx", tcp->u_arg[0]);
		} else {
#if !defined(SPARC) && !defined(SPARC64) && !defined(SH) && !defined(IA64)
			int fds[2];

			if (umoven(tcp, tcp->u_arg[0], sizeof fds, (char *) fds) < 0)
				tprints("[...]");
			else
				tprintf("[%u, %u]", fds[0], fds[1]);
#elif defined(SPARC) || defined(SPARC64) || defined(SH) || defined(IA64)
			tprintf("[%lu, %lu]", tcp->u_rval, getrval2(tcp));
#else
			tprintf("%#lx", tcp->u_arg[0]);
#endif
		}
		if (flags_arg >= 0) {
			tprints(", ");
			printflags(open_mode_flags, tcp->u_arg[flags_arg], "O_???");
		}
	}
	return 0;
}
int
sys_mincore(struct tcb *tcp)
{
	if (entering(tcp)) {
		tprintf("%#lx, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
	} else {
		unsigned long i, len;
		char *vec = NULL;

		len = tcp->u_arg[1];
		if (syserror(tcp) || tcp->u_arg[2] == 0 ||
			(vec = malloc(len)) == NULL ||
			umoven(tcp, tcp->u_arg[2], len, vec) < 0)
			tprintf("%#lx", tcp->u_arg[2]);
		else {
			tprints("[");
			for (i = 0; i < len; i++) {
				if (abbrev(tcp) && i >= max_strlen) {
					tprints("...");
					break;
				}
				tprints((vec[i] & 1) ? "1" : "0");
			}
			tprints("]");
		}
		free(vec);
	}
	return 0;
}
Exemple #7
0
int
sys_getgroups(struct tcb *tcp)
{
	unsigned long len;

	if (entering(tcp)) {
		len = tcp->u_arg[0];
		tprintf("%lu, ", len);
	} else {
		unsigned long size, start, cur, end, abbrev_end;
		uid_t gid;
		int failed = 0;

		start = tcp->u_arg[1];
		if (start == 0) {
			tprints("NULL");
			return 0;
		}
		len = tcp->u_rval;
		if (len == 0) {
			tprints("[]");
			return 0;
		}
		size = len * sizeof(gid);
		end = start + size;
		if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
		    size / sizeof(gid) != len || end < start) {
			tprintf("%#lx", start);
			return 0;
		}
		if (abbrev(tcp)) {
			abbrev_end = start + max_strlen * sizeof(gid);
			if (abbrev_end < start)
				abbrev_end = end;
		} else {
			abbrev_end = end;
		}
		tprints("[");
		for (cur = start; cur < end; cur += sizeof(gid)) {
			if (cur > start)
				tprints(", ");
			if (cur >= abbrev_end) {
				tprints("...");
				break;
			}
			if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
				tprints("?");
				failed = 1;
				break;
			}
			tprintf("%u", (unsigned int) gid);
		}
		tprints("]");
		if (failed)
			tprintf(" %#lx", tcp->u_arg[1]);
	}
	return 0;
}
Exemple #8
0
static int
copy_sigset_len(struct tcb *tcp, long addr, sigset_t *s, int len)
{
	if (len > sizeof(*s))
		len = sizeof(*s);
	sigemptyset(s);
	if (umoven(tcp, addr, len, (char *)s) < 0)
		return -1;
	return 0;
}
int
sys_oldselect(struct tcb *tcp)
{
	long args[5];

	if (umoven(tcp, tcp->u_arg[0], sizeof args, (char *) args) < 0) {
		tprints("[...]");
		return 0;
	}
	return decode_select(tcp, args, BITNESS_CURRENT);
}
static void
printargc(const char *fmt, struct tcb *tcp, long addr)
{
	int count;
	char *cp = NULL;

	for (count = 0; !umoven(tcp, addr, current_wordsize, &cp) && cp; count++) {
		addr += current_wordsize;
	}
	tprintf(fmt, count, count == 1 ? "" : "s");
}
static void
printcmsghdr(struct tcb *tcp, unsigned long addr, unsigned long len)
{
	struct cmsghdr *cmsg = len < sizeof(struct cmsghdr) ?
			       NULL : malloc(len);
	if (cmsg == NULL || umoven(tcp, addr, len, (char *) cmsg) < 0) {
		tprintf(", msg_control=%#lx", addr);
		free(cmsg);
		return;
	}

	tprintf(", {cmsg_len=%u, cmsg_level=", (unsigned) cmsg->cmsg_len);
	printxval(socketlayers, cmsg->cmsg_level, "SOL_???");
	tprints(", cmsg_type=");

	if (cmsg->cmsg_level == SOL_SOCKET) {
		unsigned long cmsg_len;

		printxval(scmvals, cmsg->cmsg_type, "SCM_???");
		cmsg_len = (len < cmsg->cmsg_len) ? len : cmsg->cmsg_len;

		if (cmsg->cmsg_type == SCM_RIGHTS
		    && CMSG_LEN(sizeof(int)) <= cmsg_len) {
			int *fds = (int *) CMSG_DATA(cmsg);
			int first = 1;

			tprints(", {");
			while ((char *) fds < ((char *) cmsg + cmsg_len)) {
				if (!first)
					tprints(", ");
				printfd(tcp, *fds++);
				first = 0;
			}
			tprints("}}");
			free(cmsg);
			return;
		}
		if (cmsg->cmsg_type == SCM_CREDENTIALS
		    && CMSG_LEN(sizeof(struct ucred)) <= cmsg_len) {
			struct ucred *uc = (struct ucred *) CMSG_DATA(cmsg);

			tprintf("{pid=%ld, uid=%ld, gid=%ld}}",
				(long)uc->pid, (long)uc->uid, (long)uc->gid);
			free(cmsg);
			return;
		}
	}
	free(cmsg);
	tprints(", ...}");
}
/* Params are pointed to by u_arg[0], offset is in pages */
int
sys_old_mmap_pgoff(struct tcb *tcp)
{
	long u_arg[5];
	int i;
	unsigned narrow_arg[6];
	unsigned long long offset;
	if (umoven(tcp, tcp->u_arg[0], sizeof(narrow_arg), (char *) narrow_arg) == -1)
		return 0;
	for (i = 0; i < 5; i++)
		u_arg[i] = (unsigned long) narrow_arg[i];
	offset = narrow_arg[5];
	offset *= get_pagesize();
	return print_mmap(tcp, u_arg, offset);
}
Exemple #13
0
// int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
//     on connection or binding succeeds, zero is returned; on error, -1 is returned.
void CDEnet_begin_bindconnect(struct tcb* tcp, int isConnect) {
    vb(1);
    if (CDE_nw_mode) {
        char addrbuf[KEYLEN];
        if (umoven(tcp, tcp->u_arg[1], tcp->u_arg[2], addrbuf) < 0) return;
        if (isConnect) {
            int port = getPort((void*)addrbuf);
            vbp(3, "Port %d\n", port);
            if (port == 53 || port == 22) return;
        }

        db_setCapturedSock(currdb, tcp->u_arg[0]);
        denySyscall(tcp->pid);
    }
}
Exemple #14
0
/* Returns the total bytes dumped */
unsigned long
dump_iov(struct tcb *tcp, unsigned long len, unsigned long addr)
{
	unsigned long toret = 0;
#if SUPPORTED_PERSONALITIES > 1
	union {
		struct { u_int32_t base; u_int32_t len; } iov32;
		struct { u_int64_t base; u_int64_t len; } iov64;
	} iov;
#define sizeof_iov \
	(current_wordsize == 4 ? sizeof(iov.iov32) : sizeof(iov.iov64))
#define iov_iov_base \
	(current_wordsize == 4 ? (uint64_t) iov.iov32.base : iov.iov64.base)
#define iov_iov_len \
	(current_wordsize == 4 ? (uint64_t) iov.iov32.len : iov.iov64.len)
#else
	struct iovec iov;
#define sizeof_iov sizeof(iov)
#define iov_iov_base iov.iov_base
#define iov_iov_len iov.iov_len
#endif
	unsigned long size, cur, end;

	if (!len) {
		return 0;
	}

	size = len * sizeof_iov;
	end = addr + size;

	if (size / sizeof_iov != len || end < addr) {
		assert(0);
	}

	for (cur = addr; cur < end; cur += sizeof_iov) {
		if (umoven(tcp, cur, sizeof_iov, (char *) &iov) < 0) {
			assert(0);
		}
		unsigned long len = iov_iov_len;
		dump_bytes(tcp, (long) iov_iov_base, len);
		toret += len;
	}
#undef sizeof_iov
#undef iov_iov_base
#undef iov_iov_len
	return toret;
}
Exemple #15
0
int socket_data_handle(struct tcb* tcp, int action) {
    int sockfd = tcp->u_arg[0];
    if (CDE_provenance_mode) {
        long len = tcp->u_rval;
        char *buf = NULL;
        if (len >0) {
            buf = malloc(len);
            if (umoven(tcp, tcp->u_arg[1], len, buf) < 0) {
                free(buf);
                return -1;
            }
        }
        print_sock_action(tcp, sockfd, buf, tcp->u_arg[2], tcp->u_arg[3], len, action, NULL);
        if (buf != NULL) free(buf);
    }
    return 0;
}
Exemple #16
0
void CDEnet_end_send(struct tcb* tcp) {
    int sockfd = tcp->u_arg[0];
    if (CDE_provenance_mode && CDE_network_content_mode && isProvCapturedSock(sockfd)) {
        vb(2);
        if (socket_data_handle(tcp, SOCK_SEND) < 0) {
            // TODO
        }
    }
    if (CDE_nw_mode && db_isCapturedSock(currdb, sockfd)) {
        vb(2);
        if (CDE_verbose_mode >= 3) {
            char buff[KEYLEN];
            size_t buflength = tcp->u_arg[2];
            if (umoven(tcp, tcp->u_arg[1], buflength, buff) < 0) {
                return;
            }
            buff[tcp->u_arg[2]] = '\0';
            vbp(3, "action %d [%ld] checksum %u ",
                SOCK_SEND, tcp->u_arg[2], checksum(buff, buflength));
            if (CDE_verbose_mode >= 3) printbuf(buff, buflength);
        }
        long pid = tcp->pid;
        char *pidkey, *sockid;
        db_get_pid_sock(currdb, pid, sockfd, &pidkey, &sockid);
        if (pidkey == NULL || sockid == NULL) {
            vbp(0, "error");
            return;
        }
        ull_t sendid = db_getPkgCounterInc(currdb, pidkey, sockid, SOCK_SEND);
        char* prov_pid = getMappedPid(pidkey);	// convert this pid to corresponding prov_pid
        ull_t u_rval;
        db_getSendRecvResult(netdb, SOCK_SEND, prov_pid, sockid, sendid, &u_rval, NULL); // get recorded result
        struct user_regs_struct regs;
        EXITIF(ptrace(PTRACE_GETREGS, pid, NULL, &regs)<0);
        SET_RETURN_CODE(&regs, u_rval);
        if (u_rval < 0) {
            // set errno? TODO
        }
        EXITIF(ptrace(PTRACE_SETREGS, pid, NULL, &regs)<0);

        free(prov_pid);
        free(sockid);
        free(pidkey);
    }
}
/* Return -1 on error or 1 on success (never 0!). */
static int
get_syscall_args(struct tcb *tcp)
{
	if (!ia64_ia32mode) {
		unsigned long *rbs_end =
			(unsigned long *) ia64_regs.ar[PT_AUR_BSP];
		unsigned long sof = (ia64_regs.cfm >> 0) & 0x7f;
		unsigned long sol = (ia64_regs.cfm >> 7) & 0x7f;
		unsigned long *out0 = ia64_rse_skip_regs(rbs_end, -sof + sol);
		unsigned int i;

		for (i = 0; i < tcp->s_ent->nargs; ++i) {
			if (umoven(tcp,
				   (unsigned long) ia64_rse_skip_regs(out0, i),
				   sizeof(long), &tcp->u_arg[i]) < 0)
				return -1;
		}
	} else {
Exemple #18
0
static void
print_cap_header(struct tcb *tcp, unsigned long addr)
{
	union { cap_user_header_t p; long *a; char *c; } arg;
	long a[sizeof(*arg.p) / sizeof(long) + 1];
	arg.a = a;

	if (!addr)
		tprints("NULL");
	else if (!verbose(tcp) ||
		 umoven(tcp, addr, sizeof(*arg.p), arg.c) < 0)
		tprintf("%#lx", addr);
	else {
		tprints("{");
		printxval(cap_version, arg.p->version,
			  "_LINUX_CAPABILITY_VERSION_???");
		tprintf(", %d}", arg.p->pid);
	}
}
static void
get_nodes(struct tcb *tcp, unsigned long ptr, unsigned long maxnodes, int err)
{
	unsigned long nlongs, size, end;

	nlongs = (maxnodes + 8 * sizeof(long) - 1) / (8 * sizeof(long));
	size = nlongs * sizeof(long);
	end = ptr + size;
	if (nlongs == 0 || ((err || verbose(tcp)) && (size * 8 == maxnodes)
			    && (end > ptr))) {
		unsigned long n, cur, abbrev_end;
		int failed = 0;

		if (abbrev(tcp)) {
			abbrev_end = ptr + max_strlen * sizeof(long);
			if (abbrev_end < ptr)
				abbrev_end = end;
		} else {
			abbrev_end = end;
		}
		tprints(", {");
		for (cur = ptr; cur < end; cur += sizeof(long)) {
			if (cur > ptr)
				tprints(", ");
			if (cur >= abbrev_end) {
				tprints("...");
				break;
			}
			if (umoven(tcp, cur, sizeof(n), (char *) &n) < 0) {
				tprints("?");
				failed = 1;
				break;
			}
			tprintf("%#0*lx", (int) sizeof(long) * 2 + 2, n);
		}
		tprints("}");
		if (failed)
			tprintf(" %#lx", ptr);
	} else
		tprintf(", %#lx", ptr);
	tprintf(", %lu", maxnodes);
}
int
sys_socketpair(struct tcb *tcp)
{
	int fds[2];

	if (entering(tcp)) {
		printxval(domains, tcp->u_arg[0], "PF_???");
		tprints(", ");
		tprint_sock_type(tcp, tcp->u_arg[1]);
		tprintf(", %lu", tcp->u_arg[2]);
	} else {
		if (syserror(tcp)) {
			tprintf(", %#lx", tcp->u_arg[3]);
			return 0;
		}
		if (umoven(tcp, tcp->u_arg[3], sizeof fds, (char *) fds) < 0)
			tprints(", [...]");
		else
			tprintf(", [%u, %u]", fds[0], fds[1]);
	}
	return 0;
}
Exemple #21
0
static void
decode_mips_subcall(struct tcb *tcp)
{
	if (!scno_is_valid(tcp->u_arg[0]))
		return;
	tcp->scno = tcp->u_arg[0];
	tcp->qual_flg = qual_flags(tcp->scno);
	tcp->s_ent = &sysent[tcp->scno];
	memmove(&tcp->u_arg[0], &tcp->u_arg[1],
		sizeof(tcp->u_arg) - sizeof(tcp->u_arg[0]));
	/*
	 * Fetching the last arg of 7-arg syscalls (fadvise64_64
	 * and sync_file_range) requires additional code,
	 * see linux/mips/get_syscall_args.c
	 */
	if (tcp->s_ent->nargs == MAX_ARGS) {
		if (umoven(tcp,
			   mips_REG_SP + MAX_ARGS * sizeof(tcp->u_arg[0]),
			   sizeof(tcp->u_arg[0]),
			   &tcp->u_arg[MAX_ARGS - 1]) < 0)
		tcp->u_arg[MAX_ARGS - 1] = 0;
	}
}
Exemple #22
0
static void
print_cap_data(struct tcb *tcp, unsigned long addr)
{
	union { cap_user_data_t p; long *a; char *c; } arg;
	long a[sizeof(*arg.p) / sizeof(long) + 1];
	arg.a = a;

	if (!addr)
		tprints("NULL");
	else if (!verbose(tcp) ||
		 (exiting(tcp) && syserror(tcp)) ||
		 umoven(tcp, addr, sizeof(*arg.p), arg.c) < 0)
		tprintf("%#lx", addr);
	else {
		tprints("{");
		printflags(capabilities, arg.p->effective, "CAP_???");
		tprints(", ");
		printflags(capabilities, arg.p->permitted, "CAP_???");
		tprints(", ");
		printflags(capabilities, arg.p->inheritable, "CAP_???");
		tprints("}");
	}
}
Exemple #23
0
void CDEnet_end_bindconnect(struct tcb* tcp, int isConnect) {
    int sockfd = tcp->u_arg[0];
    long addr = tcp->u_arg[1];
    int addrlen = tcp->u_arg[2];
    union sockaddr_t addrbuf;

    vb(2);

    if (addr == 0) return;

    if (addrlen < 2 || addrlen > sizeof(addrbuf)) addrlen = sizeof(addrbuf);

    if (umoven(tcp, addr, addrlen, addrbuf.pad) < 0) return;
    addrbuf.pad[sizeof(addrbuf.pad) - 1] = '\0';

    //~ printf("sock %d, family %d inet %d\n", sockfd, addrbuf.sa.sa_family, AF_INET);
    //~ if (CDE_provenance_mode && addrbuf.sa.sa_family == AF_INET) {
    if (CDE_provenance_mode) {
        int port = getPort((void*)addrbuf.pad);
        char buf[KEYLEN];
        bzero(buf, sizeof(buf));
        vbp(3, "Port %d return %ld\n", port, tcp->u_rval);
        if (port == 53 || port == 22) return;
        if (isConnect) {
            if (addrbuf.sa.sa_family == AF_INET) {
                get_ip_info(tcp->pid, sockfd, buf);
            } else if (addrbuf.sa.sa_family == AF_LOCAL) {
                sprintf(buf, "..%s", addrbuf.sau.sun_path);
            }
        }
        print_connect_prov(tcp, sockfd, addrbuf.pad, tcp->u_arg[2], tcp->u_rval, buf);
    }
    if (CDE_nw_mode) { // return my own network socket connect result from netdb
        if (isConnect) if (!isCurrCapturedSock(sockfd)) return;
        setBindConnectReturnValue(tcp);
    }
}
Exemple #24
0
static void
decode_socket_subcall(struct tcb *tcp)
{
	const int call = tcp->u_arg[0];

	if (call < 1 || call >= SYS_socket_nsubcalls)
		return;

	const kernel_ulong_t scno = SYS_socket_subcall + call;
	const unsigned int nargs = sysent[scno].nargs;
	uint64_t buf[nargs];

	if (umoven(tcp, tcp->u_arg[1], nargs * current_wordsize, buf) < 0)
		return;

	tcp->scno = scno;
	tcp->qual_flg = qual_flags(scno);
	tcp->s_ent = &sysent[scno];

	unsigned int i;
	for (i = 0; i < nargs; ++i)
		tcp->u_arg[i] = (sizeof(uint32_t) == current_wordsize)
				? ((uint32_t *) (void *) buf)[i] : buf[i];
}
Exemple #25
0
void
print_sigset_addr_len(struct tcb *tcp, long addr, long len)
{
	sigset_t ss;

	if (!addr) {
		tprints("NULL");
		return;
	}
	/* Here len is usually equals NSIG / 8 or current_wordsize.
	 * But we code this defensively:
	 */
	if (len < 0) {
 bad:
		tprintf("%#lx", addr);
		return;
	}
	if (len > NSIG / 8)
		len = NSIG / 8;
	sigemptyset(&ss);
	if (umoven(tcp, addr, len, (char *)&ss) < 0)
		goto bad;
	printsigmask(&ss);
}
Exemple #26
0
static void
print_sg_io_buffer(struct tcb *tcp, unsigned long addr, const unsigned int len)
{
	unsigned char *buf = NULL;
	unsigned int allocated, i;

	tprints("[");
	if (len == 0)
		goto out;
	allocated = (len > max_strlen) ? max_strlen : len;
	if ((buf = malloc(allocated)) == NULL ||
	    umoven(tcp, addr, allocated, buf) < 0) {
		tprintf("%#lx", addr);
		goto out;
	}
	tprintf("%02x", buf[0]);
	for (i = 1; i < allocated; ++i)
		tprintf(", %02x", buf[i]);
	if (allocated != len)
		tprints(", ...");
out:
	free(buf);
	tprints("]");
}
void
printsock(struct tcb *tcp, long addr, int addrlen)
{
	union {
		char pad[128];
		struct sockaddr sa;
		struct sockaddr_in sin;
		struct sockaddr_un sau;
#ifdef HAVE_INET_NTOP
		struct sockaddr_in6 sa6;
#endif
#if defined(LINUX) && defined(AF_IPX)
		struct sockaddr_ipx sipx;
#endif
#ifdef AF_PACKET
		struct sockaddr_ll ll;
#endif
#ifdef AF_NETLINK
		struct sockaddr_nl nl;
#endif
	} addrbuf;
	char string_addr[100];

	if (addr == 0) {
		tprintf("NULL");
		return;
	}
	if (!verbose(tcp)) {
		tprintf("%#lx", addr);
		return;
	}

	if (addrlen < 2 || addrlen > sizeof(addrbuf))
		addrlen = sizeof(addrbuf);

	memset(&addrbuf, 0, sizeof(addrbuf));
	if (umoven(tcp, addr, addrlen, addrbuf.pad) < 0) {
		tprintf("{...}");
		return;
	}
	addrbuf.pad[sizeof(addrbuf.pad) - 1] = '\0';

	tprintf("{sa_family=");
	printxval(addrfams, addrbuf.sa.sa_family, "AF_???");
	tprintf(", ");

	switch (addrbuf.sa.sa_family) {
	case AF_UNIX:
		if (addrlen == 2) {
			tprintf("NULL");
		} else if (addrbuf.sau.sun_path[0]) {
			tprintf("path=");
			printpathn(tcp, addr + 2, strlen(addrbuf.sau.sun_path));
		} else {
			tprintf("path=@");
			printpathn(tcp, addr + 3, strlen(addrbuf.sau.sun_path + 1));
		}
		break;
	case AF_INET:
		tprintf("sin_port=htons(%u), sin_addr=inet_addr(\"%s\")",
			ntohs(addrbuf.sin.sin_port), inet_ntoa(addrbuf.sin.sin_addr));
		break;
#ifdef HAVE_INET_NTOP
	case AF_INET6:
		inet_ntop(AF_INET6, &addrbuf.sa6.sin6_addr, string_addr, sizeof(string_addr));
		tprintf("sin6_port=htons(%u), inet_pton(AF_INET6, \"%s\", &sin6_addr), sin6_flowinfo=%u",
				ntohs(addrbuf.sa6.sin6_port), string_addr,
				addrbuf.sa6.sin6_flowinfo);
#ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID
		{
#if defined(HAVE_IF_INDEXTONAME) && defined(IN6_IS_ADDR_LINKLOCAL) && defined(IN6_IS_ADDR_MC_LINKLOCAL)
		    int numericscope = 0;
		    if (IN6_IS_ADDR_LINKLOCAL (&addrbuf.sa6.sin6_addr)
			    || IN6_IS_ADDR_MC_LINKLOCAL (&addrbuf.sa6.sin6_addr)) {
			char scopebuf[IFNAMSIZ + 1];

			if (if_indextoname (addrbuf.sa6.sin6_scope_id, scopebuf) == NULL)
			    numericscope++;
			else
			    tprintf(", sin6_scope_id=if_nametoindex(\"%s\")", scopebuf);
		    } else
			numericscope++;

		    if (numericscope)
#endif
			tprintf(", sin6_scope_id=%u", addrbuf.sa6.sin6_scope_id);
		}
#endif
		    break;
#endif
#if defined(AF_IPX) && defined(linux)
	case AF_IPX:
		{
			int i;
			tprintf("sipx_port=htons(%u), ",
					ntohs(addrbuf.sipx.sipx_port));
			/* Yes, I know, this does not look too
			 * strace-ish, but otherwise the IPX
			 * addresses just look monstrous...
			 * Anyways, feel free if you don't like
			 * this way.. :)
			 */
			tprintf("%08lx:", (unsigned long)ntohl(addrbuf.sipx.sipx_network));
			for (i = 0; i<IPX_NODE_LEN; i++)
				tprintf("%02x", addrbuf.sipx.sipx_node[i]);
			tprintf("/[%02x]", addrbuf.sipx.sipx_type);
		}
		break;
#endif /* AF_IPX && linux */
#ifdef AF_PACKET
	case AF_PACKET:
		{
			int i;
			tprintf("proto=%#04x, if%d, pkttype=",
					ntohs(addrbuf.ll.sll_protocol),
					addrbuf.ll.sll_ifindex);
			printxval(af_packet_types, addrbuf.ll.sll_pkttype, "?");
			tprintf(", addr(%d)={%d, ",
					addrbuf.ll.sll_halen,
					addrbuf.ll.sll_hatype);
			for (i=0; i<addrbuf.ll.sll_halen; i++)
				tprintf("%02x", addrbuf.ll.sll_addr[i]);
		}
		break;

#endif /* AF_APACKET */
#ifdef AF_NETLINK
	case AF_NETLINK:
		tprintf("pid=%d, groups=%08x", addrbuf.nl.nl_pid, addrbuf.nl.nl_groups);
		break;
#endif /* AF_NETLINK */
	/* AF_AX25 AF_APPLETALK AF_NETROM AF_BRIDGE AF_AAL5
	AF_X25 AF_ROSE etc. still need to be done */

	default:
		tprintf("sa_data=");
		printstr(tcp, (long) &((struct sockaddr *) addr)->sa_data,
			sizeof addrbuf.sa.sa_data);
		break;
	}
	tprintf("}");
}
static void
printcmsghdr(struct tcb *tcp, unsigned long addr, size_t len)
{
	const size_t cmsg_size =
#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
		(current_wordsize < sizeof(long)) ? sizeof(struct cmsghdr32) :
#endif
			sizeof(struct cmsghdr);

	char *buf = len < cmsg_size ? NULL : malloc(len);
	if (!buf || umoven(tcp, addr, len, buf) < 0) {
		tprints(", msg_control=");
		printaddr(addr);
		free(buf);
		return;
	}

	union_cmsghdr u = { .ptr = buf };

	tprints(", [");
	while (len >= cmsg_size) {
		size_t cmsg_len =
#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
			(current_wordsize < sizeof(long)) ? u.cmsg32->cmsg_len :
#endif
				u.cmsg->cmsg_len;
		int cmsg_level =
#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
			(current_wordsize < sizeof(long)) ? u.cmsg32->cmsg_level :
#endif
				u.cmsg->cmsg_level;
		int cmsg_type =
#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
			(current_wordsize < sizeof(long)) ? u.cmsg32->cmsg_type :
#endif
				u.cmsg->cmsg_type;

		if (u.ptr != buf)
			tprints(", ");
		tprintf("{cmsg_len=%lu, cmsg_level=", (unsigned long) cmsg_len);
		printxval(socketlayers, cmsg_level, "SOL_???");
		tprints(", cmsg_type=");

		if (cmsg_len > len)
			cmsg_len = len;

		print_cmsg_type_data(tcp, cmsg_level, cmsg_type,
				     (const void *) (u.ptr + cmsg_size),
				     cmsg_len > cmsg_size ? cmsg_len - cmsg_size: 0);
		tprints("}");

		if (cmsg_len < cmsg_size) {
			len -= cmsg_size;
			break;
		}
		cmsg_len = (cmsg_len + current_wordsize - 1) &
			(size_t) ~(current_wordsize - 1);
		if (cmsg_len >= len) {
			len = 0;
			break;
		}
		u.ptr += cmsg_len;
		len -= cmsg_len;
	}
	if (len)
		tprints(", ...");
	tprints("]");
	free(buf);
}
Exemple #29
0
/*
 * data_size limits the cumulative size of printed data.
 * Example: recvmsg returing a short read.
 */
void
tprint_iov_upto(struct tcb *tcp, unsigned long len, unsigned long addr, int decode_iov, unsigned long data_size)
{
#if SUPPORTED_PERSONALITIES > 1
	union {
		struct { u_int32_t base; u_int32_t len; } iov32;
		struct { u_int64_t base; u_int64_t len; } iov64;
	} iov;
#define sizeof_iov \
	(current_wordsize == 4 ? sizeof(iov.iov32) : sizeof(iov.iov64))
#define iov_iov_base \
	(current_wordsize == 4 ? (uint64_t) iov.iov32.base : iov.iov64.base)
#define iov_iov_len \
	(current_wordsize == 4 ? (uint64_t) iov.iov32.len : iov.iov64.len)
#else
	struct iovec iov;
#define sizeof_iov sizeof(iov)
#define iov_iov_base iov.iov_base
#define iov_iov_len iov.iov_len
#endif
	unsigned long size, cur, end, abbrev_end;
	int failed = 0;

	if (!len) {
		tprints("[]");
		return;
	}
	size = len * sizeof_iov;
	end = addr + size;
	if (!verbose(tcp) || size / sizeof_iov != len || end < addr) {
		tprintf("%#lx", addr);
		return;
	}
	if (abbrev(tcp)) {
		abbrev_end = addr + max_strlen * sizeof_iov;
		if (abbrev_end < addr)
			abbrev_end = end;
	} else {
		abbrev_end = end;
	}
	tprints("[");
	for (cur = addr; cur < end; cur += sizeof_iov) {
		if (cur > addr)
			tprints(", ");
		if (cur >= abbrev_end) {
			tprints("...");
			break;
		}
		if (umoven(tcp, cur, sizeof_iov, (char *) &iov) < 0) {
			tprints("?");
			failed = 1;
			break;
		}
		tprints("{");
		if (decode_iov) {
			unsigned long len = iov_iov_len;
			if (len > data_size)
				len = data_size;
			data_size -= len;
			printstr(tcp, (long) iov_iov_base, len);
		} else
			tprintf("%#lx", (long) iov_iov_base);
		tprintf(", %lu}", (unsigned long)iov_iov_len);
	}
	tprints("]");
	if (failed)
		tprintf(" %#lx", addr);
#undef sizeof_iov
#undef iov_iov_base
#undef iov_iov_len
}
Exemple #30
0
/*
 * Return true if syscall accesses a selected path
 * (or if no paths have been specified for tracing).
 */
int
pathtrace_match(struct tcb *tcp)
{
	const struct_sysent *s;

	s = tcp->s_ent;

	if (!(s->sys_flags & (TRACE_FILE | TRACE_DESC | TRACE_NETWORK)))
		return 0;

	/*
	 * Check for special cases where we need to do something
	 * other than test arg[0].
	 */

	if (s->sys_func == sys_dup2 ||
	    s->sys_func == sys_dup3 ||
	    s->sys_func == sys_sendfile ||
	    s->sys_func == sys_sendfile64 ||
	    s->sys_func == sys_tee)
	{
		/* fd, fd */
		return fdmatch(tcp, tcp->u_arg[0]) ||
			fdmatch(tcp, tcp->u_arg[1]);
	}

	if (s->sys_func == sys_inotify_add_watch ||
	    s->sys_func == sys_faccessat ||
	    s->sys_func == sys_fchmodat ||
	    s->sys_func == sys_futimesat ||
	    s->sys_func == sys_unlinkat ||
	    s->sys_func == sys_newfstatat ||
	    s->sys_func == sys_mknodat ||
	    s->sys_func == sys_openat ||
	    s->sys_func == sys_readlinkat ||
	    s->sys_func == sys_utimensat ||
	    s->sys_func == sys_fchownat ||
	    s->sys_func == sys_pipe2)
	{
		/* fd, path */
		return fdmatch(tcp, tcp->u_arg[0]) ||
			upathmatch(tcp, tcp->u_arg[1]);
	}

	if (s->sys_func == sys_link ||
	    s->sys_func == sys_mount)
	{
		/* path, path */
		return upathmatch(tcp, tcp->u_arg[0]) ||
			upathmatch(tcp, tcp->u_arg[1]);
	}

	if (s->sys_func == sys_quotactl)
	{
		/* x, path */
		return upathmatch(tcp, tcp->u_arg[1]);
	}

	if (s->sys_func == sys_renameat ||
	    s->sys_func == sys_renameat2 ||
	    s->sys_func == sys_linkat)
	{
		/* fd, path, fd, path */
		return fdmatch(tcp, tcp->u_arg[0]) ||
			fdmatch(tcp, tcp->u_arg[2]) ||
			upathmatch(tcp, tcp->u_arg[1]) ||
			upathmatch(tcp, tcp->u_arg[3]);
	}

	if (
	    s->sys_func == sys_old_mmap ||
#if defined(S390)
	    s->sys_func == sys_old_mmap_pgoff ||
#endif
	    s->sys_func == sys_mmap ||
	    s->sys_func == sys_mmap_pgoff ||
	    s->sys_func == sys_mmap_4koff
	) {
		/* x, x, x, x, fd */
		return fdmatch(tcp, tcp->u_arg[4]);
	}

	if (s->sys_func == sys_symlinkat) {
		/* path, fd, path */
		return fdmatch(tcp, tcp->u_arg[1]) ||
			upathmatch(tcp, tcp->u_arg[0]) ||
			upathmatch(tcp, tcp->u_arg[2]);
	}

	if (s->sys_func == sys_splice) {
		/* fd, x, fd, x, x */
		return fdmatch(tcp, tcp->u_arg[0]) ||
			fdmatch(tcp, tcp->u_arg[2]);
	}

	if (s->sys_func == sys_epoll_ctl) {
		/* x, x, fd, x */
		return fdmatch(tcp, tcp->u_arg[2]);
	}

	if (s->sys_func == sys_fanotify_mark) {
		/* x, x, x, fd, path */
		return fdmatch(tcp, tcp->u_arg[3]) ||
			upathmatch(tcp, tcp->u_arg[4]);
	}

	if (s->sys_func == sys_select ||
	    s->sys_func == sys_oldselect ||
	    s->sys_func == sys_pselect6)
	{
		int     i, j;
		int     nfds;
		long   *args, oldargs[5];
		unsigned fdsize;
		fd_set *fds;

		args = tcp->u_arg;
		if (s->sys_func == sys_oldselect) {
			if (umoven(tcp, tcp->u_arg[0], sizeof oldargs,
				   oldargs) < 0)
			{
				fprintf(stderr, "umoven() failed\n");
				return 0;
			}
			args = oldargs;
		}

		/* Kernel truncates arg[0] to int, we do the same. */
		nfds = (int) args[0];
		/* Kernel rejects negative nfds, so we don't parse it either. */
		if (nfds <= 0)
			return 0;
		/* Beware of select(2^31-1, NULL, NULL, NULL) and similar... */
		if (nfds > 1024*1024)
			nfds = 1024*1024;
		fdsize = (((nfds + 7) / 8) + current_wordsize-1) & -current_wordsize;
		fds = malloc(fdsize);
		if (!fds)
			die_out_of_memory();

		for (i = 1; i <= 3; ++i) {
			if (args[i] == 0)
				continue;
			if (umoven(tcp, args[i], fdsize, fds) < 0) {
				fprintf(stderr, "umoven() failed\n");
				continue;
			}
			for (j = 0;; j++) {
				j = next_set_bit(fds, j, nfds);
				if (j < 0)
					break;
				if (fdmatch(tcp, j)) {
					free(fds);
					return 1;
				}
			}
		}
		free(fds);
		return 0;
	}

	if (s->sys_func == sys_poll ||
	    s->sys_func == sys_ppoll)
	{
		struct pollfd fds;
		unsigned nfds;
		unsigned long start, cur, end;

		start = tcp->u_arg[0];
		nfds = tcp->u_arg[1];

		end = start + sizeof(fds) * nfds;

		if (nfds == 0 || end < start)
			return 0;

		for (cur = start; cur < end; cur += sizeof(fds))
			if ((umoven(tcp, cur, sizeof fds, &fds) == 0)
			    && fdmatch(tcp, fds.fd))
				return 1;

		return 0;
	}

	if (s->sys_func == printargs ||
	    s->sys_func == sys_pipe ||
	    s->sys_func == sys_pipe2 ||
	    s->sys_func == sys_eventfd2 ||
	    s->sys_func == sys_eventfd ||
	    s->sys_func == sys_inotify_init1 ||
	    s->sys_func == sys_timerfd_create ||
	    s->sys_func == sys_timerfd_settime ||
	    s->sys_func == sys_timerfd_gettime ||
	    s->sys_func == sys_epoll_create ||
	    s->sys_func == sys_socket ||
	    s->sys_func == sys_socketpair ||
	    s->sys_func == sys_fanotify_init)
	{
		/*
		 * These have TRACE_FILE or TRACE_DESCRIPTOR or TRACE_NETWORK set,
		 * but they don't have any file descriptor or path args to test.
		 */
		return 0;
	}

	/*
	 * Our fallback position for calls that haven't already
	 * been handled is to just check arg[0].
	 */

	if (s->sys_flags & TRACE_FILE)
		return upathmatch(tcp, tcp->u_arg[0]);

	if (s->sys_flags & (TRACE_DESC | TRACE_NETWORK))
		return fdmatch(tcp, tcp->u_arg[0]);

	return 0;
}