Prevent buffer overflow in format_cmd() by properly tracking maximum

buffer size.
Reported by:	Lionnel CHAPTAL <Lionnel.Chaptal@IPricot.com>
MFC after:	1 week
This commit is contained in:
Jordan K. Hubbard 2003-01-06 07:39:02 +00:00
parent 3fc473df24
commit 12ebd46e4b
4 changed files with 24 additions and 16 deletions

View file

@ -223,7 +223,7 @@ extract_plist(const char *home, Package *pkg)
errx(2, "%s: no directory specified for '%s' command",
__func__, p->name);
}
format_cmd(cmd, p->name, Directory, last_file);
format_cmd(cmd, FILENAME_MAX, p->name, Directory, last_file);
PUSHOUT(Directory);
if (Verbose)
printf("extract: execute '%s'\n", cmd);

View file

@ -370,50 +370,58 @@ unpack(const char *pkg, const char *flist)
*
*/
void
format_cmd(char *buf, const char *fmt, const char *dir, const char *name)
format_cmd(char *buf, int max, const char *fmt, const char *dir, const char *name)
{
char *cp, scratch[FILENAME_MAX * 2];
int l;
while (*fmt) {
while (*fmt && max > 0) {
if (*fmt == '%') {
switch (*++fmt) {
case 'F':
strcpy(buf, name);
buf += strlen(name);
strncpy(buf, name, max);
l = strlen(name);
buf += l, max -= l;
break;
case 'D':
strcpy(buf, dir);
buf += strlen(dir);
strncpy(buf, dir, max);
l = strlen(dir);
buf += l, max -= l;
break;
case 'B':
sprintf(scratch, "%s/%s", dir, name);
snprintf(scratch, FILENAME_MAX * 2, "%s/%s", dir, name);
cp = &scratch[strlen(scratch) - 1];
while (cp != scratch && *cp != '/')
--cp;
*cp = '\0';
strcpy(buf, scratch);
buf += strlen(scratch);
strncpy(buf, scratch, max);
l = strlen(scratch);
buf += l, max -= l;
break;
case 'f':
sprintf(scratch, "%s/%s", dir, name);
snprintf(scratch, FILENAME_MAX * 2, "%s/%s", dir, name);
cp = &scratch[strlen(scratch) - 1];
while (cp != scratch && *(cp - 1) != '/')
--cp;
strcpy(buf, cp);
buf += strlen(cp);
strncpy(buf, cp, max);
l = strlen(cp);
buf += l, max -= l;
break;
default:
*buf++ = *fmt;
--max;
break;
}
++fmt;
}
else
else {
*buf++ = *fmt++;
--max;
}
}
*buf = '\0';
}

View file

@ -171,7 +171,7 @@ void move_file(const char *, const char *, const char *);
void copy_hierarchy(const char *, const char *, Boolean);
int delete_hierarchy(const char *, Boolean, Boolean);
int unpack(const char *, const char *);
void format_cmd(char *, const char *, const char *, const char *);
void format_cmd(char *, int, const char *, const char *, const char *);
/* Msg */
void upchuck(const char *);

View file

@ -427,7 +427,7 @@ delete_package(Boolean ign_err, Boolean nukedirs, Package *pkg)
break;
case PLIST_UNEXEC:
format_cmd(tmp, p->name, Where, last_file);
format_cmd(tmp, FILENAME_MAX, p->name, Where, last_file);
if (Verbose)
printf("Execute '%s'\n", tmp);
if (!Fake && system(tmp)) {