This commit fixes couple corner case buffer overflows at few locations
where earlier a hostname[MAXHOSTNAMELEN] array had been defined exactly
to maximum lenght of a hostname. If a host is using maxium hostname
length the string will not be null terminated.
Reference:
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=blob;f=ker...
Signed-off-by: Sami Kerola <kerolasa(a)iki.fi>
---
anacron/runjob.c | 8 ++++----
src/crontab.c | 25 +++++++++++++++----------
src/database.c | 10 +++++++---
src/do_command.c | 6 ++++--
4 files changed, 30 insertions(+), 19 deletions(-)
diff --git a/anacron/runjob.c b/anacron/runjob.c
index 18e16d7..8f72412 100644
--- a/anacron/runjob.c
+++ b/anacron/runjob.c
@@ -36,6 +36,7 @@
#include "global.h"
#include <langinfo.h>
+#include "cronie_common.h"
static int
temp_file(job_rec *jr)
@@ -236,13 +237,11 @@ launch_job(job_rec *jr)
{
pid_t pid;
int fd;
- char hostname[512];
+ char *hostname;
char *mailto;
/* get hostname */
- if (gethostname(hostname, 512)) {
- strcpy (hostname,"unknown machine");
- }
+ hostname = xgethostname();
setup_env(jr);
@@ -276,6 +275,7 @@ launch_job(job_rec *jr)
xwrite(fd, "' on ");
xwrite(fd, hostname);
xwrite(fd, "\n\n");
+ free(hostname);
jr->mail_header_size = file_size(fd);
diff --git a/src/crontab.c b/src/crontab.c
index 5703a3b..7a4f4a3 100644
--- a/src/crontab.c
+++ b/src/crontab.c
@@ -91,7 +91,7 @@ static char *selinux_context = 0;
static PID_T Pid;
static char User[MAX_UNAME], RealUser[MAX_UNAME];
static char Filename[MAX_FNAME], TempFilename[MAX_FNAME];
-static char Host[MAXHOSTNAMELEN];
+static char *Host;
static FILE *NewCrontab;
static int CheckErrorCount;
static int PromptOnDelete;
@@ -327,9 +327,13 @@ static void parse_args(int argc, char *argv[]) {
if (Option == opt_hostset && argv[optind] != NULL) {
HostSpecified = 1;
- if (strlen(argv[optind]) >= sizeof Host)
+ if (get_hostname_max() < strlen(argv[optind]))
usage("hostname too long");
- (void) strcpy(Host, argv[optind]);
+ Host = strdup(argv[optind]);
+ if (Host == NULL) {
+ fprintf(stderr, "host argument strdup failed\n");
+ exit(ERROR_EXIT);
+ }
optind++;
}
@@ -455,10 +459,7 @@ static char *host_specific_filename(const char *filename, int
prefix)
*/
static char safename[MAX_FNAME];
- char hostname[MAXHOSTNAMELEN];
-
- if (gethostname(hostname, sizeof hostname) != 0)
- return NULL;
+ char *hostname = xgethostname();
if (prefix) {
if (!glue_strings(safename, sizeof safename, hostname, filename, '.'))
@@ -909,7 +910,7 @@ static int hostset_cmd(void) {
char *safename;
if (!HostSpecified)
- gethostname(Host, sizeof Host);
+ Host = xgethostname();
safename = host_specific_filename("tmp.XXXXXXXXXX", 1);
if (!safename || !glue_strings(TempFilename, sizeof TempFilename, SPOOL_DIR,
@@ -967,6 +968,7 @@ static int hostset_cmd(void) {
(void) unlink(TempFilename);
TempFilename[0] = '\0';
}
+ free(Host);
return (error);
}
@@ -984,12 +986,14 @@ static int hostget_cmd(void) {
fprintf(stderr, "File %s not found\n", n);
else
perror(n);
- return (-2);
+ return (-2);
}
- if (get_string(Host, sizeof Host, f, "\n") == EOF) {
+ Host = alloc_hostname_array();
+ if (get_string(Host, get_hostname_max() + 1, f, "\n") == EOF) {
fprintf(stderr, "Error reading from %s\n", n);
fclose(f);
+ free(Host);
return (-2);
}
@@ -999,6 +1003,7 @@ static int hostget_cmd(void) {
fflush(stdout);
log_it(RealUser, Pid, "GET HOST", Host, 0);
+ free(Host);
return (0);
}
diff --git a/src/database.c b/src/database.c
index 61764d7..30d0f00 100644
--- a/src/database.c
+++ b/src/database.c
@@ -43,6 +43,7 @@
# include <sys/inotify.h>
#endif
+#include "cronie_common.h"
#include "funcs.h"
#include "globals.h"
#include "pathnames.h"
@@ -255,7 +256,7 @@ cluster_host_is_local(void)
char filename[MAXNAMLEN+1];
int is_local;
FILE *f;
- char hostname[MAXHOSTNAMELEN], myhostname[MAXHOSTNAMELEN];
+ char *hostname, *myhostname;
if (!EnableClustering)
return (1);
@@ -275,14 +276,17 @@ cluster_host_is_local(void)
is_local = 0;
if (glue_strings(filename, sizeof filename, SPOOL_DIR, CRON_HOSTNAME, '/')) {
if ((f = fopen(filename, "r"))) {
+ hostname = alloc_hostname_array();
+ myhostname = xgethostname();
- if (EOF != get_string(hostname, MAXHOSTNAMELEN, f, "\n") &&
- gethostname(myhostname, MAXHOSTNAMELEN) == 0) {
+ if (EOF != get_string(hostname, get_hostname_max() + 1, f, "\n")) {
is_local = (strcmp(myhostname, hostname) == 0);
} else {
Debug(DLOAD, ("cluster: hostname comparison error\n"));
}
+ free(hostname);
+ free(myhostname);
fclose(f);
} else {
Debug(DLOAD, ("cluster: file %s not found\n", filename));
diff --git a/src/do_command.c b/src/do_command.c
index cb3d9e9..45330a8 100644
--- a/src/do_command.c
+++ b/src/do_command.c
@@ -31,6 +31,7 @@
#include <sys/wait.h>
#include <unistd.h>
+#include "cronie_common.h"
#include "externs.h"
#include "funcs.h"
#include "globals.h"
@@ -413,12 +414,12 @@ static int child_process(entry * e, char **jobenv) {
&& strncmp(MailCmd,"off",4) && !SyslogOutput) {
char **env;
char mailcmd[MAX_COMMAND];
- char hostname[MAXHOSTNAMELEN];
+ char *hostname;
char *content_type = env_get("CONTENT_TYPE", jobenv),
*content_transfer_encoding =
env_get("CONTENT_TRANSFER_ENCODING", jobenv);
- gethostname(hostname, MAXHOSTNAMELEN);
+ hostname = xgethostname();
if (MailCmd[0] == '\0') {
if (snprintf(mailcmd, sizeof mailcmd, MAILFMT, MAILARG, mailfrom)
@@ -439,6 +440,7 @@ static int child_process(entry * e, char **jobenv) {
fprintf(mail, "To: %s\n", mailto);
fprintf(mail, "Subject: Cron <%s@%s> %s\n",
usernm, first_word(hostname, "."), e->cmd);
+ free(hostname);
#ifdef MAIL_DATE
fprintf(mail, "Date: %s\n", arpadate(&StartTime));
--
1.8.1.1