From 9f5a288d510d29e8fc9a65742ec8eaed0094f02e Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Apr 20 2015 13:58:42 +0000 Subject: Don't use O_NOFOLLOW Switch to using a before/after lstat()/fstat() check instead of O_NOFOLLOW to ensure there aren't any shenanigans going on when we go to tweak permissions on an NSS database's individual files. O_NOFOLLOW isn't as portable as we'd need. --- diff --git a/src/util-n.c b/src/util-n.c index 045520b..b84bfa4 100644 --- a/src/util-n.c +++ b/src/util-n.c @@ -142,7 +142,7 @@ util_set_db_owner_perms(const char *dbdir, const char *filename, struct group *grp; uid_t uid; gid_t gid; - struct stat st; + struct stat st, before; int fd; if (filename == NULL) { @@ -153,7 +153,11 @@ util_set_db_owner_perms(const char *dbdir, const char *filename, return; } sprintf(pathname, "%s/%s", dbdir, filename); - fd = open(pathname, O_RDWR | O_NOFOLLOW); + if ((lstat(pathname, &before) == -1) || !S_ISREG(before.st_mode)) { + free(pathname); + return; + } + fd = open(pathname, O_RDWR); if (fd == -1) { free(pathname); return; @@ -163,6 +167,12 @@ util_set_db_owner_perms(const char *dbdir, const char *filename, free(pathname); return; } + if ((st.st_dev != before.st_dev) || + (st.st_ino != before.st_ino)) { + close(fd); + free(pathname); + return; + } if (owner != NULL) { user = strdup(owner); if (strchr(user, ':') == NULL) {