Skip to content

Commit f8732b1

Browse files
stoeckmannalejandro-colomar
authored andcommitted
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 a472091 commit f8732b1

File tree

1 file changed

+25
-27
lines changed

1 file changed

+25
-27
lines changed

lib/commonio.c

Lines changed: 25 additions & 27 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 *fmkstemp_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 *fmkstemp_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, 0, 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+
/* fmkstemp_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 tmpf[PATH_MAX], target[PATH_MAX];
277274
struct stat sb;
278275
struct utimbuf ub;
279276
FILE *bkfp;
280277
int c;
281278

279+
stprintf_a(tmpf, "%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 = fmkstemp_set_perms(tmpf, &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(tmpf);
303301
return -1;
304302
}
305303
if (fsync (fileno (bkfp)) != 0) {
306304
(void) fclose (bkfp);
307-
unlink(backup);
305+
unlink(tmpf);
308306
return -1;
309307
}
310308
if (fclose (bkfp) != 0) {
311-
unlink(backup);
309+
unlink(tmpf);
310+
return -1;
311+
}
312+
313+
stprintf_a(target, "%s-", name);
314+
if (lrename(tmpf, target) != 0) {
315+
unlink(tmpf);
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(tmpf, &ub);
318322
return 0;
319323
}
320324

@@ -900,19 +904,13 @@ commonio_close(struct commonio_db *db, MAYBE_UNUSED bool process_selinux)
900904
/*
901905
* Create backup file.
902906
*/
903-
if (stprintf_a(buf, "%s-", db->filename) == -1) {
904-
(void) fclose (db->fp);
905-
db->fp = NULL;
906-
goto fail;
907-
}
908-
909907
#ifdef WITH_SELINUX
910908
if (process_selinux
911909
&& set_selinux_file_context (db->filename, S_IFREG) != 0) {
912910
errors = true;
913911
}
914912
#endif
915-
if (create_backup (buf, db->fp) != 0) {
913+
if (create_backup(db->filename, db->fp) != 0) {
916914
errors = true;
917915
}
918916

@@ -939,7 +937,7 @@ commonio_close(struct commonio_db *db, MAYBE_UNUSED bool process_selinux)
939937
sb.st_gid = db->st_gid;
940938
}
941939

942-
if (stprintf_a(buf, "%s+", db->filename) == -1)
940+
if (stprintf_a(buf, "%s.cioXXXXXX", db->filename) == -1)
943941
goto fail;
944942

945943
#ifdef WITH_SELINUX
@@ -949,7 +947,7 @@ commonio_close(struct commonio_db *db, MAYBE_UNUSED bool process_selinux)
949947
}
950948
#endif
951949

952-
db->fp = fopen_set_perms (buf, "w", &sb);
950+
db->fp = fmkstemp_set_perms(buf, &sb);
953951
if (NULL == db->fp) {
954952
goto fail;
955953
}
@@ -977,7 +975,7 @@ commonio_close(struct commonio_db *db, MAYBE_UNUSED bool process_selinux)
977975
goto fail;
978976
}
979977

980-
if (lrename (buf, db->filename) != 0) {
978+
if (lrename(buf, db->filename) != 0) {
981979
goto fail;
982980
}
983981

0 commit comments

Comments
 (0)