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 29static int badfd = -1; 30static int fd_dir, fd_file; 31static char buf1[K_1]; 32const char *TEST_DIR = "test_dir"; 33const char *TEST_FILE = "test_file"; 34 35static struct iovec invalid_iovec[] = { 36 {buf1, -1}, 37 {buf1 + CHUNK, CHUNK}, 38 {buf1 + 2*CHUNK, CHUNK}, 39}; 40 41static struct iovec large_iovec[] = { 42 {buf1, K_1}, 43 {buf1 + CHUNK, K_1}, 44 {buf1 + CHUNK*2, K_1}, 45}; 46 47static struct iovec efault_iovec[] = { 48 {NULL, CHUNK}, 49 {buf1 + CHUNK, CHUNK}, 50 {buf1 + 2*CHUNK, CHUNK}, 51}; 52 53static struct iovec valid_iovec[] = { 54 {buf1, CHUNK}, 55}; 56 57static 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 70static 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 78static 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 90static 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 99static 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