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