mirror of
https://git.openafs.org/openafs.git
synced 2025-01-18 15:00:12 +00:00
vos: Check end of dump magic when file is seekable
When restoring a volume with the -file argument, vos verifies the last four bytes of the file are the dump end magic before sending the dump to the volume server. Currently, this check is skipped when reading a dump from stdin because it is assumed the data is being read from a pipe. However, this assumption is not correct. The file handle created from stdin may be seekable when redirection is used, and the file handle created from a file name may or may not be seekable, depending on the file type. For example, when redirecting a regular file to stdin, the file handle is seekable, since the shell opens the given file name and associates stdin with the opened file: $ vos restore ... < myfile In addition, the file handle is not seekable when specifying a named pipe (fifo) with the -file option: $ mkfifo mypipe $ vos restore ... -file mypipe Instead of assuming file handles opened from file names are always seekable and file handles opened from stdin are never seekable, use USD_IOCTL() to determine when file handles are seekable, and when seekable, verify the file ends with the dump end magic number. While here, be sure to check the return codes from seek and reads while checking for the dump end magic. Change-Id: I9d16b13682365b82cb9d0b3673c4ed7c3ab4dc2e Reviewed-on: https://gerrit.openafs.org/14758 Reviewed-by: Andrew Deason <adeason@sinenomine.net> Reviewed-by: Cheyenne Wills <cwills@sinenomine.net> Tested-by: BuildBot <buildbot@rampaginggeek.com> Reviewed-by: Michael Meffie <mmeffie@sinenomine.net>
This commit is contained in:
parent
ba27ac6f04
commit
4e7b6ffc8f
@ -372,9 +372,7 @@ WriteData(struct rx_call *call, void *rock)
|
||||
usd_handle_t ufd = NULL;
|
||||
afs_int32 error = 0;
|
||||
afs_int32 code;
|
||||
afs_int64 currOffset;
|
||||
afs_uint32 buffer;
|
||||
afs_uint32 got;
|
||||
int is_seekable = 0;
|
||||
|
||||
if (!filename || !*filename) {
|
||||
usd_StandardInput(&ufd);
|
||||
@ -386,16 +384,55 @@ WriteData(struct rx_call *call, void *rock)
|
||||
error = VOLSERBADOP;
|
||||
goto wfail;
|
||||
}
|
||||
/* test if we have a valid dump */
|
||||
USD_SEEK(ufd, 0, SEEK_END, &currOffset);
|
||||
USD_SEEK(ufd, currOffset - sizeof(afs_uint32), SEEK_SET, &currOffset);
|
||||
USD_READ(ufd, (char *)&buffer, sizeof(afs_uint32), &got);
|
||||
if ((got != sizeof(afs_uint32)) || (ntohl(buffer) != DUMPENDMAGIC)) {
|
||||
fprintf(STDERR, "Signature missing from end of file '%s'\n", filename);
|
||||
}
|
||||
|
||||
/* Test if we have a valid dump. */
|
||||
code = USD_IOCTL(ufd, USD_IOCTL_ISSEEKABLE, &is_seekable);
|
||||
if (code != 0) {
|
||||
fprintf(STDERR, "Failed to determine if '%s' is seekable; code=%d\n",
|
||||
ufd->fullPathName, code);
|
||||
error = code;
|
||||
goto wfail;
|
||||
}
|
||||
if (is_seekable) {
|
||||
afs_int64 offset = 0;
|
||||
afs_uint32 magic = 0;
|
||||
afs_uint32 got = 0;
|
||||
|
||||
code = USD_SEEK(ufd, 0, SEEK_END, &offset);
|
||||
if (code != 0) {
|
||||
fprintf(STDERR, "Failed seek to end of '%s'; code=%d\n",
|
||||
ufd->fullPathName, code);
|
||||
error = code;
|
||||
goto wfail;
|
||||
}
|
||||
if (offset < sizeof(magic)) {
|
||||
fprintf(STDERR, "End of dump signature not found in '%s'.\n",
|
||||
ufd->fullPathName);
|
||||
error = VOLSERBADOP;
|
||||
goto wfail;
|
||||
}
|
||||
USD_SEEK(ufd, 0, SEEK_SET, &currOffset);
|
||||
code = USD_SEEK(ufd, offset - sizeof(magic), SEEK_SET, &offset);
|
||||
if (code != 0) {
|
||||
fprintf(STDERR, "Failed seek to dump end signature in '%s'; code=%d\n",
|
||||
ufd->fullPathName, code);
|
||||
error = code;
|
||||
goto wfail;
|
||||
}
|
||||
code = USD_READ(ufd, (char *)&magic, sizeof(magic), &got);
|
||||
if (code != 0 || got != sizeof(magic) || ntohl(magic) != DUMPENDMAGIC) {
|
||||
fprintf(STDERR, "End of dump signature not found in '%s'.\n",
|
||||
ufd->fullPathName);
|
||||
error = VOLSERBADOP;
|
||||
goto wfail;
|
||||
}
|
||||
code = USD_SEEK(ufd, 0, SEEK_SET, &offset);
|
||||
if (code != 0) {
|
||||
fprintf(STDERR, "Failed seek to start of '%s'; code=%d\n",
|
||||
ufd->fullPathName, code);
|
||||
error = code;
|
||||
goto wfail;
|
||||
}
|
||||
}
|
||||
code = SendFile(ufd, call);
|
||||
if (code) {
|
||||
|
Loading…
Reference in New Issue
Block a user