Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
mailsplit: make PATH_MAX buffers dynamic
There are several PATH_MAX-sized buffers in mailsplit, along
with some questionable uses of sprintf.  These are not
really of security interest, as local mailsplit pathnames
are not typically under control of an attacker, and you
could generally only overflow a few numbers at the end of a
path that approaches PATH_MAX (a longer path would choke
mailsplit long before). But it does not hurt to be careful,
and as a bonus we lift some limits for systems with
too-small PATH_MAX varibles.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Jeff King authored and Junio C Hamano committed Sep 25, 2015
1 parent c1fd080 commit 1d895f1
Showing 1 changed file with 23 additions and 11 deletions.
34 changes: 23 additions & 11 deletions builtin/mailsplit.c
Expand Up @@ -98,30 +98,37 @@ static int populate_maildir_list(struct string_list *list, const char *path)
{
DIR *dir;
struct dirent *dent;
char name[PATH_MAX];
char *name = NULL;
char *subs[] = { "cur", "new", NULL };
char **sub;
int ret = -1;

for (sub = subs; *sub; ++sub) {
snprintf(name, sizeof(name), "%s/%s", path, *sub);
free(name);
name = xstrfmt("%s/%s", path, *sub);
if ((dir = opendir(name)) == NULL) {
if (errno == ENOENT)
continue;
error("cannot opendir %s (%s)", name, strerror(errno));
return -1;
goto out;
}

while ((dent = readdir(dir)) != NULL) {
if (dent->d_name[0] == '.')
continue;
snprintf(name, sizeof(name), "%s/%s", *sub, dent->d_name);
free(name);
name = xstrfmt("%s/%s", *sub, dent->d_name);
string_list_insert(list, name);
}

closedir(dir);
}

return 0;
ret = 0;

out:
free(name);
return ret;
}

static int maildir_filename_cmp(const char *a, const char *b)
Expand All @@ -148,8 +155,7 @@ static int maildir_filename_cmp(const char *a, const char *b)
static int split_maildir(const char *maildir, const char *dir,
int nr_prec, int skip)
{
char file[PATH_MAX];
char name[PATH_MAX];
char *file = NULL;
FILE *f = NULL;
int ret = -1;
int i;
Expand All @@ -161,7 +167,11 @@ static int split_maildir(const char *maildir, const char *dir,
goto out;

for (i = 0; i < list.nr; i++) {
snprintf(file, sizeof(file), "%s/%s", maildir, list.items[i].string);
char *name;

free(file);
file = xstrfmt("%s/%s", maildir, list.items[i].string);

f = fopen(file, "r");
if (!f) {
error("cannot open mail %s (%s)", file, strerror(errno));
Expand All @@ -173,8 +183,9 @@ static int split_maildir(const char *maildir, const char *dir,
goto out;
}

sprintf(name, "%s/%0*d", dir, nr_prec, ++skip);
name = xstrfmt("%s/%0*d", dir, nr_prec, ++skip);
split_one(f, name, 1);
free(name);

fclose(f);
f = NULL;
Expand All @@ -184,14 +195,14 @@ static int split_maildir(const char *maildir, const char *dir,
out:
if (f)
fclose(f);
free(file);
string_list_clear(&list, 1);
return ret;
}

static int split_mbox(const char *file, const char *dir, int allow_bare,
int nr_prec, int skip)
{
char name[PATH_MAX];
int ret = -1;
int peek;

Expand All @@ -218,8 +229,9 @@ static int split_mbox(const char *file, const char *dir, int allow_bare,
}

while (!file_done) {
sprintf(name, "%s/%0*d", dir, nr_prec, ++skip);
char *name = xstrfmt("%s/%0*d", dir, nr_prec, ++skip);
file_done = split_one(f, name, allow_bare);
free(name);
}

if (f != stdin)
Expand Down

0 comments on commit 1d895f1

Please sign in to comment.