1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2023 Axcient 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 extern "C" { 29 #include <fcntl.h> 30 #include <unistd.h> 31 } 32 33 #include "mockfs.hh" 34 #include "utils.hh" 35 36 using namespace testing; 37 38 class BadServer: public FuseTest {}; 39 40 /* 41 * If the server sends a response for an unknown request, the kernel should 42 * gracefully return EINVAL. 43 */ 44 TEST_F(BadServer, UnknownUnique) 45 { 46 mockfs_buf_out out; 47 48 out.header.len = sizeof(out.header); 49 out.header.error = 0; 50 out.header.unique = 99999; // Invalid! 51 out.expected_errno = EINVAL; 52 m_mock->write_response(out); 53 } 54 55 /* 56 * If the server sends less than a header's worth of data, the kernel should 57 * gracefully return EINVAL. 58 */ 59 TEST_F(BadServer, ShortWrite) 60 { 61 mockfs_buf_out out; 62 63 out.header.len = sizeof(out.header) - 1; 64 out.header.error = 0; 65 out.header.unique = 0; // Asynchronous notification 66 out.expected_errno = EINVAL; 67 m_mock->write_response(out); 68 } 69 70 /* 71 * It is illegal to report an error, and also send back a payload. 72 */ 73 TEST_F(BadServer, ErrorWithPayload) 74 { 75 const char FULLPATH[] = "mountpoint/some_file.txt"; 76 const char RELPATH[] = "some_file.txt"; 77 78 EXPECT_LOOKUP(FUSE_ROOT_ID, RELPATH) 79 .WillOnce(Invoke([&](auto in, auto &out) { 80 // First send an invalid response 81 std::unique_ptr<mockfs_buf_out> out0(new mockfs_buf_out); 82 out0->header.unique = in.header.unique; 83 out0->header.error = -ENOENT; 84 SET_OUT_HEADER_LEN(*out0, entry); // Invalid! 85 out0->expected_errno = EINVAL; 86 out.push_back(std::move(out0)); 87 88 // Then, respond to the lookup so we can complete the test 89 std::unique_ptr<mockfs_buf_out> out1(new mockfs_buf_out); 90 out1->header.unique = in.header.unique; 91 out1->header.error = -ENOENT; 92 out1->header.len = sizeof(out1->header); 93 out.push_back(std::move(out1)); 94 95 // The kernel may disconnect us for bad behavior, so don't try 96 // to read any more. 97 m_mock->m_quit = true; 98 })); 99 100 EXPECT_NE(0, access(FULLPATH, F_OK)); 101 102 EXPECT_EQ(ENOENT, errno); 103 } 104