+++ /dev/null
-Description: Build hardening: check a few more return values.
-Origin: other: http://svn.ringlet.net/svn/ringlet/mail/dma/
-Forwarded: yes
-Author: Peter Pentchev <roam@ringlet.net>
-Last-Update: 2010-06-21
-
---- a/util.c
-+++ b/util.c
-@@ -92,9 +92,9 @@
- char *sufx;
-
- va_start(ap, fmt);
-- vasprintf(&sufx, fmt, ap);
-- if (sufx != NULL) {
-- asprintf(&tag, "%s[%s]", logident_base, sufx);
-+ if (vasprintf(&sufx, fmt, ap) != -1 && sufx != NULL) {
-+ if (asprintf(&tag, "%s[%s]", logident_base, sufx) == -1)
-+ tag = NULL;
- free(sufx);
- }
- va_end(ap);
-@@ -112,7 +112,8 @@
-
- if (fmt != NULL) {
- va_start(ap, fmt);
-- vasprintf(&outs, fmt, ap);
-+ if (vasprintf(&outs, fmt, ap) == -1)
-+ outs = NULL;
- va_end(ap);
- }
-
-@@ -135,7 +136,8 @@
-
- if (fmt != NULL) {
- va_start(ap, fmt);
-- vasprintf(&outs, fmt, ap);
-+ if (vasprintf(&outs, fmt, ap) == -1)
-+ outs = NULL;
- va_end(ap);
- }
-
-@@ -189,8 +191,8 @@
- else
- free(u);
- }
-- asprintf(__DECONST(void *, &username), "%ld", (long)uid);
-- if (username != NULL)
-+ if (asprintf(__DECONST(void *, &username), "%ld", (long)uid) != -1 &&
-+ username != NULL)
- return;
- username = "unknown-or-invalid-username";
- }
struct aliases aliases = LIST_HEAD_INITIALIZER(aliases);
struct strlist tmpfs = SLIST_HEAD_INITIALIZER(tmpfs);
struct authusers authusers = LIST_HEAD_INITIALIZER(authusers);
-const char *username;
+char username[USERNAME_SIZE];
const char *logident_base;
+char errmsg[ERRMSG_SIZE];
static int daemonize = 1;
{
int error;
unsigned int backoff = MIN_RETRY;
- const char *errmsg = "unknown bounce reason";
struct timeval now;
struct stat st;
+ snprintf(errmsg, sizeof(errmsg), "unknown bounce reason");
+
retry:
syslog(LOG_INFO, "trying delivery");
if (it->remote)
- error = deliver_remote(it, &errmsg);
+ error = deliver_remote(it);
else
- error = deliver_local(it, &errmsg);
+ error = deliver_local(it);
switch (error) {
case 0:
}
if (gettimeofday(&now, NULL) == 0 &&
(now.tv_sec - st.st_mtim.tv_sec > MAX_TIMEOUT)) {
- asprintf(__DECONST(void *, &errmsg),
+ snprintf(errmsg, sizeof(errmsg),
"Could not deliver for the last %d seconds. Giving up.",
MAX_TIMEOUT);
goto bounce;
#define VERSION "DragonFly Mail Agent " DMA_VERSION
#define BUF_SIZE 2048
+#define ERRMSG_SIZE 200
+#define USERNAME_SIZE 50
#define MIN_RETRY 300 /* 5 minutes */
#define MAX_RETRY (3*60*60) /* retry at least every 3 hours */
#define MAX_TIMEOUT (5*24*60*60) /* give up after 5 days */
extern struct config config;
extern struct strlist tmpfs;
extern struct authusers authusers;
-extern const char *username;
+extern char username[USERNAME_SIZE];
extern const char *logident_base;
-extern char neterr[BUF_SIZE];
+extern char neterr[ERRMSG_SIZE];
+extern char errmsg[ERRMSG_SIZE];
/* aliases_parse.y */
int yyparse(void);
char *ssl_errstr(void);
int read_remote(int, int, char *);
ssize_t send_remote_command(int, const char*, ...);
-int deliver_remote(struct qitem *, const char **);
+int deliver_remote(struct qitem *);
/* base64.c */
int base64_encode(const void *, int, char **);
void dropspool(struct queue *, struct qitem *);
/* local.c */
-int deliver_local(struct qitem *, const char **errmsg);
+int deliver_local(struct qitem *);
/* mail.c */
void bounce(struct qitem *, const char *);
#include "dma.h"
int
-deliver_local(struct qitem *it, const char **errmsg)
+deliver_local(struct qitem *it)
{
char fn[PATH_MAX+1];
char line[1000];
linelen = strlen(line);
if (linelen == 0 || line[linelen - 1] != '\n') {
syslog(LOG_CRIT, "local delivery failed: corrupted queue file");
- *errmsg = "corrupted queue file";
+ snprintf(errmsg, sizeof(errmsg), "corrupted queue file");
error = -1;
goto chop;
}
#include "dma.h"
-char neterr[BUF_SIZE];
+char neterr[ERRMSG_SIZE];
char *
ssl_errstr(void)
}
static int
-deliver_to_host(struct qitem *it, struct mx_hostentry *host, void *errmsgc)
+deliver_to_host(struct qitem *it, struct mx_hostentry *host)
{
struct authuser *a;
char line[1000];
int fd, error = 0, do_auth = 0, res = 0;
if (fseek(it->mailf, 0, SEEK_SET) != 0) {
- asprintf(errmsgc, "can not seek: %s", strerror(errno));
+ snprintf(errmsg, sizeof(errmsg), "can not seek: %s", strerror(errno));
return (-1);
}
if (res == 5) { \
syslog(LOG_ERR, "remote delivery to %s [%s] failed after %s: %s", \
host->host, host->addr, c, neterr); \
- asprintf(errmsgc, "%s [%s] did not like our %s:\n%s", \
+ snprintf(errmsg, sizeof(errmsg), "%s [%s] did not like our %s:\n%s", \
host->host, host->addr, c, neterr); \
return (-1); \
} else if (res != exp) { \
if (error < 0) {
syslog(LOG_ERR, "remote delivery failed:"
" SMTP login failed: %m");
- asprintf(errmsgc, "SMTP login to %s failed", host->host);
+ snprintf(errmsg, sizeof(errmsg), "SMTP login to %s failed", host->host);
return (-1);
}
/* SMTP login is not available, so try without */
linelen = strlen(line);
if (linelen == 0 || line[linelen - 1] != '\n') {
syslog(LOG_CRIT, "remote delivery failed: corrupted queue file");
- *(const char **)errmsgc = "corrupted queue file";
+ snprintf(errmsg, sizeof(errmsg), "corrupted queue file");
error = -1;
goto out;
}
}
int
-deliver_remote(struct qitem *it, const char **errmsg)
+deliver_remote(struct qitem *it)
{
- /* asprintf can't take const */
- void *errmsgc = __DECONST(char **, errmsg);
struct mx_hostentry *hosts, *h;
const char *host;
int port;
host = strrchr(it->addr, '@');
/* Should not happen */
if (host == NULL) {
- asprintf(errmsgc, "Internal error: badly formed address %s",
+ snprintf(errmsg, sizeof(errmsg), "Internal error: badly formed address %s",
it->addr);
return(-1);
} else {
}
for (h = hosts; *h->host != 0; h++) {
- switch (deliver_to_host(it, h, errmsgc)) {
+ switch (deliver_to_host(it, h)) {
case 0:
/* success */
error = 0;
void
setlogident(const char *fmt, ...)
{
- char *tag = NULL;
+ char tag[50];
+ snprintf(tag, sizeof(tag), "%s", logident_base);
if (fmt != NULL) {
va_list ap;
- char *sufx;
+ char sufx[50];
va_start(ap, fmt);
- if (vasprintf(&sufx, fmt, ap) != -1 && sufx != NULL) {
- if (asprintf(&tag, "%s[%s]", logident_base, sufx) == -1)
- tag = NULL;
- free(sufx);
- }
+ vsnprintf(sufx, sizeof(sufx), fmt, ap);
va_end(ap);
+ snprintf(tag, sizeof(tag), "%s[%s]", logident_base, sufx);
}
closelog();
- openlog(tag != NULL ? tag : logident_base, 0, LOG_MAIL);
+ openlog(tag, 0, LOG_MAIL);
}
void
{
int oerrno = errno;
va_list ap;
- char *outs = NULL;
+ char outs[ERRMSG_SIZE];
+ outs[0] = 0;
if (fmt != NULL) {
va_start(ap, fmt);
- if (vasprintf(&outs, fmt, ap) == -1)
- outs = NULL;
+ vsnprintf(outs, sizeof(outs), fmt, ap);
va_end(ap);
}
- if (outs != NULL) {
+ if (*outs != 0) {
syslog(LOG_ERR, "%s: %m", outs);
fprintf(stderr, "%s: %s: %s\n", getprogname(), outs, strerror(oerrno));
} else {
errlogx(int exitcode, const char *fmt, ...)
{
va_list ap;
- char *outs = NULL;
+ char outs[ERRMSG_SIZE];
+ outs[0] = 0;
if (fmt != NULL) {
va_start(ap, fmt);
- if (vasprintf(&outs, fmt, ap) == -1)
- outs = NULL;
+ vsnprintf(outs, sizeof(outs), fmt, ap);
va_end(ap);
}
- if (outs != NULL) {
+ if (*outs != 0) {
syslog(LOG_ERR, "%s", outs);
fprintf(stderr, "%s: %s\n", getprogname(), outs);
} else {
exit(exitcode);
}
-static const char *
+static int
check_username(const char *name, uid_t ckuid)
{
struct passwd *pwd;
if (name == NULL)
- return (NULL);
+ return (0);
pwd = getpwnam(name);
if (pwd == NULL || pwd->pw_uid != ckuid)
- return (NULL);
- return (name);
+ return (0);
+ snprintf(username, sizeof(username), "%s", name);
+ return (1);
}
void
set_username(void)
{
struct passwd *pwd;
- char *u = NULL;
uid_t uid;
uid = getuid();
- username = check_username(getlogin(), uid);
- if (username != NULL)
+ if (check_username(getlogin(), uid))
return;
- username = check_username(getenv("LOGNAME"), uid);
- if (username != NULL)
+ if (check_username(getenv("LOGNAME"), uid))
return;
- username = check_username(getenv("USER"), uid);
- if (username != NULL)
+ if (check_username(getenv("USER"), uid))
return;
pwd = getpwuid(uid);
- if (pwd != NULL && pwd->pw_name != NULL && pwd->pw_name[0] != '\0' &&
- (u = strdup(pwd->pw_name)) != NULL) {
- username = check_username(u, uid);
- if (username != NULL)
+ if (pwd != NULL && pwd->pw_name != NULL && pwd->pw_name[0] != '\0') {
+ if (check_username(pwd->pw_name, uid))
return;
- else
- free(u);
}
- if (asprintf(__DECONST(void *, &username), "%ld", (long)uid) != -1 &&
- username != NULL)
- return;
- username = "unknown-or-invalid-username";
+ snprintf(username, sizeof(username), "uid=%ld", (long)uid);
}
void