tftpd: make it possible to adjust the remap deadman

Allow the user to tweak the remap deadman counter if it is necessary
for whatever reason.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
H. Peter Anvin 2024-06-10 20:36:22 -07:00
parent ac7f98e4d8
commit 9a92dec1dc
4 changed files with 27 additions and 4 deletions

View file

@ -39,6 +39,8 @@
#define RULE_WRQ 0x400 /* Put (write) only */ #define RULE_WRQ 0x400 /* Put (write) only */
#define RULE_SEDG 0x800 /* sed-style global */ #define RULE_SEDG 0x800 /* sed-style global */
int deadman_max_steps = DEADMAN_MAX_STEPS;
struct rule { struct rule {
struct rule *next; struct rule *next;
int nrule; int nrule;
@ -397,7 +399,7 @@ char *rewrite_string(const struct formats *pf,
int i; int i;
int len, newlen; int len, newlen;
int was_match = 0; int was_match = 0;
int deadman = DEADMAN_MAX_STEPS; int deadman = deadman_max_steps;
int matchsense; int matchsense;
int pmatches; int pmatches;
unsigned int bad_flags; unsigned int bad_flags;
@ -534,9 +536,9 @@ char *rewrite_string(const struct formats *pf,
return current; return current;
dead: /* Deadman expired */ dead: /* Deadman expired */
syslog(LOG_WARNING, syslog(LOG_ERR,
"remap: Breaking loop, input = %s, last = %s", input, "remap: Breaking loop after %d steps, input = %s, last = %s",
current); deadman_max_steps, input, current);
free(current); free(current);
return NULL; /* Did not terminate! */ return NULL; /* Did not terminate! */
} }

View file

@ -40,5 +40,8 @@ char *rewrite_string(const struct formats *, const char *,
const struct rule *, int, int, const struct rule *, int, int,
match_pattern_callback, const char **); match_pattern_callback, const char **);
/* Remapping deadman counter */
extern int deadman_max_steps;
#endif /* WITH_REGEX */ #endif /* WITH_REGEX */
#endif /* TFTPD_REMAP_H */ #endif /* TFTPD_REMAP_H */

View file

@ -163,6 +163,10 @@ remapping below. This option may not be compiled in, see the output of
.B "in.tftpd \-V" .B "in.tftpd \-V"
to verify whether or not it is available. to verify whether or not it is available.
.TP .TP
.\fB\-\-map-steps\fP \fIsteps\fP
Specify the number of remapping rules that may be executed before the
filename mapping fails. The default is 4096.
.TP
\fB\-\-verbose\fP, \fB\-v\fP \fB\-\-verbose\fP, \fB\-v\fP
Increase the logging verbosity of Increase the logging verbosity of
.BR tftpd . .BR tftpd .

View file

@ -325,6 +325,7 @@ static int split_port(char **ap, char **pp)
enum long_only_options { enum long_only_options {
OPT_VERBOSITY = 256, OPT_VERBOSITY = 256,
OPT_MAP_STEPS
}; };
static struct option long_options[] = { static struct option long_options[] = {
@ -347,6 +348,7 @@ static struct option long_options[] = {
{ "retransmit", 1, NULL, 'T' }, { "retransmit", 1, NULL, 'T' },
{ "port-range", 1, NULL, 'R' }, { "port-range", 1, NULL, 'R' },
{ "map-file", 1, NULL, 'm' }, { "map-file", 1, NULL, 'm' },
{ "map-steps", 1, NULL, OPT_MAP_STEPS },
{ "pidfile", 1, NULL, 'P' }, { "pidfile", 1, NULL, 'P' },
{ NULL, 0, NULL, 0 } { NULL, 0, NULL, 0 }
}; };
@ -495,6 +497,18 @@ int main(int argc, char **argv)
} }
rewrite_file = optarg; rewrite_file = optarg;
break; break;
case OPT_MAP_STEPS:
{
char *ep;
unsigned long steps = strtoul(optarg, &ep, 0);
if (*optarg && *ep && steps > 0 && steps <= INT_MAX) {
deadman_max_steps = steps;
} else {
syslog(LOG_ERR, "Bad --map-steps option: %s", optarg);
exit(EX_USAGE);
}
break;
}
#endif #endif
case 'v': case 'v':
verbosity++; verbosity++;