mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Don't report partialResult errors from sendfile
The input file descriptor is always a regular file, so sendfile can't lose any data if it will not be able to write them to the output file descriptor. Reported-by: syzbot+22d22330a35fa1c02155@syzkaller.appspotmail.com PiperOrigin-RevId: 272730357
This commit is contained in:
@@ -159,9 +159,14 @@ func Sendfile(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Sysc
|
||||
}, outFile.Flags().NonBlocking)
|
||||
}
|
||||
|
||||
// Sendfile can't lose any data because inFD is always a regual file.
|
||||
if n != 0 {
|
||||
err = nil
|
||||
}
|
||||
|
||||
// We can only pass a single file to handleIOError, so pick inFile
|
||||
// arbitrarily. This is used only for debugging purposes.
|
||||
return uintptr(n), nil, handleIOError(t, n != 0, err, kernel.ERESTARTSYS, "sendfile", inFile)
|
||||
return uintptr(n), nil, handleIOError(t, false, err, kernel.ERESTARTSYS, "sendfile", inFile)
|
||||
}
|
||||
|
||||
// Splice implements splice(2).
|
||||
@@ -305,6 +310,11 @@ func Tee(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallCo
|
||||
Dup: true,
|
||||
}, nonBlock)
|
||||
|
||||
// Tee doesn't change a state of inFD, so it can't lose any data.
|
||||
if n != 0 {
|
||||
err = nil
|
||||
}
|
||||
|
||||
// See above; inFile is chosen arbitrarily here.
|
||||
return uintptr(n), nil, handleIOError(t, n != 0, err, kernel.ERESTARTSYS, "tee", inFile)
|
||||
return uintptr(n), nil, handleIOError(t, false, err, kernel.ERESTARTSYS, "tee", inFile)
|
||||
}
|
||||
|
||||
@@ -1905,6 +1905,7 @@ cc_binary(
|
||||
srcs = ["sendfile.cc"],
|
||||
linkstatic = 1,
|
||||
deps = [
|
||||
"//test/util:eventfd_util",
|
||||
"//test/util:file_descriptor",
|
||||
"//test/util:temp_path",
|
||||
"//test/util:test_main",
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/eventfd.h>
|
||||
#include <sys/sendfile.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@@ -21,6 +22,7 @@
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/time/clock.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "test/util/eventfd_util.h"
|
||||
#include "test/util/file_descriptor.h"
|
||||
#include "test/util/temp_path.h"
|
||||
#include "test/util/test_util.h"
|
||||
@@ -511,6 +513,23 @@ TEST(SendFileTest, SendPipeBlocks) {
|
||||
SyscallSucceedsWithValue(kDataSize));
|
||||
}
|
||||
|
||||
TEST(SendFileTest, SendToSpecialFile) {
|
||||
// Create temp file.
|
||||
const TempPath in_file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFileWith(
|
||||
GetAbsoluteTestTmpdir(), "", TempPath::kDefaultFileMode));
|
||||
|
||||
const FileDescriptor inf =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(Open(in_file.path(), O_RDWR));
|
||||
constexpr int kSize = 0x7ff;
|
||||
ASSERT_THAT(ftruncate(inf.get(), kSize), SyscallSucceeds());
|
||||
|
||||
auto eventfd = ASSERT_NO_ERRNO_AND_VALUE(NewEventFD());
|
||||
|
||||
// eventfd can accept a number of bytes which is a multiple of 8.
|
||||
EXPECT_THAT(sendfile(eventfd.get(), inf.get(), nullptr, 0xfffff),
|
||||
SyscallSucceedsWithValue(kSize & (~7)));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace testing
|
||||
|
||||
Reference in New Issue
Block a user