• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (C) Bull S.A. 2001
4  * Copyright (c) International Business Machines  Corp., 2001
5  * 07/2001 Ported by Wayne Boyer
6  * 05/2002 Ported by Jacky Malcles
7  */
8 
9 /*\
10  * [Description]
11  *
12  * Tests readv() failures:
13  *
14  * - EINVAL the sum of the iov_len values overflows an ssize_t value
15  * - EFAULT buffer is outside the accessible address space
16  * - EINVAL the vector count iovcnt is less than zero
17  * - EISDIR the file descriptor is a directory
18  * - EBADF  the file descriptor is not valid
19  */
20 
21 #include <sys/uio.h>
22 #include "tst_test.h"
23 
24 #define K_1     1024
25 #define MODES   0700
26 
27 #define CHUNK           64
28 
29 static int badfd = -1;
30 static int fd_dir, fd_file;
31 static char buf1[K_1];
32 const char *TEST_DIR = "test_dir";
33 const char *TEST_FILE = "test_file";
34 
35 static struct iovec invalid_iovec[] = {
36 	{buf1, -1},
37 	{buf1 + CHUNK, CHUNK},
38 	{buf1 + 2*CHUNK, CHUNK},
39 };
40 
41 static struct iovec large_iovec[] = {
42 	{buf1, K_1},
43 	{buf1 + CHUNK, K_1},
44 	{buf1 + CHUNK*2, K_1},
45 };
46 
47 static struct iovec efault_iovec[] = {
48 	{NULL, CHUNK},
49 	{buf1 + CHUNK, CHUNK},
50 	{buf1 + 2*CHUNK, CHUNK},
51 };
52 
53 static struct iovec valid_iovec[] = {
54 	{buf1, CHUNK},
55 };
56 
57 static struct tcase {
58 	int *fd;
59 	void *buf;
60 	int count;
61 	int exp_error;
62 } tcases[] = {
63 	{&fd_file, invalid_iovec, 1, EINVAL},
64 	{&fd_file, efault_iovec, 3, EFAULT},
65 	{&fd_file, large_iovec, -1, EINVAL},
66 	{&fd_dir, valid_iovec, 1, EISDIR},
67 	{&badfd, valid_iovec, 3, EBADF},
68 };
69 
verify_readv(unsigned int n)70 static void verify_readv(unsigned int n)
71 {
72 	struct tcase *tc = &tcases[n];
73 
74 	TST_EXP_FAIL2(readv(*tc->fd, tc->buf, tc->count), tc->exp_error,
75 		"readv(%d, %p, %d)", *tc->fd, tc->buf, tc->count);
76 }
77 
setup(void)78 static void setup(void)
79 {
80 	SAFE_FILE_PRINTF(TEST_FILE, "test");
81 
82 	fd_file = SAFE_OPEN(TEST_FILE, O_RDONLY);
83 
84 	efault_iovec[0].iov_base = tst_get_bad_addr(NULL);
85 
86 	SAFE_MKDIR(TEST_DIR, MODES);
87 	fd_dir = SAFE_OPEN(TEST_DIR, O_RDONLY);
88 }
89 
cleanup(void)90 static void cleanup(void)
91 {
92 	if (fd_file > 0)
93 		SAFE_CLOSE(fd_file);
94 
95 	if (fd_dir > 0)
96 		SAFE_CLOSE(fd_dir);
97 }
98 
99 static struct tst_test test = {
100 	.tcnt = ARRAY_SIZE(tcases),
101 	.needs_tmpdir = 1,
102 	.setup = setup,
103 	.cleanup = cleanup,
104 	.test = verify_readv,
105 };
106