Home | History | Annotate | Download | only in sendto
      1 /*
      2  * Copyright(c) 2016 Fujitsu Ltd.
      3  * Author: Xiao Yang <yangx.jy (at) cn.fujitsu.com>
      4  *
      5  * This program is free software; you can redistribute it and/or modify it
      6  * under the terms of version 2 of the GNU General Public License as
      7  * published by the Free Software Foundation.
      8  *
      9  * This program is distributed in the hope that it would be useful, but
     10  * WITHOUT ANY WARRANTY; without even the implied warranty of
     11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     12  *
     13  * You should have received a copy of the GNU General Public License
     14  * alone with this program.
     15  */
     16 
     17 /*
     18  * Test Name: sendto02
     19  *
     20  * Description:
     21  * When sctp protocol is selected in socket(2) and buffer is invalid,
     22  * sendto(2) should fail and set errno to EFAULT, but it sets errno
     23  * to ENOMEM.
     24  *
     25  * This is a regression test and has been fixed by kernel commit:
     26  * 6e51fe7572590d8d86e93b547fab6693d305fd0d (sctp: fix -ENOMEM result
     27  * with invalid user space pointer in sendto() syscall)
     28  */
     29 
     30 #include <errno.h>
     31 #include <string.h>
     32 #include <unistd.h>
     33 #include <sys/types.h>
     34 #include <sys/socket.h>
     35 #include <netinet/in.h>
     36 
     37 #include "tst_test.h"
     38 
     39 #ifndef IPPROTO_SCTP
     40 # define IPPROTO_SCTP	132
     41 #endif
     42 
     43 static int sockfd;
     44 static struct sockaddr_in sa;
     45 
     46 static void setup(void)
     47 {
     48 	sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP);
     49 	if (sockfd == -1) {
     50 		if (errno == EPROTONOSUPPORT)
     51 			tst_brk(TCONF, "sctp protocol was not supported");
     52 		else
     53 			tst_brk(TBROK | TERRNO, "socket() failed with sctp");
     54 	}
     55 
     56 	memset(&sa, 0, sizeof(sa));
     57 	sa.sin_family = AF_INET;
     58 	sa.sin_addr.s_addr = inet_addr("127.0.0.1");
     59 	sa.sin_port = htons(11111);
     60 }
     61 
     62 static void cleanup(void)
     63 {
     64 	if (sockfd > 0)
     65 		SAFE_CLOSE(sockfd);
     66 }
     67 
     68 static void verify_sendto(void)
     69 {
     70 	TEST(sendto(sockfd, NULL, 1, 0, (struct sockaddr *) &sa, sizeof(sa)));
     71 	if (TEST_RETURN != -1) {
     72 		tst_res(TFAIL, "sendto(fd, NULL, ...) succeeded unexpectedly");
     73 		return;
     74 	}
     75 
     76 	if (TEST_ERRNO == EFAULT) {
     77 		tst_res(TPASS | TTERRNO,
     78 			"sendto(fd, NULL, ...) failed expectedly");
     79 		return;
     80 	}
     81 
     82 	tst_res(TFAIL | TTERRNO,
     83 		"sendto(fd, NULL, ...) failed unexpectedly, expected EFAULT");
     84 }
     85 
     86 static struct tst_test test = {
     87 	.setup = setup,
     88 	.cleanup = cleanup,
     89 	.test_all = verify_sendto,
     90 };
     91