1570af302Sopenharmony_ci/*
2570af302Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
3570af302Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4570af302Sopenharmony_ci * you may not use this file except in compliance with the License.
5570af302Sopenharmony_ci * You may obtain a copy of the License at
6570af302Sopenharmony_ci *
7570af302Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8570af302Sopenharmony_ci *
9570af302Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10570af302Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11570af302Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12570af302Sopenharmony_ci * See the License for the specific language governing permissions and
13570af302Sopenharmony_ci * limitations under the License.
14570af302Sopenharmony_ci */
15570af302Sopenharmony_ci#include <errno.h>
16570af302Sopenharmony_ci#include <netinet/in.h>
17570af302Sopenharmony_ci#include <signal.h>
18570af302Sopenharmony_ci#include <stdlib.h>
19570af302Sopenharmony_ci#include <string.h>
20570af302Sopenharmony_ci#include <sys/socket.h>
21570af302Sopenharmony_ci#include <sys/wait.h>
22570af302Sopenharmony_ci#include <sigchain.h>
23570af302Sopenharmony_ci#include "fortify_test.h"
24570af302Sopenharmony_ci#include "test.h"
25570af302Sopenharmony_ci
26570af302Sopenharmony_ci#define SCTP_IP_LOOPBACK  htonl(0x7f000001)
27570af302Sopenharmony_ci#define BUF_SIZE_10 (10)
28570af302Sopenharmony_ci#define BUF_SIZE_100 (100)
29570af302Sopenharmony_ci
30570af302Sopenharmony_ci/**
31570af302Sopenharmony_ci * @tc.name     : send_and_recv_0010
32570af302Sopenharmony_ci * @tc.desc     : test send and recv normal condition
33570af302Sopenharmony_ci * @tc.level    : Level 0
34570af302Sopenharmony_ci */
35570af302Sopenharmony_cistatic void send_and_recv_0010(void)
36570af302Sopenharmony_ci{
37570af302Sopenharmony_ci    char buf[BUF_SIZE_100];
38570af302Sopenharmony_ci    int sockets[2];
39570af302Sopenharmony_ci
40570af302Sopenharmony_ci    TEST(socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) == 0);
41570af302Sopenharmony_ci    TEST(send(sockets[1], "x", 1, 0) == 1);
42570af302Sopenharmony_ci    TEST(recv(sockets[0], buf, sizeof buf, 0) == 1);
43570af302Sopenharmony_ci    TEST(buf[0]=='x', "'%c'\n", buf[0]);
44570af302Sopenharmony_ci
45570af302Sopenharmony_ci    return;
46570af302Sopenharmony_ci}
47570af302Sopenharmony_ci
48570af302Sopenharmony_ci/**
49570af302Sopenharmony_ci * @tc.name     : send_0010
50570af302Sopenharmony_ci * @tc.desc     : test send suppress compiler optimizations
51570af302Sopenharmony_ci * @tc.level    : Level 2
52570af302Sopenharmony_ci */
53570af302Sopenharmony_cistatic void send_0010(void)
54570af302Sopenharmony_ci{
55570af302Sopenharmony_ci    struct sigaction sigabrt = {
56570af302Sopenharmony_ci        .sa_handler = SignalHandler,
57570af302Sopenharmony_ci    };
58570af302Sopenharmony_ci    sigaction(SIGABRT, &sigabrt, NULL);
59570af302Sopenharmony_ci
60570af302Sopenharmony_ci    size_t data_len = atoi("11");
61570af302Sopenharmony_ci    char buf[BUF_SIZE_10];
62570af302Sopenharmony_ci    int status;
63570af302Sopenharmony_ci    int pid = fork();
64570af302Sopenharmony_ci    switch (pid) {
65570af302Sopenharmony_ci        case -1:
66570af302Sopenharmony_ci            t_error("fork failed: %s\n", strerror(errno));
67570af302Sopenharmony_ci            break;
68570af302Sopenharmony_ci        case 0:
69570af302Sopenharmony_ci            send(0, buf, data_len, 0);
70570af302Sopenharmony_ci            exit(0);
71570af302Sopenharmony_ci        default:
72570af302Sopenharmony_ci            waitpid(pid, &status, WUNTRACED);
73570af302Sopenharmony_ci            TEST(WIFEXITED(status) == 0);
74570af302Sopenharmony_ci            TEST(WIFSTOPPED(status) == 1);
75570af302Sopenharmony_ci            TEST(WSTOPSIG(status) == SIGSTOP);
76570af302Sopenharmony_ci            kill(pid, SIGCONT);
77570af302Sopenharmony_ci            break;
78570af302Sopenharmony_ci    }
79570af302Sopenharmony_ci
80570af302Sopenharmony_ci    return;
81570af302Sopenharmony_ci}
82570af302Sopenharmony_ci
83570af302Sopenharmony_ci/**
84570af302Sopenharmony_ci * @tc.name     : recv_0010
85570af302Sopenharmony_ci * @tc.desc     : test recv suppress compiler optimizations
86570af302Sopenharmony_ci * @tc.level    : Level 2
87570af302Sopenharmony_ci */
88570af302Sopenharmony_cistatic void recv_0010(void)
89570af302Sopenharmony_ci{
90570af302Sopenharmony_ci    struct sigaction sigabrt = {
91570af302Sopenharmony_ci        .sa_handler = SignalHandler,
92570af302Sopenharmony_ci    };
93570af302Sopenharmony_ci    sigaction(SIGABRT, &sigabrt, NULL);
94570af302Sopenharmony_ci
95570af302Sopenharmony_ci    size_t data_len = atoi("11");
96570af302Sopenharmony_ci    char buf[BUF_SIZE_10];
97570af302Sopenharmony_ci    int status;
98570af302Sopenharmony_ci    int pid = fork();
99570af302Sopenharmony_ci    switch (pid) {
100570af302Sopenharmony_ci        case -1:
101570af302Sopenharmony_ci            t_error("fork failed: %s\n", strerror(errno));
102570af302Sopenharmony_ci            break;
103570af302Sopenharmony_ci        case 0:
104570af302Sopenharmony_ci            recv(0, buf, data_len, 0);
105570af302Sopenharmony_ci            exit(0);
106570af302Sopenharmony_ci        default:
107570af302Sopenharmony_ci            waitpid(pid, &status, WUNTRACED);
108570af302Sopenharmony_ci            TEST(WIFEXITED(status) == 0);
109570af302Sopenharmony_ci            TEST(WIFSTOPPED(status) == 1);
110570af302Sopenharmony_ci            TEST(WSTOPSIG(status) == SIGSTOP);
111570af302Sopenharmony_ci            kill(pid, SIGCONT);
112570af302Sopenharmony_ci            break;
113570af302Sopenharmony_ci    }
114570af302Sopenharmony_ci
115570af302Sopenharmony_ci    return;
116570af302Sopenharmony_ci}
117570af302Sopenharmony_ci
118570af302Sopenharmony_ci/**
119570af302Sopenharmony_ci * @tc.name     : sendto_and_recvfrom_0010
120570af302Sopenharmony_ci * @tc.desc     : test sendto and recvfrom normal condition
121570af302Sopenharmony_ci * @tc.level    : Level 0
122570af302Sopenharmony_ci */
123570af302Sopenharmony_cistatic void sendto_and_recvfrom_0010(void)
124570af302Sopenharmony_ci{
125570af302Sopenharmony_ci    struct sockaddr_in sa = { .sin_family = AF_INET };
126570af302Sopenharmony_ci    int sendFd, recvFd, t;
127570af302Sopenharmony_ci    char buf[BUF_SIZE_100];
128570af302Sopenharmony_ci
129570af302Sopenharmony_ci    TEST((recvFd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) >= 0);
130570af302Sopenharmony_ci    TEST(bind(recvFd, (void *)&sa, sizeof sa)==0);
131570af302Sopenharmony_ci    TEST(getsockname(recvFd, (void *)&sa, (socklen_t[]){sizeof sa}) == 0);
132570af302Sopenharmony_ci
133570af302Sopenharmony_ci    TEST(setsockopt(recvFd, SOL_SOCKET, SO_RCVTIMEO,
134570af302Sopenharmony_ci        &(struct timeval){.tv_usec=1}, sizeof(struct timeval)) == 0);
135570af302Sopenharmony_ci
136570af302Sopenharmony_ci    TEST((sendFd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) >= 0);
137570af302Sopenharmony_ci    sa.sin_addr.s_addr = SCTP_IP_LOOPBACK;
138570af302Sopenharmony_ci    TEST(sendto(sendFd, "x", 1, 0, (void *)&sa, sizeof sa) == 1);
139570af302Sopenharmony_ci    TEST(recvfrom(recvFd, buf, sizeof buf, 0, (void *)&sa, (socklen_t[]){sizeof sa}) == 1);
140570af302Sopenharmony_ci    TEST(buf[0]=='x', "'%c'\n", buf[0]);
141570af302Sopenharmony_ci
142570af302Sopenharmony_ci    return;
143570af302Sopenharmony_ci}
144570af302Sopenharmony_ci
145570af302Sopenharmony_ci/**
146570af302Sopenharmony_ci * @tc.name     : sendto_0010
147570af302Sopenharmony_ci * @tc.desc     : test sendto suppress compiler optimizations
148570af302Sopenharmony_ci * @tc.level    : Level 2
149570af302Sopenharmony_ci */
150570af302Sopenharmony_cistatic void sendto_0010(void)
151570af302Sopenharmony_ci{
152570af302Sopenharmony_ci    struct sigaction sigabrt = {
153570af302Sopenharmony_ci        .sa_handler = SignalHandler,
154570af302Sopenharmony_ci    };
155570af302Sopenharmony_ci    sigaction(SIGABRT, &sigabrt, NULL);
156570af302Sopenharmony_ci
157570af302Sopenharmony_ci    size_t data_len = atoi("11");
158570af302Sopenharmony_ci    char buf[BUF_SIZE_10];
159570af302Sopenharmony_ci    int status;
160570af302Sopenharmony_ci    int pid = fork();
161570af302Sopenharmony_ci    switch (pid) {
162570af302Sopenharmony_ci        case -1:
163570af302Sopenharmony_ci            t_error("fork failed: %s\n", strerror(errno));
164570af302Sopenharmony_ci            break;
165570af302Sopenharmony_ci        case 0:
166570af302Sopenharmony_ci            sendto(0, buf, data_len, 0, NULL, 0);
167570af302Sopenharmony_ci            exit(0);
168570af302Sopenharmony_ci        default:
169570af302Sopenharmony_ci            waitpid(pid, &status, WUNTRACED);
170570af302Sopenharmony_ci            TEST(WIFEXITED(status) == 0);
171570af302Sopenharmony_ci            TEST(WIFSTOPPED(status) == 1);
172570af302Sopenharmony_ci            TEST(WSTOPSIG(status) == SIGSTOP);
173570af302Sopenharmony_ci            kill(pid, SIGCONT);
174570af302Sopenharmony_ci            break;
175570af302Sopenharmony_ci    }
176570af302Sopenharmony_ci
177570af302Sopenharmony_ci    return;
178570af302Sopenharmony_ci}
179570af302Sopenharmony_ci
180570af302Sopenharmony_ci/**
181570af302Sopenharmony_ci * @tc.name     : recvfrom_0010
182570af302Sopenharmony_ci * @tc.desc     : test recv suppress compiler optimizations
183570af302Sopenharmony_ci * @tc.level    : Level 2
184570af302Sopenharmony_ci */
185570af302Sopenharmony_cistatic void recvfrom_0010(void)
186570af302Sopenharmony_ci{
187570af302Sopenharmony_ci    struct sigaction sigabrt = {
188570af302Sopenharmony_ci        .sa_handler = SignalHandler,
189570af302Sopenharmony_ci    };
190570af302Sopenharmony_ci    sigaction(SIGABRT, &sigabrt, NULL);
191570af302Sopenharmony_ci
192570af302Sopenharmony_ci    size_t data_len = atoi("11");
193570af302Sopenharmony_ci    char buf[BUF_SIZE_10];
194570af302Sopenharmony_ci    int status;
195570af302Sopenharmony_ci    int pid = fork();
196570af302Sopenharmony_ci    switch (pid) {
197570af302Sopenharmony_ci        case -1:
198570af302Sopenharmony_ci            t_error("fork failed: %s\n", strerror(errno));
199570af302Sopenharmony_ci            break;
200570af302Sopenharmony_ci        case 0:
201570af302Sopenharmony_ci            recvfrom(0, buf, data_len, 0, NULL, 0);
202570af302Sopenharmony_ci            exit(0);
203570af302Sopenharmony_ci        default:
204570af302Sopenharmony_ci            waitpid(pid, &status, WUNTRACED);
205570af302Sopenharmony_ci            TEST(WIFEXITED(status) == 0);
206570af302Sopenharmony_ci            TEST(WIFSTOPPED(status) == 1);
207570af302Sopenharmony_ci            TEST(WSTOPSIG(status) == SIGSTOP);
208570af302Sopenharmony_ci            kill(pid, SIGCONT);
209570af302Sopenharmony_ci            break;
210570af302Sopenharmony_ci    }
211570af302Sopenharmony_ci
212570af302Sopenharmony_ci    return;
213570af302Sopenharmony_ci}
214570af302Sopenharmony_ci
215570af302Sopenharmony_ciint main(int argc, char *argv[]) {
216570af302Sopenharmony_ci    remove_all_special_handler(SIGABRT);
217570af302Sopenharmony_ci    send_and_recv_0010();
218570af302Sopenharmony_ci    send_0010();
219570af302Sopenharmony_ci    recv_0010();
220570af302Sopenharmony_ci    sendto_and_recvfrom_0010();
221570af302Sopenharmony_ci    sendto_0010();
222570af302Sopenharmony_ci    recvfrom_0010();
223570af302Sopenharmony_ci
224570af302Sopenharmony_ci    return t_status;
225570af302Sopenharmony_ci}