Limit paths for command, cwd and chroot to PATH_MAX bytes.

This helps prevent the fuzzer from going off the rails.
This commit is contained in:
Todd C. Miller
2021-09-19 18:13:43 -06:00
parent 7ab66eb3a8
commit 0ea561ca6a
5 changed files with 313 additions and 279 deletions

View File

@@ -1049,6 +1049,18 @@ valid_path(struct sudo_defs_types *def, const char *val,
bool ret = true;
debug_decl(valid_path, SUDOERS_DEBUG_DEFAULTS);
if (strlen(val) >= PATH_MAX) {
if (!quiet) {
if (line > 0) {
sudo_warnx(U_("%s:%d:%d: path name for \"%s\" too long"),
file, line, column, def->name);
} else {
sudo_warnx(U_("%s: path name for \"%s\" too long"),
file, def->name);
}
}
ret = false;
}
if (ISSET(def->type, T_CHPATH)) {
if (val[0] != '/' && val[0] != '~' && (val[0] != '*' || val[1] != '\0')) {
if (!quiet) {

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
/* A Bison parser, made by GNU Bison 3.7.6. */
/* A Bison parser, made by GNU Bison 3.8.1. */
/* Bison interface for Yacc-like parsers in C
@@ -196,6 +196,8 @@ typedef union YYSTYPE YYSTYPE;
extern YYSTYPE sudoerslval;
int sudoersparse (void);
#endif /* !YY_SUDOERS_Y_TAB_H_INCLUDED */

View File

@@ -638,6 +638,10 @@ chdirspec : CWD '=' WORD {
YYERROR;
}
}
if (strlen($3) >= PATH_MAX) {
sudoerserror(N_("\"CWD\" path too long"));
YYERROR;
}
$$ = $3;
}
;
@@ -650,6 +654,10 @@ chrootspec : CHROOT '=' WORD {
YYERROR;
}
}
if (strlen($3) >= PATH_MAX) {
sudoerserror(N_("\"CHROOT\" path too long"));
YYERROR;
}
$$ = $3;
}
;
@@ -933,6 +941,10 @@ cmnd : ALL {
| COMMAND {
struct sudo_command *c;
if (strlen($1.cmnd) >= PATH_MAX) {
sudoerserror(N_("command too long"));
YYERROR;
}
if ((c = new_command($1.cmnd, $1.args)) == NULL) {
sudoerserror(N_("unable to allocate memory"));
YYERROR;

View File

@@ -202,11 +202,19 @@ sudoers_policy_deserialize_info(void *v, struct defaults_list *defaults)
if (MATCHES(*cur, "cmnd_chroot=")) {
CHECK(*cur, "cmnd_chroot=");
user_runchroot = *cur + sizeof("cmnd_chroot=") - 1;
if (strlen(user_runchroot) >= PATH_MAX) {
sudo_warnx(U_("path name for \"%s\" too long"), "cmnd_chroot");
goto bad;
}
continue;
}
if (MATCHES(*cur, "cmnd_cwd=")) {
CHECK(*cur, "cmnd_cwd=");
user_runcwd = *cur + sizeof("cmnd_cwd=") - 1;
if (strlen(user_runcwd) >= PATH_MAX) {
sudo_warnx(U_("path name for \"%s\" too long"), "cmnd_cwd");
goto bad;
}
continue;
}
if (MATCHES(*cur, "runas_user=")) {