Skip to content

Commit 92e2db5

Browse files
committed
lib/commonio.c: Use unpredictable temporary names
Make sure that an attacker with sufficient privileges cannot simply create a file with expected temporary name to retrieve content of previous and/or future database. Signed-off-by: Tobias Stoeckmann <[email protected]>
1 parent 9d45996 commit 92e2db5

File tree

1 file changed

+25
-21
lines changed

1 file changed

+25
-21
lines changed

lib/commonio.c

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "atoi/getnum.h"
2828
#include "commonio.h"
2929
#include "defines.h"
30+
#include "fs/mkstemp/fmkomstemp.h"
3031
#include "nscd.h"
3132
#ifdef WITH_TCB
3233
#include <tcb.h>
@@ -47,9 +48,8 @@
4748
static int lrename (const char *, const char *);
4849
static int check_link_count (const char *file, bool log);
4950
static int do_lock_file (const char *file, const char *lock, bool log);
50-
static /*@null@*/ /*@dependent@*/FILE *fopen_set_perms (
51-
const char *name,
52-
const char *mode,
51+
static /*@null@*/ /*@dependent@*/FILE *fmkomstemp_set_perms (
52+
char *name,
5353
const struct stat *sb);
5454
static int create_backup (const char *, FILE *);
5555
static void free_linked_list (struct commonio_db *);
@@ -240,17 +240,13 @@ static int do_lock_file (const char *file, const char *lock, bool log)
240240
}
241241

242242

243-
static /*@null@*/ /*@dependent@*/FILE *fopen_set_perms (
244-
const char *name,
245-
const char *mode,
243+
static /*@null@*/ /*@dependent@*/FILE *fmkomstemp_set_perms (
244+
char *name,
246245
const struct stat *sb)
247246
{
248247
FILE *fp;
249-
mode_t mask;
250248

251-
mask = umask (0777);
252-
fp = fopen (name, mode);
253-
(void) umask (mask);
249+
fp = fmkomstemp(name, O_CLOEXEC, 0600);
254250
if (NULL == fp) {
255251
return NULL;
256252
}
@@ -266,24 +262,26 @@ static /*@null@*/ /*@dependent@*/FILE *fopen_set_perms (
266262

267263
fail:
268264
(void) fclose (fp);
269-
/* fopen_set_perms is used for intermediate files */
265+
/* fmkomstemp_set_perms is used for intermediate files */
270266
(void) unlink (name);
271267
return NULL;
272268
}
273269

274270

275-
static int create_backup (const char *backup, FILE * fp)
271+
static int create_backup (const char *name, FILE * fp)
276272
{
273+
char buf[PATH_MAX], target[PATH_MAX];
277274
struct stat sb;
278275
struct utimbuf ub;
279276
FILE *bkfp;
280277
int c;
281278

279+
stprintf_a(buf, "%s.cioXXXXXX", name);
282280
if (fstat (fileno (fp), &sb) != 0) {
283281
return -1;
284282
}
285283

286-
bkfp = fopen_set_perms (backup, "w", &sb);
284+
bkfp = fmkomstemp_set_perms(buf, &sb);
287285
if (NULL == bkfp) {
288286
return -1;
289287
}
@@ -299,22 +297,28 @@ static int create_backup (const char *backup, FILE * fp)
299297
}
300298
if ((c != EOF) || (ferror (fp) != 0) || (fflush (bkfp) != 0)) {
301299
(void) fclose (bkfp);
302-
unlink(backup);
300+
unlink(buf);
303301
return -1;
304302
}
305303
if (fsync (fileno (bkfp)) != 0) {
306304
(void) fclose (bkfp);
307-
unlink(backup);
305+
unlink(buf);
308306
return -1;
309307
}
310308
if (fclose (bkfp) != 0) {
311-
unlink(backup);
309+
unlink(buf);
310+
return -1;
311+
}
312+
313+
stprintf_a(target, "%s-", name);
314+
if (lrename(buf, target) != 0) {
315+
unlink(buf);
312316
return -1;
313317
}
314318

315319
ub.actime = sb.st_atime;
316320
ub.modtime = sb.st_mtime;
317-
(void) utime (backup, &ub);
321+
(void) utime(buf, &ub);
318322
return 0;
319323
}
320324

@@ -912,7 +916,7 @@ commonio_close(struct commonio_db *db, MAYBE_UNUSED bool process_selinux)
912916
errors = true;
913917
}
914918
#endif
915-
if (create_backup (buf, db->fp) != 0) {
919+
if (create_backup(db->filename, db->fp) != 0) {
916920
errors = true;
917921
}
918922

@@ -939,7 +943,7 @@ commonio_close(struct commonio_db *db, MAYBE_UNUSED bool process_selinux)
939943
sb.st_gid = db->st_gid;
940944
}
941945

942-
if (stprintf_a(buf, "%s+", db->filename) == -1)
946+
if (stprintf_a(buf, "%s.cioXXXXXX", db->filename) == -1)
943947
goto fail;
944948

945949
#ifdef WITH_SELINUX
@@ -949,7 +953,7 @@ commonio_close(struct commonio_db *db, MAYBE_UNUSED bool process_selinux)
949953
}
950954
#endif
951955

952-
db->fp = fopen_set_perms (buf, "w", &sb);
956+
db->fp = fmkomstemp_set_perms(buf, &sb);
953957
if (NULL == db->fp) {
954958
goto fail;
955959
}
@@ -977,7 +981,7 @@ commonio_close(struct commonio_db *db, MAYBE_UNUSED bool process_selinux)
977981
goto fail;
978982
}
979983

980-
if (lrename (buf, db->filename) != 0) {
984+
if (lrename(buf, db->filename) != 0) {
981985
goto fail;
982986
}
983987

0 commit comments

Comments
 (0)