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;
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 (log) {
(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)
{
snprintf (db->filename, sizeof (db->filename), "%s", name);
db->setname = true;
return 1;
}
@ -414,38 +415,40 @@ cleanup_ENOMEM:
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;
#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.
*/
@ -471,7 +474,6 @@ int commonio_lock (struct commonio_db *db)
}
}
return 0; /* failure */
#endif /* !HAVE_LCKPWDF */
}
static void dec_lock_count (void)

View File

@ -143,6 +143,7 @@ struct commonio_db {
bool isopen:1;
bool locked:1;
bool readonly:1;
bool setname:1;
};
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, /* isopen */
false, /* locked */
false /* readonly */
false, /* readonly */
false /* setname */
};
int gr_setdbname (const char *filename)

View File

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

View File

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

View File

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

View File

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