mirror of
https://git.openafs.org/openafs.git
synced 2025-01-18 15:00:12 +00:00
vos: Check start-of-dump magic in vos restore
When restoring with a regular file (either with -file or a shell redirect '<'), vos restore verifies the file ends with the end-of-dump magic number. This catches cases in which the specified file is obviously not a dump file, for example the file is empty, truncated, or just not file created by vos dump. Currently, no checks are done when restoring from a pipe or fifo, since it is not possible to check the end of the stream and reset the seek pointer to before sending the data to the volume server. Add a check to verify the dump begins with the dump header tag and the start-of-dump magic number, even when the dump file is not seekable. In the case the dump file is not seekable, send the start of dump tag and the start-of-dump magic number directly in SendFile(), since those values were already read in CheckDumpFile(). This guards against starting a restore from an empty or wrong file when restoring from a pipeline or a named pipe. Change-Id: I7aa508bf5f0e81da7d6602856b5242cb6313e9a8 Reviewed-on: https://gerrit.openafs.org/14711 Reviewed-by: Cheyenne Wills <cwills@sinenomine.net> Tested-by: BuildBot <buildbot@rampaginggeek.com> Reviewed-by: Andrew Deason <adeason@sinenomine.net>
This commit is contained in:
parent
22e8fa88d1
commit
65290ac18b
@ -288,6 +288,9 @@ IsPartValid(afs_int32 partId, afs_uint32 server, afs_int32 *code)
|
||||
* @param[in] call rx call object
|
||||
* @param[in] rock usd file handle opened for read
|
||||
*
|
||||
* @pre The ufd is positioned after the DUMPBEGINMAGIC
|
||||
* in the dump stream.
|
||||
*
|
||||
* @returns status
|
||||
* @retval 0 success
|
||||
* @retval -1 error
|
||||
@ -300,6 +303,8 @@ SendFile(struct rx_call *call, void *rock)
|
||||
afs_int32 error;
|
||||
afs_uint32 nbytes;
|
||||
long blksize = 0;
|
||||
char tag = D_DUMPHEADER;
|
||||
afs_uint32 magic = htonl(DUMPBEGINMAGIC);
|
||||
|
||||
error = USD_IOCTL(ufd, USD_IOCTL_GETBLKSIZE, &blksize);
|
||||
if (error != 0) {
|
||||
@ -307,12 +312,23 @@ SendFile(struct rx_call *call, void *rock)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Send the header fields already read in CheckDumpFile(). */
|
||||
nbytes = rx_Write(call, &tag, sizeof(tag));
|
||||
if (nbytes != sizeof(tag)) {
|
||||
return -1;
|
||||
}
|
||||
nbytes = rx_Write(call, (char *)&magic, sizeof(magic));
|
||||
if (nbytes != sizeof(magic)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
buffer = malloc(blksize);
|
||||
if (!buffer) {
|
||||
fprintf(STDERR, "malloc failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Send the rest of the dump. */
|
||||
while (!error) {
|
||||
#if !defined(AFS_NT40_ENV) && !defined(AFS_PTHREAD_ENV)
|
||||
/* Only for this for non-NT, non-pthread. For NT, we can't select on
|
||||
@ -349,12 +365,18 @@ SendFile(struct rx_call *call, void *rock)
|
||||
*
|
||||
* @param[in] ufd dump file handle
|
||||
* @retval 0 file appears to contain a volume dump
|
||||
*
|
||||
* @post For a valid volume dump, ufd is positioned after the
|
||||
* DUMPBEGINMAGIC in the dump stream.
|
||||
*/
|
||||
static int
|
||||
CheckDumpFile(usd_handle_t ufd)
|
||||
{
|
||||
afs_int32 code;
|
||||
int is_seekable = 0;
|
||||
char tag = '\0';
|
||||
afs_uint32 got = 0;
|
||||
afs_uint32 magic = 0;
|
||||
|
||||
/* Test if we have a valid dump. */
|
||||
code = USD_IOCTL(ufd, USD_IOCTL_ISSEEKABLE, &is_seekable);
|
||||
@ -365,8 +387,6 @@ CheckDumpFile(usd_handle_t ufd)
|
||||
}
|
||||
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) {
|
||||
@ -398,6 +418,20 @@ CheckDumpFile(usd_handle_t ufd)
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
code = USD_READ(ufd, &tag, sizeof(tag), &got);
|
||||
if (code != 0 || got != sizeof(tag) || tag != D_DUMPHEADER) {
|
||||
fprintf(STDERR, "Start tag not found in '%s'.\n",
|
||||
ufd->fullPathName);
|
||||
return VOLSERBADOP;
|
||||
}
|
||||
code = USD_READ(ufd, (char *)&magic, sizeof(magic), &got);
|
||||
if (code != 0 || got != sizeof(magic) || ntohl(magic) != DUMPBEGINMAGIC) {
|
||||
fprintf(STDERR, "Begin dump signature not found in '%s'.\n",
|
||||
ufd->fullPathName);
|
||||
return VOLSERBADOP;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user