Merge pull request #164 from t8m/use-lckpwdf

Use lckpwdf() again if prefix is not set and fix a possible DoS in locking
This commit is contained in:
Christian Brauner 2019-05-03 10:43:41 +02:00 committed by GitHub
commit caefe9e8de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 47 additions and 38 deletions

View File

@ -141,7 +141,7 @@ static int do_lock_file (const char *file, const char *lock, bool log)
int retval; int retval;
char buf[32]; char buf[32];
fd = open (file, O_CREAT | O_EXCL | O_WRONLY, 0600); fd = open (file, O_CREAT | O_TRUNC | O_WRONLY, 0600);
if (-1 == fd) { if (-1 == fd) {
if (log) { if (log) {
(void) fprintf (stderr, (void) fprintf (stderr,
@ -364,6 +364,7 @@ static void free_linked_list (struct commonio_db *db)
int commonio_setname (struct commonio_db *db, const char *name) int commonio_setname (struct commonio_db *db, const char *name)
{ {
snprintf (db->filename, sizeof (db->filename), "%s", name); snprintf (db->filename, sizeof (db->filename), "%s", name);
db->setname = true;
return 1; return 1;
} }
@ -414,38 +415,40 @@ cleanup_ENOMEM:
int commonio_lock (struct commonio_db *db) int commonio_lock (struct commonio_db *db)
{ {
/*#ifdef HAVE_LCKPWDF*/ /* not compatible with prefix option*/
#if 0
/*
* only if the system libc has a real lckpwdf() - the one from
* lockpw.c calls us and would cause infinite recursion!
*/
/*
* Call lckpwdf() on the first lock.
* If it succeeds, call *_lock() only once
* (no retries, it should always succeed).
*/
if (0 == lock_count) {
if (lckpwdf () == -1) {
if (geteuid () != 0) {
(void) fprintf (stderr,
"%s: Permission denied.\n",
Prog);
}
return 0; /* failure */
}
}
if (commonio_lock_nowait (db, true) != 0) {
return 1; /* success */
}
ulckpwdf ();
return 0; /* failure */
#else /* !HAVE_LCKPWDF */
int i; int i;
#ifdef HAVE_LCKPWDF
/*
* Only if the system libc has a real lckpwdf() - the one from
* lockpw.c calls us and would cause infinite recursion!
* It is also not used with the prefix option.
*/
if (!db->setname) {
/*
* Call lckpwdf() on the first lock.
* If it succeeds, call *_lock() only once
* (no retries, it should always succeed).
*/
if (0 == lock_count) {
if (lckpwdf () == -1) {
if (geteuid () != 0) {
(void) fprintf (stderr,
"%s: Permission denied.\n",
Prog);
}
return 0; /* failure */
}
}
if (commonio_lock_nowait (db, true) != 0) {
return 1; /* success */
}
ulckpwdf ();
return 0; /* failure */
}
#endif /* !HAVE_LCKPWDF */
/* /*
* lckpwdf() not used - do it the old way. * lckpwdf() not used - do it the old way.
*/ */
@ -471,7 +474,6 @@ int commonio_lock (struct commonio_db *db)
} }
} }
return 0; /* failure */ return 0; /* failure */
#endif /* !HAVE_LCKPWDF */
} }
static void dec_lock_count (void) static void dec_lock_count (void)

View File

@ -143,6 +143,7 @@ struct commonio_db {
bool isopen:1; bool isopen:1;
bool locked:1; bool locked:1;
bool readonly:1; bool readonly:1;
bool setname:1;
}; };
extern int commonio_setname (struct commonio_db *, const char *); extern int commonio_setname (struct commonio_db *, const char *);

View File

@ -139,7 +139,8 @@ static /*@owned@*/struct commonio_db group_db = {
false, /* changed */ false, /* changed */
false, /* isopen */ false, /* isopen */
false, /* locked */ false, /* locked */
false /* readonly */ false, /* readonly */
false /* setname */
}; };
int gr_setdbname (const char *filename) int gr_setdbname (const char *filename)

View File

@ -114,7 +114,8 @@ static struct commonio_db passwd_db = {
false, /* changed */ false, /* changed */
false, /* isopen */ false, /* isopen */
false, /* locked */ false, /* locked */
false /* readonly */ false, /* readonly */
false /* setname */
}; };
int pw_setdbname (const char *filename) int pw_setdbname (const char *filename)

View File

@ -238,7 +238,8 @@ static struct commonio_db gshadow_db = {
false, /* changed */ false, /* changed */
false, /* isopen */ false, /* isopen */
false, /* locked */ false, /* locked */
false /* readonly */ false, /* readonly */
false /* setname */
}; };
int sgr_setdbname (const char *filename) int sgr_setdbname (const char *filename)

View File

@ -114,7 +114,8 @@ static struct commonio_db shadow_db = {
false, /* changed */ false, /* changed */
false, /* isopen */ false, /* isopen */
false, /* locked */ false, /* locked */
false /* readonly */ false, /* readonly */
false /* setname */
}; };
int spw_setdbname (const char *filename) int spw_setdbname (const char *filename)

View File

@ -550,7 +550,8 @@ static struct commonio_db subordinate_uid_db = {
false, /* changed */ false, /* changed */
false, /* isopen */ false, /* isopen */
false, /* locked */ false, /* locked */
false /* readonly */ false, /* readonly */
false /* setname */
}; };
int sub_uid_setdbname (const char *filename) int sub_uid_setdbname (const char *filename)
@ -631,7 +632,8 @@ static struct commonio_db subordinate_gid_db = {
false, /* changed */ false, /* changed */
false, /* isopen */ false, /* isopen */
false, /* locked */ false, /* locked */
false /* readonly */ false, /* readonly */
false /* setname */
}; };
int sub_gid_setdbname (const char *filename) int sub_gid_setdbname (const char *filename)