summaryrefslogtreecommitdiffstats
path: root/src/lib/kdb
diff options
context:
space:
mode:
authorBen Kaduk <kaduk@mit.edu>2012-07-03 10:27:20 -0400
committerBen Kaduk <kaduk@mit.edu>2013-11-04 13:43:36 -0500
commit0415740bb569bad53b18f4483837e7e037f88544 (patch)
treef8f1ff9ad2d2f619a415d831ca262de0f01825ed /src/lib/kdb
parentf7e434aa7ecb05a6ade5e3d4a435d25069acd5b2 (diff)
downloadkrb5-0415740bb569bad53b18f4483837e7e037f88544.tar.gz
krb5-0415740bb569bad53b18f4483837e7e037f88544.tar.xz
krb5-0415740bb569bad53b18f4483837e7e037f88544.zip
Remove last uses of "possibly-insecure" mktemp(3)
Many libc implementations include notations to the linker to generate warnings upon references to mktemp(3), due to its potential for insecure operation. This has been the case for quite some time, as was noted in RT #6199. Our usage of the function has decreased with time, but has not yet disappeared entirely. This commit removes the last few instances from our tree. kprop's credentials never need to hit the disk, so a MEMORY ccache is sufficient (and does not need randomization). store_master_key_list is explicitly putting keys on disk so as to do an atomic rename of the stash file, but since the stash file should be in a root-only directory, we can just use a fixed name for the temporary file. When using this fixed name, we must detect (and error out) if the temporary file already exists; add a test to confirm that we do so. ticket: 1794
Diffstat (limited to 'src/lib/kdb')
-rw-r--r--src/lib/kdb/kdb_default.c37
1 files changed, 23 insertions, 14 deletions
diff --git a/src/lib/kdb/kdb_default.c b/src/lib/kdb/kdb_default.c
index 82fa5c4a07..b7a2f24276 100644
--- a/src/lib/kdb/kdb_default.c
+++ b/src/lib/kdb/kdb_default.c
@@ -156,10 +156,6 @@ krb5_def_store_mkey_list(krb5_context context,
keyfile = defkeyfile;
}
- /*
- * XXX making the assumption that the keyfile is in a dir that requires root
- * privilege to write to thus making timing attacks unlikely.
- */
if ((statrc = stat(keyfile, &stb)) >= 0) {
/* if keyfile exists it better be a regular file */
if (!S_ISREG(stb.st_mode)) {
@@ -171,27 +167,40 @@ krb5_def_store_mkey_list(krb5_context context,
}
}
- /* Use temp keytab file name in case creation of keytab fails */
-
- /* create temp file template for use by mktemp() */
- if ((retval = asprintf(&tmp_ktname, "WRFILE:%s_XXXXXX", keyfile)) < 0) {
+ /*
+ * We assume the stash file is in a directory writable only by root.
+ * As such, don't worry about collisions, just do an atomic rename.
+ */
+ retval = asprintf(&tmp_ktname, "FILE:%s_tmp", keyfile);
+ if (retval < 0) {
krb5_set_error_message(context, retval,
_("Could not create temp keytab file name."));
goto out;
}
/*
- * Set tmp_ktpath to point to the keyfile path (skip WRFILE:). Subtracting
+ * Set tmp_ktpath to point to the keyfile path (skip FILE:). Subtracting
* 1 to account for NULL terminator in sizeof calculation of a string
* constant. Used further down.
*/
- tmp_ktpath = tmp_ktname + (sizeof("WRFILE:") - 1);
+ tmp_ktpath = tmp_ktname + (sizeof("FILE:") - 1);
- if (mktemp(tmp_ktpath) == NULL) {
+ /*
+ * This time-of-check-to-time-of-access race is fine; we care only
+ * about an administrator running the command twice, not an attacker
+ * trying to beat us to creating the file. Per the above comment, we
+ * assume the stash file is in a directory writable only by root.
+ */
+ statrc = stat(tmp_ktpath, &stb);
+ if (statrc == -1 && errno != ENOENT) {
+ /* ENOENT is the expected case */
retval = errno;
+ goto out;
+ } else if (statrc == 0) {
+ retval = EEXIST;
krb5_set_error_message(context, retval,
- _("Could not create temp stash file: %s"),
- error_message(errno));
+ _("Temporary stash file already exists: %s."),
+ tmp_ktpath);
goto out;
}
@@ -215,7 +224,7 @@ krb5_def_store_mkey_list(krb5_context context,
/* Clean up by deleting the tmp keyfile if it exists. */
(void)unlink(tmp_ktpath);
} else {
- /* rename original keyfile to original filename */
+ /* Atomically rename temp keyfile to original filename. */
if (rename(tmp_ktpath, keyfile) < 0) {
retval = errno;
krb5_set_error_message(context, retval,