From patchwork Thu Oct 30 19:52:35 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gert Doering X-Patchwork-Id: 4555 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7001:2f13:b0:72f:f16c:e055 with SMTP id sa19csp1163235mab; Thu, 30 Oct 2025 12:53:00 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCVX/HITqAXCP2D/XJxrzyxX442CXQNoCr6xUw1nICqTjzAIEUOQKcgyilUJRXc8/yJW2WJw6F92HNo=@openvpn.net X-Google-Smtp-Source: AGHT+IEKjjqbScq+Zw551IsePp85C2tiBS9l8sdbnnvNh4ZejhqlKIkVNTRTsUCutml0atZ19pp6 X-Received: by 2002:a05:6808:14c9:b0:44d:a0ec:d9a5 with SMTP id 5614622812f47-44f95e4c5famr502028b6e.1.1761853980350; Thu, 30 Oct 2025 12:53:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1761853980; cv=none; d=google.com; s=arc-20240605; b=Tg76FXUXIXzt2HI1pLJg61rT5hvR0Wb4C9S1qg4SxYtNzSwScbOr4UjCLDqU4k+74I aKmPvxdgM7cJ7IGB+q3UUutszda6hDpY6JMktzWwYwVCMhqgugRcV2M0Ez2/rWeCbHiy TGJwb+arqR0sL7b0Rd5g6yhCcfPLy57WfDGNN7Oer07Osz/uJ2/RtBmF8FK/BfyDNFLB 2T8jZfVAfgiYpb31ASyTrg1l6mm3ihcXD6J4ZSPwjCQLcl+V72/WLVHFrlGu52ycQWKO b49x6rs0QtUpwhiRC9e+OeYKgN3KhdFrlYFB6IcUUBsUlZnBVUYQK5mhAnf9SU3JnBEy SgkQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=errors-to:content-transfer-encoding:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence:subject :mime-version:references:in-reply-to:message-id:date:to:from :dkim-signature:dkim-signature:dkim-signature; bh=3k4CrL64PpZpVjV+g3UQjsAfKdJS+tl30MyVkhqbbA0=; fh=4NbAC/LsuMLI0S0hprUlLSLCiHwg6SCAifhH718Jh0Q=; b=lbEQPzfSQTTEsICqYgd3GIWpjO95r2dqs79nuBY7oiofrfpRPN3cfD3xi6qcypwvu+ pcHMI5cJrfhASrxXWe8qqR+alVy8Vki7gDEnyVpG3YasUQMsxKlqzFVe5xSMuCX+xh/M QXlOpC8di1pjlFNJR7kipkMbA03HVjpzTl7WK3ZGQcQL26/mnhQQyS1sbB8MVqcj/vZv ytdqOe93V8hlX+Ejb96Ved5bjBqngjHY0HJL/7s/pDCqGYVWiKnGkUG7BBEAWz89XtPt 8dBI85sgLwme7DqEgVfCBB9XkbAI7FDuilubQhXUVRthsIMS4yJrpYkh0GDifD5hdn88 rj/Q==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b="DhLuM8/N"; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=WbsOalwi; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=J9rbW1ys; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=muc.de Received: from lists.sourceforge.net (lists.sourceforge.net. [216.105.38.7]) by mx.google.com with ESMTPS id 5614622812f47-44da5520406si4381685b6e.324.2025.10.30.12.53.00 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 30 Oct 2025 12:53:00 -0700 (PDT) Received-SPF: pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) client-ip=216.105.38.7; Authentication-Results: mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b="DhLuM8/N"; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=WbsOalwi; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=J9rbW1ys; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=muc.de DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.sourceforge.net; s=beta; h=Content-Transfer-Encoding:Content-Type: List-Subscribe:List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id: Subject:MIME-Version:References:In-Reply-To:Message-ID:Date:To:From:Sender: Reply-To:Cc:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=3k4CrL64PpZpVjV+g3UQjsAfKdJS+tl30MyVkhqbbA0=; b=DhLuM8/N+9sCwY0x5yyxb6b4Dx l5Q/9Mt27y7PHKK6Z1/uTN9HiX+JMxAN9Rtrav7RqAWWCDpMq9kUMrnDi68/K86SC+Lt1x0zg3ZF2 DotcfuTZ7NPDEjDwlOSRi5ejykpfpQEtbEBU15j/cAKC1bRFR/Ep0G70zazV298+90TU=; Received: from [127.0.0.1] (helo=sfs-ml-2.v29.lw.sourceforge.com) by sfs-ml-2.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1vEYhd-0004LG-Ns; Thu, 30 Oct 2025 19:52:58 +0000 Received: from [172.30.29.66] (helo=mx.sourceforge.net) by sfs-ml-2.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1vEYhc-0004L3-MG for openvpn-devel@lists.sourceforge.net; Thu, 30 Oct 2025 19:52:57 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=g1y7+LqJiJqXJtsne7Q3kaZgFXLt/OkMLplP/0mZc78=; b=WbsOalwi5qaoAElIbG3z9vRs9d OEK1cHm/Gqr03HAdkIKQDmCDnEmzBC57UyAnxv5c4tkKqrt+LwOjbvcxy/9NtdrBkbn5yRjQJtiL1 ZZ2NeSABTTEdwwZrQ+3yxqoO2JmgN2Ci9b2z6HpnZwIBzrOvequG4YjRImYmYpBwaE2s=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID: Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=g1y7+LqJiJqXJtsne7Q3kaZgFXLt/OkMLplP/0mZc78=; b=J9rbW1ysscYpw4zhMHX6IB8cUl xx8PKRQmja6sVfp8CdjrM1ltvSCK0XGs71dZMaGfrAbCbnixjP/6yocLkrIeoa/YVUNQUemSuHZmc dODjbmIDK5G1cfO7SDUC14T+VqE2t82N1ja6TO77W/1Rm4NCNwsUJuvTxDUbG4JBKX5Q=; Received: from [193.149.48.134] (helo=blue.greenie.muc.de) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1vEYhc-0001ph-4h for openvpn-devel@lists.sourceforge.net; Thu, 30 Oct 2025 19:52:57 +0000 Received: from blue.greenie.muc.de (localhost [127.0.0.1]) by blue.greenie.muc.de (8.18.1/8.18.1) with ESMTP id 59UJqir5002688 for ; Thu, 30 Oct 2025 20:52:44 +0100 Received: (from gert@localhost) by blue.greenie.muc.de (8.18.1/8.18.1/Submit) id 59UJqike002687 for openvpn-devel@lists.sourceforge.net; Thu, 30 Oct 2025 20:52:44 +0100 From: Gert Doering To: openvpn-devel@lists.sourceforge.net Date: Thu, 30 Oct 2025 20:52:35 +0100 Message-ID: <20251030195244.2659-1-gert@greenie.muc.de> X-Mailer: git-send-email 2.49.1 In-Reply-To: References: MIME-Version: 1.0 X-Spam-Score: 1.3 (+) X-Spam-Report: Spam detection software, running on the system "sfi-spamd-1.hosts.colo.sdot.me", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: From: Marco Baffo The number of messages calculated before the call to message_splitter(), used in the memory allocation in the buffer array, could in certain cases be less than one than the actual number of messages, [...] Content analysis details: (1.3 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 1.3 RDNS_NONE Delivered to internal network by a host with no rDNS X-Headers-End: 1vEYhc-0001ph-4h Subject: [Openvpn-devel] [PATCH v6] PUSH_UPDATE server: invalid read bug-fix and unit-tests improvements X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox X-GMAIL-THRID: =?utf-8?q?1847437799203430702?= X-GMAIL-MSGID: =?utf-8?q?1847437799203430702?= From: Marco Baffo The number of messages calculated before the call to message_splitter(), used in the memory allocation in the buffer array, could in certain cases be less than one than the actual number of messages, thus causing an override of the sentinel buffer in message_splitter() and therefore an invalid read in send_single_push_update(). The case in question would be, for example, a sequence of three options "A,B,C" with the size of B equal to safe_cap - 1 and the sum of the sizes of A and C less than safe_cap - 2. The buffer array was therefore replaced with a list of buffers to completely avoid calculating the number of messages before it was actually computed. The test case in question has been added to the unit tests. The unit tests have been improved using cmocka macros. Change-Id: Idba419681fe3ccc4e6e2f6ce7592332dcff62cd9 Signed-off-by: Marco Baffo Acked-by: Gert Doering Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1316 --- This change was reviewed on Gerrit and approved by at least one developer. I request to merge it to master. Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1316 This mail reflects revision 6 of this Change. Acked-by according to Gerrit (reflected above): Gert Doering diff --git a/src/openvpn/push_util.c b/src/openvpn/push_util.c index 552679a..51c7b5f 100644 --- a/src/openvpn/push_util.c +++ b/src/openvpn/push_util.c @@ -91,7 +91,7 @@ * Return `false` on failure an `true` on success. */ static bool -message_splitter(const char *s, struct buffer *msgs, struct gc_arena *gc, const size_t safe_cap) +message_splitter(const char *s, struct buffer_list *msgs, struct gc_arena *gc, const size_t safe_cap) { if (!s || !*s) { @@ -100,7 +100,6 @@ char *str = gc_strdup(s, gc); size_t i = 0; - int im = 0; while (*str) { @@ -115,37 +114,38 @@ } str[ci] = '\0'; /* copy from i to (ci -1) */ - msgs[im] = forge_msg(str, ",push-continuation 2", gc); + struct buffer tmp = forge_msg(str, ",push-continuation 2", gc); + buffer_list_push(msgs, BSTR(&tmp)); i = ci + 1; } else { - if (im) + if (msgs->head) { - msgs[im] = forge_msg(str, ",push-continuation 1", gc); + struct buffer tmp = forge_msg(str, ",push-continuation 1", gc); + buffer_list_push(msgs, BSTR(&tmp)); } else { - msgs[im] = forge_msg(str, NULL, gc); + struct buffer tmp = forge_msg(str, NULL, gc); + buffer_list_push(msgs, BSTR(&tmp)); } i = strlen(str); } str = &str[i]; - im++; } return true; } /* send the message(s) prepared to one single client */ static bool -send_single_push_update(struct multi_context *m, struct multi_instance *mi, struct buffer *msgs) +send_single_push_update(struct multi_context *m, struct multi_instance *mi, struct buffer_list *msgs) { - if (!msgs[0].data || !*(msgs[0].data)) + if (!msgs->head) { return false; } - int i = -1; unsigned int option_types_found = 0; struct context *c = &mi->context; struct options o; @@ -160,9 +160,10 @@ o.ifconfig_local = canary; o.ifconfig_ipv6_local = canary; - while (msgs[++i].data && *(msgs[i].data)) + struct buffer_entry *e = msgs->head; + while (e) { - if (!send_control_channel_string(c, BSTR(&msgs[i]), D_PUSH)) + if (!send_control_channel_string(c, BSTR(&e->buf), D_PUSH)) { return false; } @@ -182,13 +183,14 @@ * Also we need to make a temporary copy so we can buf_advance() * without modifying original buffer. */ - struct buffer tmp_msg = msgs[i]; + struct buffer tmp_msg = e->buf; buf_string_compare_advance(&tmp_msg, push_update_cmd); unsigned int permission_mask = pull_permission_mask(c); if (process_push_update(c, &o, permission_mask, &option_types_found, &tmp_msg, true) == PUSH_MSG_ERROR) { msg(M_WARN, "Failed to process push update message sent to client ID: %u", c->c2.tls_multi->peer_id); } + e = e->next; } if (option_types_found & OPT_P_UP) @@ -270,12 +272,11 @@ * we want to send exceeds that size we have to split it into smaller messages */ ASSERT(push_bundle_size > extra); const size_t safe_cap = push_bundle_size - extra; - size_t msgs_num = (strlen(msg) / safe_cap) + ((strlen(msg) % safe_cap) != 0); - struct buffer *msgs = gc_malloc((msgs_num + 1) * sizeof(struct buffer), true, &gc); + struct buffer_list *msgs = buffer_list_new(); - msgs[msgs_num].data = NULL; if (!message_splitter(msg, msgs, &gc, safe_cap)) { + buffer_list_free(msgs); gc_free(&gc); return -EINVAL; } @@ -286,6 +287,7 @@ if (!mi) { + buffer_list_free(msgs); gc_free(&gc); return -ENOENT; } @@ -293,6 +295,7 @@ if (!support_push_update(mi)) { msg(M_CLIENT, "PUSH_UPDATE: not sending message to unsupported peer with ID: %u", mi->context.c2.tls_multi->peer_id); + buffer_list_free(msgs); gc_free(&gc); return 0; } @@ -300,11 +303,13 @@ if (!mi->halt && send_single_push_update(m, mi, msgs)) { + buffer_list_free(msgs); gc_free(&gc); return 1; } else { + buffer_list_free(msgs); gc_free(&gc); return 0; } @@ -334,6 +339,7 @@ } hash_iterator_free(&hi); + buffer_list_free(msgs); gc_free(&gc); return count; } diff --git a/tests/unit_tests/openvpn/test_push_update_msg.c b/tests/unit_tests/openvpn/test_push_update_msg.c index 516e94c..6ef1266 100644 --- a/tests/unit_tests/openvpn/test_push_update_msg.c +++ b/tests/unit_tests/openvpn/test_push_update_msg.c @@ -130,18 +130,11 @@ return true; } #else /* ifndef ENABLE_MANAGEMENT */ -char **res; -int i; bool send_control_channel_string(struct context *c, const char *str, msglvl_t msglevel) { - if (res && res[i] && strcmp(res[i], str)) - { - printf("\n\nexpected: %s\n\n actual: %s\n\n", res[i], str); - return false; - } - i++; + check_expected(str); return true; } @@ -301,44 +294,75 @@ #ifdef ENABLE_MANAGEMENT char *r0[] = { - "PUSH_UPDATE,redirect-gateway local,route 192.168.1.0 255.255.255.0" + "PUSH_UPDATE,redirect-gateway local,route 192.168.1.0 255.255.255.0", + NULL }; char *r1[] = { "PUSH_UPDATE,-dhcp-option,blablalalalalalalalalalalalalf, lalalalalalalalalalalalalalaf,push-continuation 2", "PUSH_UPDATE, akakakakakakakakakakakaf, dhcp-option DNS 8.8.8.8,redirect-gateway local,push-continuation 2", - "PUSH_UPDATE,route 192.168.1.0 255.255.255.0,push-continuation 1" + "PUSH_UPDATE,route 192.168.1.0 255.255.255.0,push-continuation 1", + NULL }; char *r3[] = { - "PUSH_UPDATE,,," + "PUSH_UPDATE,,,", + NULL }; char *r4[] = { "PUSH_UPDATE,-dhcp-option, blablalalalalalalalalalalalalf, lalalalalalalalalalalalalalaf,push-continuation 2", "PUSH_UPDATE, akakakakakakakakakakakaf,dhcp-option DNS 8.8.8.8, redirect-gateway local,push-continuation 2", - "PUSH_UPDATE, route 192.168.1.0 255.255.255.0,,push-continuation 1" + "PUSH_UPDATE, route 192.168.1.0 255.255.255.0,,push-continuation 1", + NULL }; char *r5[] = { "PUSH_UPDATE,,-dhcp-option, blablalalalalalalalalalalalalf, lalalalalalalalalalalalalalaf,push-continuation 2", "PUSH_UPDATE, akakakakakakakakakakakaf,dhcp-option DNS 8.8.8.8, redirect-gateway local,push-continuation 2", - "PUSH_UPDATE, route 192.168.1.0 255.255.255.0,push-continuation 1" + "PUSH_UPDATE, route 192.168.1.0 255.255.255.0,push-continuation 1", + NULL }; char *r6[] = { "PUSH_UPDATE,-dhcp-option,blablalalalalalalalalalalalalf, lalalalalalalalalalalalalalaf,push-continuation 2", "PUSH_UPDATE, akakakakakakakakakakakaf, dhcp-option DNS 8.8.8.8, redirect-gateway 10.10.10.10,,push-continuation 2", - "PUSH_UPDATE, route 192.168.1.0 255.255.255.0,,push-continuation 1" + "PUSH_UPDATE, route 192.168.1.0 255.255.255.0,,push-continuation 1", + NULL }; char *r7[] = { "PUSH_UPDATE,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,push-continuation 2", - "PUSH_UPDATE,,,,,,,,,,,,,,,,,,,push-continuation 1" + "PUSH_UPDATE,,,,,,,,,,,,,,,,,,,push-continuation 1", + NULL }; char *r8[] = { "PUSH_UPDATE,-dhcp-option,blablalalalalalalalalalalalalf, lalalalalalalalalalalalalalaf,push-continuation 2", "PUSH_UPDATE, akakakakakakakakakakakaf, dhcp-option DNS 8.8.8.8,redirect-gateway\n local,push-continuation 2", - "PUSH_UPDATE,route 192.168.1.0 255.255.255.0\n\n\n,push-continuation 1" + "PUSH_UPDATE,route 192.168.1.0 255.255.255.0\n\n\n,push-continuation 1", + NULL }; char *r9[] = { - "PUSH_UPDATE,," + "PUSH_UPDATE,,", + NULL }; - +char *r11[] = { + "PUSH_UPDATE,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,push-continuation 2", + "PUSH_UPDATE,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,push-continuation 2", + "PUSH_UPDATE,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,push-continuation 2", + "PUSH_UPDATE,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,push-continuation 2", + "PUSH_UPDATE,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,push-continuation 1", + NULL +}; +char *r12[] = { + "PUSH_UPDATE,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,,,,,,a,push-continuation 2", + "PUSH_UPDATE,abc,push-continuation 1", + NULL +}; +char *r13[] = { + "PUSH_UPDATE,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,,,,,,a,", + NULL +}; +char *r14[] = { + "PUSH_UPDATE,a,push-continuation 2", + "PUSH_UPDATE,aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,push-continuation 2", + "PUSH_UPDATE,a,push-continuation 1", + NULL +}; const char *msg0 = "redirect-gateway local,route 192.168.1.0 255.255.255.0"; const char *msg1 = "-dhcp-option,blablalalalalalalalalalalalalf, lalalalalalalalalalalalalalaf," @@ -365,32 +389,50 @@ "daisy damage damp dance danger daring dash daughter dawn day deal debate debris decade december decide decline" "decorate decrease deer defense define defy degree delay deliver demand demise denial"; +const char *msg11 = "a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a," + "a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a," + "a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a," + "a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a," + "a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a"; + +const char *msg12 = "a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,,,,,,a,abc"; + +const char *msg13 = "a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,,,,,,a,"; + +const char *msg14 = "a,aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,a"; + #define PUSH_BUNDLE_SIZE_TEST 184 +#define expect_control_channel_strings(res) \ + do \ + { \ + for (int j = 0; res[j] != NULL; j++) \ + { \ + expect_string(send_control_channel_string, str, res[j]); \ + } \ + } while (0) + static void test_send_push_msg0(void **state) { - i = 0; - res = r0; struct multi_context *m = *state; const unsigned long cid = 0; + expect_control_channel_strings(r0); assert_int_equal(send_push_update(m, &cid, msg0, UPT_BY_CID, PUSH_BUNDLE_SIZE_TEST), 1); } + static void test_send_push_msg1(void **state) { - i = 0; - res = r1; struct multi_context *m = *state; const unsigned long cid = 0; + expect_control_channel_strings(r1); assert_int_equal(send_push_update(m, &cid, msg1, UPT_BY_CID, PUSH_BUNDLE_SIZE_TEST), 1); } static void test_send_push_msg2(void **state) { - i = 0; - res = NULL; struct multi_context *m = *state; const unsigned long cid = 0; assert_int_equal(send_push_update(m, &cid, msg2, UPT_BY_CID, PUSH_BUNDLE_SIZE_TEST), -EINVAL); @@ -399,83 +441,110 @@ static void test_send_push_msg3(void **state) { - i = 0; - res = r3; struct multi_context *m = *state; const unsigned long cid = 0; + expect_control_channel_strings(r3); assert_int_equal(send_push_update(m, &cid, msg3, UPT_BY_CID, PUSH_BUNDLE_SIZE_TEST), 1); } static void test_send_push_msg4(void **state) { - i = 0; - res = r4; struct multi_context *m = *state; const unsigned long cid = 0; + expect_control_channel_strings(r4); assert_int_equal(send_push_update(m, &cid, msg4, UPT_BY_CID, PUSH_BUNDLE_SIZE_TEST), 1); } static void test_send_push_msg5(void **state) { - i = 0; - res = r5; struct multi_context *m = *state; const unsigned long cid = 0; + expect_control_channel_strings(r5); assert_int_equal(send_push_update(m, &cid, msg5, UPT_BY_CID, PUSH_BUNDLE_SIZE_TEST), 1); } static void test_send_push_msg6(void **state) { - i = 0; - res = r6; struct multi_context *m = *state; const unsigned long cid = 0; + expect_control_channel_strings(r6); assert_int_equal(send_push_update(m, &cid, msg6, UPT_BY_CID, PUSH_BUNDLE_SIZE_TEST), 1); } static void test_send_push_msg7(void **state) { - i = 0; - res = r7; struct multi_context *m = *state; const unsigned long cid = 0; + expect_control_channel_strings(r7); assert_int_equal(send_push_update(m, &cid, msg7, UPT_BY_CID, PUSH_BUNDLE_SIZE_TEST), 1); } static void test_send_push_msg8(void **state) { - i = 0; - res = r8; struct multi_context *m = *state; const unsigned long cid = 0; + expect_control_channel_strings(r8); assert_int_equal(send_push_update(m, &cid, msg8, UPT_BY_CID, PUSH_BUNDLE_SIZE_TEST), 1); } static void test_send_push_msg9(void **state) { - i = 0; - res = r9; struct multi_context *m = *state; const unsigned long cid = 0; + expect_control_channel_strings(r9); assert_int_equal(send_push_update(m, &cid, msg9, UPT_BY_CID, PUSH_BUNDLE_SIZE_TEST), 1); } static void test_send_push_msg10(void **state) { - i = 0; - res = NULL; struct multi_context *m = *state; const unsigned long cid = 0; assert_int_equal(send_push_update(m, &cid, msg10, UPT_BY_CID, PUSH_BUNDLE_SIZE_TEST), -EINVAL); } +static void +test_send_push_msg11(void **state) +{ + struct multi_context *m = *state; + const unsigned long cid = 0; + expect_control_channel_strings(r11); + assert_int_equal(send_push_update(m, &cid, msg11, UPT_BY_CID, PUSH_BUNDLE_SIZE_TEST), 1); +} + +static void +test_send_push_msg12(void **state) +{ + struct multi_context *m = *state; + const unsigned long cid = 0; + expect_control_channel_strings(r12); + assert_int_equal(send_push_update(m, &cid, msg12, UPT_BY_CID, PUSH_BUNDLE_SIZE_TEST), 1); +} + +static void +test_send_push_msg13(void **state) +{ + struct multi_context *m = *state; + const unsigned long cid = 0; + expect_control_channel_strings(r13); + assert_int_equal(send_push_update(m, &cid, msg13, UPT_BY_CID, PUSH_BUNDLE_SIZE_TEST), 1); +} + +static void +test_send_push_msg14(void **state) +{ + struct multi_context *m = *state; + const unsigned long cid = 0; + expect_control_channel_strings(r14); + assert_int_equal(send_push_update(m, &cid, msg14, UPT_BY_CID, PUSH_BUNDLE_SIZE_TEST), 1); +} + #undef PUSH_BUNDLE_SIZE_TEST static int @@ -535,6 +604,7 @@ cmocka_unit_test_setup_teardown(test_incoming_push_message_mix, setup, teardown), cmocka_unit_test_setup_teardown(test_incoming_push_message_mix2, setup, teardown), #ifdef ENABLE_MANAGEMENT + cmocka_unit_test_setup_teardown(test_send_push_msg0, setup2, teardown2), cmocka_unit_test_setup_teardown(test_send_push_msg1, setup2, teardown2), cmocka_unit_test_setup_teardown(test_send_push_msg2, setup2, teardown2), @@ -545,7 +615,11 @@ cmocka_unit_test_setup_teardown(test_send_push_msg7, setup2, teardown2), cmocka_unit_test_setup_teardown(test_send_push_msg8, setup2, teardown2), cmocka_unit_test_setup_teardown(test_send_push_msg9, setup2, teardown2), - cmocka_unit_test_setup_teardown(test_send_push_msg10, setup2, teardown2) + cmocka_unit_test_setup_teardown(test_send_push_msg10, setup2, teardown2), + cmocka_unit_test_setup_teardown(test_send_push_msg11, setup2, teardown2), + cmocka_unit_test_setup_teardown(test_send_push_msg12, setup2, teardown2), + cmocka_unit_test_setup_teardown(test_send_push_msg13, setup2, teardown2), + cmocka_unit_test_setup_teardown(test_send_push_msg14, setup2, teardown2) #endif };