free_safe() was broken, as the pointer was not set to NULL outside of free_safe(). Simplest/cleanest way to fix this was to replace it by a macro doing the same. Now the pointers are correctly set to NULL, and things are actually safe.
ifeq ($(FCRONDYN), 1)
LIBOBJS := socket.o $(LIBOBJS)
endif
-OBJSD := fcron.o subs.o save.o temp_file.o log.o database.o job.o conf.o u_list.o exe_list.o lavg_list.o env_list.o fcronconf.o $(LIBOBJS)
-OBJSTAB := fcrontab.o subs.o save.o temp_file.o log.o fileconf.o allow.o read_string.o u_list.o env_list.o fcronconf.o
-OBJSDYN := fcrondyn.o subs.o log.o allow.o read_string.o fcronconf.o
-OBJCONV := convert-fcrontab.o subs.o save.o log.o u_list.o env_list.o
-OBJSIG := fcronsighup.o subs.o log.o allow.o fcronconf.o
-HEADERSALL := config.h $(SRCDIR)/global.h $(SRCDIR)/log.h $(SRCDIR)/subs.h $(SRCDIR)/save.h $(SRCDIR)/option.h $(SRCDIR)/dyncom.h
+OBJSD := fcron.o subs.o mem.o save.o temp_file.o log.o database.o job.o conf.o u_list.o exe_list.o lavg_list.o env_list.o fcronconf.o $(LIBOBJS)
+OBJSTAB := fcrontab.o subs.o mem.o save.o temp_file.o log.o fileconf.o allow.o read_string.o u_list.o env_list.o fcronconf.o
+OBJSDYN := fcrondyn.o subs.o mem.o log.o allow.o read_string.o fcronconf.o
+OBJCONV := convert-fcrontab.o subs.o mem.o save.o log.o u_list.o env_list.o
+OBJSIG := fcronsighup.o subs.o mem.o log.o allow.o fcronconf.o
+HEADERSALL := config.h $(SRCDIR)/global.h $(SRCDIR)/log.h $(SRCDIR)/subs.h $(SRCDIR)/mem.h $(SRCDIR)/save.h $(SRCDIR)/option.h $(SRCDIR)/dyncom.h
# this is a regular expression :
# do not ci automaticaly generated files and doc (done by doc's Makefile)
next = rm_list;
while( (l = next) != NULL ) {
next = l->next;
- free_safe(l->str);
- free_safe(l);
+ Free_safe(l->str);
+ Free_safe(l);
}
next = new_list;
while( (l = next) != NULL ) {
next = l->next;
- free_safe(l->str);
- free_safe(l);
+ Free_safe(l->str);
+ Free_safe(l);
}
next = file_list;
while( (l = next) != NULL ) {
next = l->next;
- free_safe(l->str);
- free_safe(l);
+ Free_safe(l->str);
+ Free_safe(l);
}
}
return OK;
err:
- if (*str)
- free_safe(*str);
+ Free_safe(*str);
return ERR;
}
}
/* get the owner's name */
/* we set cf->cf_user before for SE Linux, so we need to free it here */
- free_safe(cf->cf_user);
+ Free_safe(cf->cf_user);
if ( read_strn(fileno(ff), &cf->cf_user, size) != OK ) {
error("Cannot read user's name : file ignored");
goto err;
/* we use file owner's name for more security (see above) */
/* free the value obtained by read_strn() (we need to read it anyway
* to set the file ptr to the next thing to read) */
- free_safe(cf->cf_user);
+ Free_safe(cf->cf_user);
cf->cf_user = runas_str;
}
else {
env_list_putenv(cf->cf_env_list, envvar, 1);
}
- free_safe(envvar);
+ Free_safe(envvar);
}
break;
}
/* free last cl Alloc : unused */
- free_safe(cl);
+ Free_safe(cl);
/* check for an error */
if ( ferror(ff) != 0 )
if ( cl != NULL && cl->cl_next == NULL ) {
/* line is not yet in the line list of the file : free it */
- if ( cl->cl_shell ) free_safe(cl->cl_shell);
- if ( cl->cl_runas) free_safe(cl->cl_runas);
- if ( cl->cl_mailto) free_safe(cl->cl_mailto);
- free_safe(cl);
+ Free_safe(cl->cl_shell);
+ Free_safe(cl->cl_runas);
+ Free_safe(cl->cl_mailto);
+ Free_safe(cl);
}
/* check if we have started to read the lines and env var */
delete_file(cf->cf_user);
}
- else if (cf->cf_user != NULL)
- free_safe(cf->cf_user);
+ else {
+ Free_safe(cf->cf_user);
+ }
return ERR;
/* free a line, including its fields */
{
if (cl != NULL) {
- free_safe(cl->cl_shell);
- free_safe(cl->cl_runas);
- free_safe(cl->cl_mailto);
- free_safe(cl->cl_tz);
- free_safe(cl);
+ Free_safe(cl->cl_shell);
+ Free_safe(cl->cl_runas);
+ Free_safe(cl->cl_mailto);
+ Free_safe(cl->cl_tz);
+ Free_safe(cl);
}
}
!= NULL)
k++;
}
- free_safe(serial_array);
+ Free_safe(serial_array);
serial_array = s_a;
serial_array_index = 0;
prev_j->j_next = j->j_next;
else
queue_base = j->j_next;
- free_safe(j);
+ Free_safe(j);
break;
}
else
env_list_destroy(file->cf_env_list);
/* finally free file itself */
- free_safe(file->cf_user);
- free_safe(file);
+ Free_safe(file->cf_user);
+ Free_safe(file);
}
/* $Id: convert-fcrontab.c,v 1.23 2007-04-14 18:04:21 thib Exp $ */
#include "convert-fcrontab.h"
+#include "mem.h"
char rcs_info[] = "$Id: convert-fcrontab.c,v 1.23 2007-04-14 18:04:21 thib Exp $";
cur_line = file->cf_line_base;
while ( (line = cur_line) != NULL) {
cur_line = line->cl_next;
- free_safe(line->cl_shell);
- free_safe(line->cl_mailto);
- free_safe(line->cl_runas);
- free_safe(line);
+ Free_safe(line->cl_shell);
+ Free_safe(line->cl_mailto);
+ Free_safe(line->cl_runas);
+ Free_safe(line);
}
/* free env variables */
env_list_destroy(file->cf_env_list);
/* finally free file itself */
- free_safe(file->cf_user);
- free_safe(file);
+ Free_safe(file->cf_user);
+ Free_safe(file);
}
/* read env variables */
while( (env = read_str(f, buf, sizeof(buf))) != NULL ) {
env_list_putenv(file->cf_env_list, env, 1);
- free_safe(env);
+ Free_safe(env);
}
/* read lines */
}
- free_safe(line);
+ Free_safe(line);
fclose(f);
/* first element of the list */
queue_base = j->j_next;
- free_safe(j);
+ Free_safe(j);
return jprev;
}
}
memcpy(ptr, serial_array + (old_size - serial_array_index),
(sizeof(cl_t*) * serial_array_index));
serial_array_index = 0;
- free_safe(serial_array);
+ Free_safe(serial_array);
serial_array = ptr;
}
}
env_list_end_iteration(list);
/* free the data in the env_t entries */
for ( c = env_list_first(list) ; c != NULL ; c = env_list_next(list) ) {
- free_safe(c->e_envvar);
+ Free_safe(c->e_envvar);
}
/* free the actual list structure */
return (env_list_t *) u_list_destroy((u_list_t *) list);
char *p = NULL;
for ( p = envp[0] ; p != NULL ; p++ ) {
- free_safe(p);
+ Free_safe(p);
}
- free_safe(envp);
+ Free_safe(envp);
}
lavg_list_destroy(lavg_list);
free_conf();
- free_safe(orig_tz_envvar);
+ Free_safe(orig_tz_envvar);
explain("Exiting with code %d", exit_value);
exit (exit_value);
#define __FCRON_H__
#include "global.h"
+#include "mem.h"
#include "exe_list.h"
#include "lavg_list.h"
#include "fcronconf.h"
/* $Id: subs.c,v 1.29 2008-05-11 11:08:23 thib Exp $ */
#include "global.h"
+#include "mem.h"
#include "fcronconf.h"
#include "subs.h"
free_conf(void)
/* free() the memory allocated in init_conf() */
{
- free_safe(fcronconf);
- free_safe(fcrontabs);
- free_safe(pidfile);
- free_safe(fifofile);
- free_safe(fcronallow);
- free_safe(fcrondeny);
- free_safe(shell);
- free_safe(sendmail);
- free_safe(editor);
+ Free_safe(fcronconf);
+ Free_safe(fcrontabs);
+ Free_safe(pidfile);
+ Free_safe(fifofile);
+ Free_safe(fcronallow);
+ Free_safe(fcrondeny);
+ Free_safe(shell);
+ Free_safe(sendmail);
+ Free_safe(editor);
}
void
#include "fcrondyn.h"
#include "allow.h"
#include "read_string.h"
+#include "mem.h"
char rcs_info[] = "$Id: fcrondyn.c,v 1.19 2007-04-14 18:04:11 thib Exp $";
xexit(int exit_val)
/* clean & exit */
{
- free_safe(cmd_str);
+ Free_safe(cmd_str);
exit(exit_val);
}
send(fd, buf, len, 0);
Overwrite(buf);
Overwrite(password);
- free_safe(password);
+ Free_safe(password);
tv.tv_sec = MAX_WAIT_TIME;
tv.tv_usec = 0;
return ERR;
send(fd, cmd, cmd_len * sizeof(long int), 0);
- free_safe(cmd);
+ Free_safe(cmd);
cmd_len = 0;
tv.tv_sec = MAX_WAIT_TIME;
break;
case 'i':
- free_safe(cmd_str);
+ Free_safe(cmd_str);
break;
case 'x':
in Makefile to create .o files which needs the corresponding .h to exist. */
#include "global.h"
+#include "mem.h"
extern uid_t rootuid;
extern gid_t rootgid;
#define __FCRONTAB_H__
#include "global.h"
+#include "mem.h"
#include "fcronconf.h"
/* global variables */
e = alloc_safe(l->array_size*l->entry_size, "larger fifo_list_t array");
memcpy(e, l->entries_array, (l->entry_size * old_size));
- free_safe(l->entries_array);
+ Free_safe(l->entries_array);
l->entries_array = e;
if ( l->cur_entry != NULL )
if ( list == NULL )
die("Invalid argument for fifo_list_destroy(): list=%d", list);
- free_safe(list->entries_array);
- free_safe(list);
+ Free_safe(list->entries_array);
+ Free_safe(list);
return NULL;
}
bzero(cl, sizeof(cl_t));
Set(cl->cl_runas, runas);
Set(cl->cl_mailto, runas);
- free_safe(cl->cl_tz);
+ Free_safe(cl->cl_tz);
set_default_opt(cl->cl_option);
cl->cl_file = cf;
}
if (fflush(file) != 0)
error_e("could not fflush() file_name");
- free_safe(default_line.cl_runas);
- free_safe(default_line.cl_mailto);
- free_safe(default_line.cl_tz);
+ Free_safe(default_line.cl_runas);
+ Free_safe(default_line.cl_mailto);
+ Free_safe(default_line.cl_tz);
if ( ! need_correction )
return OK;
env_list_setenv(cf->cf_env_list, name, val, 1);
}
- free_safe(val);
+ Free_safe(val);
return;
buf[i++] = *ptr++;
if ( strcmp(buf, "\0") == 0 ) {
- free_safe(cl->cl_tz);
+ Free_safe(cl->cl_tz);
}
else {
Set(cl->cl_tz, buf);
if ( strcmp(cl->cl_shell, "\0") == 0 ) {
fprintf(stderr, "%s:%d: No shell command: skipping line.\n",
file_name, line);
- free_safe(cl->cl_shell);
+ Free_safe(cl->cl_shell);
goto exiterr;
}
return 1;
exiterr:
- free_safe(cl);
+ Free_safe(cl);
need_correction = 1;
return 1;
}
if ( strcmp(cl->cl_shell, "\0") == 0 ) {
fprintf(stderr, "%s:%d: No shell command: skipping line.\n",
file_name, line);
- free_safe(cl->cl_shell);
+ Free_safe(cl->cl_shell);
goto exiterr;
}
fprintf(stderr, "\n"); \
fprintf(stderr, "%s:%d: Error while reading " DESCRP " field: " \
"skipping line.\n", file_name, line); \
- free_safe(cl); \
+ Free_safe(cl); \
return; \
}
if ( strcmp(cl->cl_shell, "\0") == 0 ) {
fprintf(stderr, "%s:%d: No shell command: skipping line.\n",
file_name, line);
- free_safe(cl->cl_shell);
+ Free_safe(cl->cl_shell);
goto exiterr;
}
if ( strcmp(cl->cl_shell, "\0") == 0 ) {
fprintf(stderr, "%s:%d: No shell command: skipping line.\n",
file_name, line);
- free_safe(cl->cl_shell);
+ Free_safe(cl->cl_shell);
goto exiterr;
}
else if ( cl->cl_shell[0] == '*' || isdigit( (int) cl->cl_shell[0]) )
/* free a line, including its fields */
{
if (cl != NULL) {
- free_safe(cl->cl_shell);
- free_safe(cl->cl_runas);
- free_safe(cl->cl_mailto);
- free_safe(cl->cl_tz);
- free_safe(cl);
+ Free_safe(cl->cl_shell);
+ Free_safe(cl->cl_runas);
+ Free_safe(cl->cl_mailto);
+ Free_safe(cl->cl_tz);
+ Free_safe(cl);
}
}
env_list_destroy(file->cf_env_list);
/* finally free file itself */
- free_safe(file->cf_user);
- free_safe(file);
+ Free_safe(file->cf_user);
+ Free_safe(file);
}
#define setegid(arg) setresgid(-1,(arg),-1)
#endif
-#define Alloc(PTR, TYPE) \
- if( (PTR = calloc(1, sizeof(TYPE))) == NULL ) \
- die_e("Could not calloc.");
-
-#define Set(VAR, VALUE) \
- { \
- free_safe(VAR); \
- VAR = strdup2(VALUE); \
- }
-
#define Skip_blanks(PTR) \
while((*(PTR) == ' ') || (*(PTR) == '\t')) \
(PTR)++;
setup_user_and_env(cl, pas, sendmailenv, jobenv, curshell, curhome,
content_type, encoding);
become_user(cl, pas, *curhome);
- free_safe(*curhome);
+ Free_safe(*curhome);
}
void
}
become_user(line, pas, curhome);
- free_safe(curhome);
+ Free_safe(curhome);
/* restore umask to default */
umask (saved_umask);
log_console_str(msg);
log_fd_str(fd, msg);
- free_safe(msg);
+ Free_safe(msg);
}
/* Same as log_syslog(), but also appends an error description corresponding
log_syslog_str(priority, msg);
log_console_str(msg);
- free_safe(msg);
+ Free_safe(msg);
}
xcloselog();
- free_safe(msg);
+ Free_safe(msg);
}
#endif
log_fd_str(fd, msg);
- free_safe(msg);
+ Free_safe(msg);
va_end(args);
}
log_fd_str(fd, msg);
- free_safe(msg);
+ Free_safe(msg);
va_end(args);
}
--- /dev/null
+/*
+ * FCRON - periodic command scheduler
+ *
+ * Copyright 2000-2010 Thibault Godouet <fcron@free.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * The GNU General Public License can also be found in the file
+ * `LICENSE' that comes with the fcron source distribution.
+ */
+
+#include "global.h"
+#include "mem.h"
+
+char *
+strdup2(const char *str)
+{
+ char *ptr;
+
+ if ( str == NULL )
+ return NULL;
+
+ ptr = strdup(str);
+
+ if ( ! ptr)
+ die_e("Could not strdup()");
+
+ return(ptr);
+}
+
+char *
+strndup2(const char *str, size_t n)
+{
+ char *ptr;
+
+ if ( str == NULL )
+ return NULL;
+
+ ptr = strndup(str, n);
+
+ if ( ! ptr)
+ die_e("Could not strdup()");
+
+ return(ptr);
+}
+
+void *
+alloc_safe(size_t len, const char * desc)
+/* allocate len-bytes of memory, and return the pointer.
+ * Die with a log message if there is any error */
+{
+ void *ptr = NULL;
+
+ ptr = calloc(1, len);
+ if ( ptr == NULL ) {
+ die_e("Could not allocate %d bytes of memory%s%s", len, (desc)? "for " : "", desc);
+ }
+ return ptr;
+}
+
+void *
+realloc_safe(void *cur, size_t len, const char * desc)
+/* allocate len-bytes of memory, and return the pointer.
+ * Die with a log message if there is any error */
+{
+ void *new = NULL;
+
+ new = realloc(cur, len);
+ if ( new == NULL ) {
+ die_e("Could not reallocate %d bytes of memory%s%s", len, (desc)? "for " : "", desc);
+ }
+ return new;
+}
+
+
--- /dev/null
+/*
+ * FCRON - periodic command scheduler
+ *
+ * Copyright 2000-2010 Thibault Godouet <fcron@free.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * The GNU General Public License can also be found in the file
+ * `LICENSE' that comes with the fcron source distribution.
+ */
+
+/* mem: manage memory (de)allocation.
+ * Mostly wrappers around standard functions to check for errors.
+ * We also always set variable to NULL after free()ing them, and check
+ * if a variable is NULL before attempting to free it. */
+
+#ifndef __MEM_H__
+#define __MEM_H__
+
+/* macros */
+#define Alloc(PTR, TYPE) \
+{ \
+ if ( ( (PTR)=calloc(1, sizeof(TYPE)) ) == NULL ) { \
+ die_e("Could not calloc."); \
+ } \
+}
+
+#define Free_safe(PTR) \
+{ \
+ if ((PTR) != NULL) { \
+ free((PTR)); \
+ (PTR) = NULL; \
+ } \
+}
+
+#define Set(VAR, VALUE) \
+{ \
+ Free_safe((VAR)); \
+ (VAR) = strdup2((VALUE)); \
+}
+
+
+/* functions prototypes */
+extern char *strdup2(const char *);
+extern char *strndup2(const char *, size_t n);
+extern void *alloc_safe(size_t len, const char * desc);
+extern void *realloc_safe(void *ptr, size_t len, const char * desc);
+
+#endif /* __MEM_H__ */
#include "global.h"
#include "read_string.h"
#include "log.h"
+#include "mem.h"
extern char debug_opt;
debug("connection closed : fd : %d", (*client)->fcl_sock_fd);
if (prev_client == NULL ) {
fcrondyn_cl_base = (*client)->fcl_next;
- free_safe((*client)->fcl_user);
- free_safe(*client);
+ Free_safe((*client)->fcl_user);
+ Free_safe(*client);
*client = fcrondyn_cl_base;
}
else {
prev_client->fcl_next = (*client)->fcl_next;
- free_safe((*client)->fcl_user);
- free_safe(*client);
+ Free_safe((*client)->fcl_user);
+ Free_safe(*client);
*client = prev_client->fcl_next;
}
fcrondyn_cl_num -= 1;
close(client->fcl_sock_fd);
client_buf = client->fcl_next;
- free_safe(client);
+ Free_safe(client);
fcrondyn_cl_num -= 1;
client = client_buf;
}
return (*left - *right);
}
-
-char *
-strdup2(const char *str)
-{
- char *ptr;
-
- if ( str == NULL )
- return NULL;
-
- ptr = strdup(str);
-
- if ( ! ptr)
- die_e("Could not strdup()");
-
- return(ptr);
-}
-
-void *
-alloc_safe(size_t len, const char * desc)
-/* allocate len-bytes of memory, and return the pointer.
- * Die with a log message if there is any error */
-{
- void *ptr = NULL;
-
- ptr = calloc(1, len);
- if ( ptr == NULL ) {
- die_e("Could not allocate %d bytes of memory%s%s", len, (desc)? "for " : "", desc);
- }
- return ptr;
-}
-
-void *
-realloc_safe(void *cur, size_t len, const char * desc)
-/* allocate len-bytes of memory, and return the pointer.
- * Die with a log message if there is any error */
-{
- void *new = NULL;
-
- new = realloc(cur, len);
- if ( new == NULL ) {
- die_e("Could not reallocate %d bytes of memory%s%s", len, (desc)? "for " : "", desc);
- }
- return new;
-}
-
-void
-free_safe(void *ptr)
- /* free() p and set it to NULL to prevent errors if it is free()ed again */
-{
- free(ptr);
- ptr = NULL;
-}
-
int
get_word(char **str)
/* make str point the next word and return word length */
extern int remove_blanks(char *str);
extern int strcmp_until(const char *left, const char *right, char until);
-extern char *strdup2(const char *);
-extern void *alloc_safe(size_t len, const char * desc);
-extern void *realloc_safe(void *ptr, size_t len, const char * desc);
-extern void free_safe(void *ptr);
extern int get_word(char **str);
extern void my_unsetenv(const char *name);
extern void my_setenv_overwrite(const char *name, const char *value);
#include "global.h"
#include "temp_file.h"
+#include "mem.h"
extern char *tmp_path;
extern char debug_opt;
*/
#include "global.h"
+#include "mem.h"
#include "log.h"
#include "u_list.h"
if ( list == NULL )
die("Invalid argument for u_list_destroy(): list=%d", list);
- free_safe(list->entries_array);
- free_safe(list);
+ Free_safe(list->entries_array);
+ Free_safe(list);
return NULL;
}