- Fix #595: unbound-anchor cannot deal with full disk; it will now

first write out to a temp file before replacing the original one,
  like Unbound already does for auto-trust-anchor-file.
This commit is contained in:
Yorgos Thessalonikefs 2024-04-08 14:15:03 +02:00
parent ba16e41160
commit 8575d5b35c
2 changed files with 52 additions and 23 deletions

View File

@ -1,3 +1,8 @@
8 April 2024: Yorgos
- Fix #595: unbound-anchor cannot deal with full disk; it will now
first write out to a temp file before replacing the original one,
like Unbound already does for auto-trust-anchor-file.
5 April 2024: Wouter
- Fix comment syntax for view function views_find_view.

View File

@ -1835,15 +1835,49 @@ verify_p7sig(BIO* data, BIO* p7s, STACK_OF(X509)* trust, const char* p7signer)
return secure;
}
/** open a temp file */
static FILE*
tempfile_open(char* tempf, size_t tempflen, const char* fname, const char* mode)
{
snprintf(tempf, tempflen, "%s~", fname);
return fopen(tempf, mode);
}
/** close an open temp file and replace the original with it */
static void
tempfile_close(FILE* fd, const char* tempf, const char* fname)
{
fflush(fd);
#ifdef HAVE_FSYNC
fsync(fileno(fd));
#else
FlushFileBuffers((HANDLE)_get_osfhandle(_fileno(fd)));
#endif
if(fclose(fd) != 0) {
printf("could not complete write: %s: %s\n",
tempf, strerror(errno));
unlink(tempf);
return;
}
/* success; overwrite actual file */
#ifdef USE_WINSOCK
(void)unlink(fname); /* windows does not replace file with rename() */
#endif
if(rename(tempf, fname) < 0) {
printf("rename(%s to %s): %s", tempf, fname, strerror(errno));
}
}
/** write unsigned root anchor file, a 5011 revoked tp */
static void
write_unsigned_root(const char* root_anchor_file)
{
FILE* out;
time_t now = time(NULL);
out = fopen(root_anchor_file, "w");
char tempf[2048];
out = tempfile_open(tempf, sizeof(tempf), root_anchor_file, "w");
if(!out) {
if(verb) printf("%s: %s\n", root_anchor_file, strerror(errno));
if(verb) printf("%s: %s\n", tempf, strerror(errno));
return;
}
if(fprintf(out, "; autotrust trust anchor file\n"
@ -1858,13 +1892,7 @@ write_unsigned_root(const char* root_anchor_file)
root_anchor_file);
if(verb && errno != 0) printf("%s\n", strerror(errno));
}
fflush(out);
#ifdef HAVE_FSYNC
fsync(fileno(out));
#else
FlushFileBuffers((HANDLE)_get_osfhandle(_fileno(out)));
#endif
fclose(out);
tempfile_close(out, tempf, root_anchor_file);
}
/** write root anchor file */
@ -1874,29 +1902,24 @@ write_root_anchor(const char* root_anchor_file, BIO* ds)
char* pp = NULL;
int len;
FILE* out;
char tempf[2048];
(void)BIO_seek(ds, 0);
len = BIO_get_mem_data(ds, &pp);
if(!len || !pp) {
if(verb) printf("out of memory\n");
return;
}
out = fopen(root_anchor_file, "w");
out = tempfile_open(tempf, sizeof(tempf), root_anchor_file, "w");
if(!out) {
if(verb) printf("%s: %s\n", root_anchor_file, strerror(errno));
if(verb) printf("%s: %s\n", tempf, strerror(errno));
return;
}
if(fwrite(pp, (size_t)len, 1, out) != 1) {
if(verb) printf("failed to write all data to %s\n",
root_anchor_file);
tempf);
if(verb && errno != 0) printf("%s\n", strerror(errno));
}
fflush(out);
#ifdef HAVE_FSYNC
fsync(fileno(out));
#else
FlushFileBuffers((HANDLE)_get_osfhandle(_fileno(out)));
#endif
fclose(out);
tempfile_close(out, tempf, root_anchor_file);
}
/** Perform the verification and update of the trustanchor file */
@ -2040,18 +2063,19 @@ try_read_anchor(const char* file)
static void
write_builtin_anchor(const char* file)
{
char tempf[2048];
const char* builtin_root_anchor = get_builtin_ds();
FILE* out = fopen(file, "w");
FILE* out = tempfile_open(tempf, sizeof(tempf), file, "w");
if(!out) {
printf("could not write builtin anchor, to file %s: %s\n",
file, strerror(errno));
tempf, strerror(errno));
return;
}
if(!fwrite(builtin_root_anchor, strlen(builtin_root_anchor), 1, out)) {
printf("could not complete write builtin anchor, to file %s: %s\n",
file, strerror(errno));
tempf, strerror(errno));
}
fclose(out);
tempfile_close(out, tempf, file);
}
/**