mirror of
https://github.com/sudo-project/sudo.git
synced 2025-08-28 04:47:42 +00:00
Fix memory leak on error found by the clang 10.01 analyzer.
This commit is contained in:
parent
0106343032
commit
24d5ee5893
@ -987,29 +987,22 @@ lock_sudoers(struct sudoersfile *entry)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Used to open (and lock) the initial sudoers file and to also open
|
* Open (and lock) a new sudoers file.
|
||||||
* any subsequent files #included via a callback from the parser.
|
* Returns a new struct sudoersfile on success or NULL on failure.
|
||||||
*/
|
*/
|
||||||
FILE *
|
static struct sudoersfile *
|
||||||
open_sudoers(const char *path, bool doedit, bool *keepopen)
|
new_sudoers(const char *path, bool doedit)
|
||||||
{
|
{
|
||||||
struct sudoersfile *entry;
|
struct sudoersfile *entry;
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
FILE *fp;
|
|
||||||
int open_flags;
|
int open_flags;
|
||||||
debug_decl(open_sudoers, SUDOERS_DEBUG_UTIL);
|
debug_decl(new_sudoersfile, SUDOERS_DEBUG_UTIL);
|
||||||
|
|
||||||
if (checkonly)
|
if (checkonly)
|
||||||
open_flags = O_RDONLY;
|
open_flags = O_RDONLY;
|
||||||
else
|
else
|
||||||
open_flags = O_RDWR | O_CREAT;
|
open_flags = O_RDWR | O_CREAT;
|
||||||
|
|
||||||
/* Check for existing entry */
|
|
||||||
TAILQ_FOREACH(entry, &sudoerslist, entries) {
|
|
||||||
if (strcmp(path, entry->path) == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (entry == NULL) {
|
|
||||||
entry = calloc(1, sizeof(*entry));
|
entry = calloc(1, sizeof(*entry));
|
||||||
if (entry == NULL || (entry->path = strdup(path)) == NULL)
|
if (entry == NULL || (entry->path = strdup(path)) == NULL)
|
||||||
sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
||||||
@ -1019,18 +1012,40 @@ open_sudoers(const char *path, bool doedit, bool *keepopen)
|
|||||||
entry->fd = open(entry->path, open_flags, sudoers_mode);
|
entry->fd = open(entry->path, open_flags, sudoers_mode);
|
||||||
if (entry->fd == -1 || fstat(entry->fd, &sb) == -1) {
|
if (entry->fd == -1 || fstat(entry->fd, &sb) == -1) {
|
||||||
sudo_warn("%s", entry->path);
|
sudo_warn("%s", entry->path);
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
if (!S_ISREG(sb.st_mode)) {
|
||||||
|
sudo_warnx(U_("%s is not a regular file"), entry->path);
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
if (!checkonly && !lock_sudoers(entry))
|
||||||
|
goto bad;
|
||||||
|
debug_return_ptr(entry);
|
||||||
|
bad:
|
||||||
if (entry->fd != -1)
|
if (entry->fd != -1)
|
||||||
close(entry->fd);
|
close(entry->fd);
|
||||||
free(entry);
|
free(entry);
|
||||||
debug_return_ptr(NULL);
|
debug_return_ptr(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Used to open (and lock) the initial sudoers file and to also open
|
||||||
|
* any subsequent files #included via a callback from the parser.
|
||||||
|
*/
|
||||||
|
FILE *
|
||||||
|
open_sudoers(const char *path, bool doedit, bool *keepopen)
|
||||||
|
{
|
||||||
|
struct sudoersfile *entry;
|
||||||
|
FILE *fp;
|
||||||
|
debug_decl(open_sudoers, SUDOERS_DEBUG_UTIL);
|
||||||
|
|
||||||
|
/* Check for existing entry */
|
||||||
|
TAILQ_FOREACH(entry, &sudoerslist, entries) {
|
||||||
|
if (strcmp(path, entry->path) == 0)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (!S_ISREG(sb.st_mode)) {
|
if (entry == NULL) {
|
||||||
sudo_warnx(U_("%s is not a regular file"), entry->path);
|
if ((entry = new_sudoers(path, doedit)) == NULL)
|
||||||
close(entry->fd);
|
|
||||||
free(entry);
|
|
||||||
debug_return_ptr(NULL);
|
|
||||||
}
|
|
||||||
if (!checkonly && !lock_sudoers(entry))
|
|
||||||
debug_return_ptr(NULL);
|
debug_return_ptr(NULL);
|
||||||
if ((fp = fdopen(entry->fd, "r")) == NULL)
|
if ((fp = fdopen(entry->fd, "r")) == NULL)
|
||||||
sudo_fatal("%s", entry->path);
|
sudo_fatal("%s", entry->path);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user