1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright(c) 2016 Fujitsu Ltd.
4 * Author: Xiao Yang <yangx.jy@cn.fujitsu.com>
5 */
6
7/*
8 * Test Name: sendto02
9 *
10 * Description:
11 * When sctp protocol is selected in socket(2) and buffer is invalid,
12 * sendto(2) should fail and set errno to EFAULT, but it sets errno
13 * to ENOMEM.
14 *
15 * This is a regression test and has been fixed by kernel commit:
16 * 6e51fe7572590d8d86e93b547fab6693d305fd0d (sctp: fix -ENOMEM result
17 * with invalid user space pointer in sendto() syscall)
18 */
19
20#include <errno.h>
21#include <string.h>
22#include <unistd.h>
23#include <sys/types.h>
24#include <sys/socket.h>
25#include <netinet/in.h>
26
27#include "tst_test.h"
28
29#ifndef IPPROTO_SCTP
30# define IPPROTO_SCTP	132
31#endif
32
33static int sockfd;
34static struct sockaddr_in sa;
35
36static void setup(void)
37{
38	sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP);
39	if (sockfd == -1) {
40		if (errno == EPROTONOSUPPORT)
41			tst_brk(TCONF, "sctp protocol was not supported");
42		else
43			tst_brk(TBROK | TERRNO, "socket() failed with sctp");
44	}
45
46	memset(&sa, 0, sizeof(sa));
47	sa.sin_family = AF_INET;
48	sa.sin_addr.s_addr = inet_addr("127.0.0.1");
49	sa.sin_port = htons(11111);
50}
51
52static void cleanup(void)
53{
54	if (sockfd > 0)
55		SAFE_CLOSE(sockfd);
56}
57
58static void verify_sendto(void)
59{
60	TEST(sendto(sockfd, NULL, 1, 0, (struct sockaddr *) &sa, sizeof(sa)));
61	if (TST_RET != -1) {
62		tst_res(TFAIL, "sendto(fd, NULL, ...) succeeded unexpectedly");
63		return;
64	}
65
66	if (TST_ERR == EFAULT) {
67		tst_res(TPASS | TTERRNO,
68			"sendto(fd, NULL, ...) failed expectedly");
69		return;
70	}
71
72	tst_res(TFAIL | TTERRNO,
73		"sendto(fd, NULL, ...) failed unexpectedly, expected EFAULT");
74}
75
76static struct tst_test test = {
77	.setup = setup,
78	.cleanup = cleanup,
79	.test_all = verify_sendto,
80	.tags = (const struct tst_tag[]) {
81		{"linux-git", "6e51fe757259"},
82		{}
83	}
84};
85