From de114484a561f44f3c923ed5b22a41f81c3c3657 Mon Sep 17 00:00:00 2001 From: hoelscher <jens.hoelscher@fh-muenster.de> Date: Sat, 31 Oct 2015 03:32:10 +0100 Subject: [PATCH] add check funktion for cmsghdr struct --- gtests/net/packetdrill/run_system_call.c | 111 ++++++++++++++++++++++- 1 file changed, 109 insertions(+), 2 deletions(-) diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c index 97b00666..d99284a6 100644 --- a/gtests/net/packetdrill/run_system_call.c +++ b/gtests/net/packetdrill/run_system_call.c @@ -60,6 +60,10 @@ static int parse_expression_to_sctp_prinfo(struct expression *expr, struct sctp_ static int parse_expression_to_sctp_authinfo(struct expression *expr, struct sctp_authinfo *info, char **error); #endif +#if defined(SCTP_DEFAULT_SNDINFO) || defined(SCTP_SNDINFO) +static int check_sctp_sndinfo(struct sctp_sndinfo_expr *expr, struct sctp_sndinfo *sctp_sndinfo, + char **error); +#endif /* Provide a wrapper for the Linux gettid() system call (glibc does not). */ static pid_t gettid(void) @@ -1875,6 +1879,105 @@ static int syscall_sendto(struct state *state, struct syscall_spec *syscall, return status; } +static int check_cmsghdr(struct expression *expr_list, struct msghdr *msg, char **error) { + struct expression_list *list; + struct expression *cmsg_expr; + struct cmsghdr *cmsg_ptr; + int cnt=0; + + assert(expr_list->type == EXPR_LIST); + + list = expr_list->value.list; + for (cmsg_ptr = CMSG_FIRSTHDR(msg); cmsg_ptr != NULL; cmsg_ptr = CMSG_NXTHDR(msg, cmsg_ptr)) { + cmsg_expr = get_arg(list, cnt, error); + if (cmsg_expr->type != EXPR_ELLIPSIS) { + struct cmsghdr_expr *expr; + expr = cmsg_expr->value.cmsghdr; + if (check_u32_expr(expr->cmsg_len, cmsg_ptr->cmsg_len, + "cmsghdr.cmsg_len", error)) + return STATUS_ERR; + if (check_s32_expr(expr->cmsg_level, cmsg_ptr->cmsg_level, + "cmsghdr.cmsg_level", error)) + return STATUS_ERR; + if (check_s32_expr(expr->cmsg_type, cmsg_ptr->cmsg_type, + "cmsghdr.cmsg_type", error)) + return STATUS_ERR; + + if (expr->cmsg_data->type == EXPR_ELLIPSIS) { + continue; + } + switch(cmsg_ptr->cmsg_type) { +#ifdef SCTP_SNDINFO + case SCTP_SNDINFO: + if (check_sctp_sndinfo(expr->cmsg_data->value.sctp_sndinfo, + (struct sctp_sndinfo *) CMSG_DATA(cmsg_ptr), + error)) { + return STATUS_ERR; + } + break; +#endif +#ifdef SCTP_PRINFO + case SCTP_PRINFO: + if (check_u16_expr(expr->cmsg_data->value.sctp_prinfo->pr_policy, + ((struct sctp_prinfo *)CMSG_DATA(cmsg_ptr))->pr_policy, + "prinfo.pr_policy", error)) + return STATUS_ERR; + if (check_u32_expr(expr->cmsg_data->value.sctp_prinfo->pr_value, + ((struct sctp_prinfo *)CMSG_DATA(cmsg_ptr))->pr_value, + "prinfo.pr_value", error)) + return STATUS_ERR; + break; +#endif +#ifdef SCTP_AUTHINFO + case SCTP_AUTHINFO: + if (check_u16_expr(expr->cmsg_data->value.sctp_authinfo->auth_keynumber, + ((struct sctp_authinfo *)CMSG_DATA(cmsg_ptr))->auth_keynumber, + "authinfo.auth_keynumber", error)) + return STATUS_ERR; + break; +#endif +#ifdef SCTP_DSTADDRV4 + case SCTP_DSTADDRV4: + if (expr->cmsg_data->type != EXPR_ELLIPSIS) { + struct sockaddr_in *addr = expr->cmsg_data->value.socket_address_ipv4; + struct in_addr *cmsg_addr = (struct in_addr *) CMSG_DATA(cmsg_ptr); + if (addr->sin_addr.s_addr != cmsg_addr->s_addr) { + asprintf(error, "cmsg_data for SCTP_DSTADDRV4: expected: %s actual: %s", + inet_ntoa(addr->sin_addr), + inet_ntoa(*cmsg_addr)); + return STATUS_ERR; + } + } + break; +#endif +#ifdef SCTP_DSTADDRV6 + case SCTP_DSTADDRV6: + if (expr->cmsg_data->type != EXPR_ELLIPSIS) { + struct sockaddr_in6 *addr = expr->cmsg_data->value.socket_address_ipv6; + struct in6_addr *cmsg_addr = (struct in6_addr *) CMSG_DATA(cmsg_ptr); + if (memcmp(&addr->sin6_addr, cmsg_addr, sizeof(struct in6_addr))) { + char expected_addr[INET6_ADDRSTRLEN]; + char live_addr[INET6_ADDRSTRLEN]; + inet_ntop(AF_INET6, &addr->sin6_addr, expected_addr, INET6_ADDRSTRLEN); + inet_ntop(AF_INET6, cmsg_addr, live_addr, INET6_ADDRSTRLEN); + asprintf(error, "sockaddr_in6 from.sin6_addr. expected: %s actual %s", + expected_addr, live_addr); + return STATUS_ERR; + } + + } + break; +#endif + default: + asprintf(error, "can't check cmsg type"); + return STATUS_ERR; + } + } + cnt++; + } + return STATUS_OK; +} + static int syscall_sendmsg(struct state *state, struct syscall_spec *syscall, struct expression_list *args, char **error) { @@ -1913,7 +2016,10 @@ static int syscall_sendmsg(struct state *state, struct syscall_spec *syscall, result = sendmsg(live_fd, msg, flags); - status = end_syscall(state, syscall, CHECK_EXACT, result, error); + if (end_syscall(state, syscall, CHECK_EXACT, result, error)) + goto error_out; + + status = check_cmsghdr(msg_expression->value.msghdr->msg_control, msg, error); error_out: msghdr_free(msg, iov_len); @@ -2339,7 +2445,8 @@ static int check_sctp_event_subscribe(struct sctp_event_subscribe_expr *expr, return STATUS_OK; } #endif -#ifdef SCTP_DEFAULT_SNDINFO + +#if defined(SCTP_DEFAULT_SNDINFO) || defined(SCTP_SNDINFO) static int check_sctp_sndinfo(struct sctp_sndinfo_expr *expr, struct sctp_sndinfo *sctp_sndinfo, char **error) -- GitLab