Skip to content

Commit

Permalink
Functions: limit number of exections
Browse files Browse the repository at this point in the history
Reduce the likelihood of users being able to run functions which
infinitel loop.

Fixes #642
  • Loading branch information
domivogt authored and ThomasAdam committed Nov 22, 2021
1 parent 114b2ab commit e8a20b2
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 27 deletions.
9 changes: 3 additions & 6 deletions fvwm/functable_complex.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,9 @@ FvwmFunction *NewFvwmFunction(const char *name)
{
FvwmFunction *tmp;

tmp = fxmalloc(sizeof *tmp);
tmp = fxcalloc(1, sizeof *tmp);
tmp->next_func = Scr.functions;
tmp->first_item = NULL;
tmp->last_item = NULL;
tmp->name = stripcpy(name);
tmp->use_depth = 0;
Scr.functions = tmp;

return tmp;
Expand All @@ -74,8 +71,8 @@ void DestroyFunction(FvwmFunction *func)
if (func->use_depth != 0)
{
fvwm_debug(
"Function %s is in use (depth %d)", func->name,
func->use_depth);
__func__, "Function is in use (depth %d): '%s'",
func->use_depth, func->name);
return;
}

Expand Down
1 change: 1 addition & 0 deletions fvwm/functable_complex.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ typedef struct FvwmFunction
FunctionItem *last_item; /* last item in function */
char *name; /* function name */
int use_depth;
int num_items;
} FvwmFunction;

/* Types of events for the FUNCTION builtin */
Expand Down
57 changes: 39 additions & 18 deletions fvwm/functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -826,13 +826,17 @@ static void __run_complex_function_items(
cond_rc_t *cond_rc, char cond, FvwmFunction *func,
const exec_context_t *exc, cmdparser_context_t *caller_pc,
char *all_pos_args_string, char *pos_arg_tokens[],
Bool has_ref_window_moved)
int *run_item_count, Bool has_ref_window_moved)
{
char c;
FunctionItem *fi;
int x0, y0, x, y;
extern Window PressedW;

if (*run_item_count >= MAX_FUNCTION_ITEMS_RUN)
{
return;
}
if (!(!has_ref_window_moved && PressedW && XTranslateCoordinates(
dpy, PressedW , Scr.Root, 0, 0, &x0, &y0,
&JunkChild)))
Expand All @@ -850,6 +854,11 @@ static void __run_complex_function_items(
}
if (c == cond)
{
if (*run_item_count >= MAX_FUNCTION_ITEMS_RUN)
{
return;
}
(*run_item_count)++;
__execute_command_line(
cond_rc, exc, fi->action, caller_pc,
FUNC_DONT_DEFER, all_pos_args_string,
Expand All @@ -869,8 +878,8 @@ static void __run_complex_function_items(
}

static void __cf_cleanup(
FvwmFunction *func, int *depth, char *all_pos_args_string,
char **pos_arg_tokens, cond_rc_t *cond_rc)
FvwmFunction *func, int *depth, int *run_item_count,
char *all_pos_args_string, char **pos_arg_tokens, cond_rc_t *cond_rc)
{
int i;

Expand All @@ -879,9 +888,10 @@ static void __cf_cleanup(
assert(*depth > 0);
}
(*depth)--;
if (!(*depth))
if (*depth == 0)
{
Scr.flags.is_executing_complex_function = 0;
*run_item_count = 0;
}
if (all_pos_args_string != NULL)
{
Expand Down Expand Up @@ -926,6 +936,7 @@ static void execute_complex_function(
int x, y ,i;
XEvent d;
static int depth = 0;
static int run_item_count = 0;
const exec_context_t *exc2;
exec_context_changes_t ecc;
exec_context_change_mask_t mask;
Expand All @@ -937,6 +948,10 @@ static void execute_complex_function(
{
assert(func != NULL);
}
if (run_item_count >= MAX_FUNCTION_ITEMS_RUN)
{
return;
}
if (cond_rc == NULL)
{
condrc_init(&tmp_rc);
Expand Down Expand Up @@ -1039,7 +1054,7 @@ static void execute_complex_function(
exc2 = exc_clone_context(exc, &ecc, mask);
__run_complex_function_items(
cond_rc, CF_IMMEDIATE, func, exc2, pc,
all_pos_args_string, pos_arg_tokens,
all_pos_args_string, pos_arg_tokens, &run_item_count,
has_ref_window_moved);
exc_destroy_context(exc2);
}
Expand Down Expand Up @@ -1120,7 +1135,7 @@ static void execute_complex_function(
exc2 = exc_clone_context(exc, &ecc, mask);
__run_complex_function_items(
cond_rc, CF_LATE_IMMEDIATE, func, exc2, pc,
all_pos_args_string, pos_arg_tokens,
all_pos_args_string, pos_arg_tokens, &run_item_count,
has_ref_window_moved);
exc_destroy_context(exc2);
do_run_late_immediate = 0;
Expand Down Expand Up @@ -1190,17 +1205,19 @@ static void execute_complex_function(
{
__run_complex_function_items(
cond_rc, CF_LATE_IMMEDIATE, func, exc2, pc,
all_pos_args_string, pos_arg_tokens,
all_pos_args_string, pos_arg_tokens, &run_item_count,
has_ref_window_moved);
}
__run_complex_function_items(
cond_rc, type, func, exc2, pc, all_pos_args_string,
pos_arg_tokens, has_ref_window_moved);
pos_arg_tokens, &run_item_count, has_ref_window_moved);
exc_destroy_context(exc2);

ungrab_exit:
func->use_depth--;
__cf_cleanup(
func, &depth, all_pos_args_string, pos_arg_tokens, cond_rc);
func, &depth, &run_item_count, all_pos_args_string,
pos_arg_tokens, cond_rc);
if (do_ungrab)
{
UngrabEm(GRAB_NORMAL);
Expand Down Expand Up @@ -1341,9 +1358,18 @@ void AddToFunction(FvwmFunction *func, char *action)
char *token = NULL;
char condition;

if (func->num_items >= MAX_FUNCTION_ITEMS)
{
fvwm_debug(
__func__, "Function too big: '%s' (%d)", func->name,
func->num_items);
return;
}
token = PeekToken(action, &action);
if (!token)
if (!token || ! action)
{
return;
}
condition = token[0];
if (isupper(condition))
condition = tolower(condition);
Expand All @@ -1354,9 +1380,7 @@ void AddToFunction(FvwmFunction *func, char *action)
condition != CF_CLICK &&
condition != CF_DOUBLE_CLICK)
{
fvwm_debug(__func__,
"Got '%s' instead of a valid function specifier",
token);
fvwm_debug(__func__, "Invalid function specifier: '%s'", token);
return;
}
if (token[0] != 0 && token[1] != 0 &&
Expand All @@ -1368,10 +1392,6 @@ void AddToFunction(FvwmFunction *func, char *action)
" error in the configuration file. Using %c as the"
" specifier.", token, token[0]);
}
if (!action)
{
return;
}
while (isspace(*action))
{
action++;
Expand All @@ -1381,6 +1401,7 @@ void AddToFunction(FvwmFunction *func, char *action)
return;
}

/* create the new item */
tmp = fxmalloc(sizeof *tmp);
tmp->next_item = NULL;
tmp->func = func;
Expand All @@ -1394,11 +1415,11 @@ void AddToFunction(FvwmFunction *func, char *action)
func->last_item->next_item = tmp;
func->last_item = tmp;
}

tmp->condition = condition;
tmp->action = stripcpy(action);

find_func_t(tmp->action, NULL, &(tmp->flags));
func->num_items++;

return;
}
Expand Down
1 change: 0 additions & 1 deletion fvwm/functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ typedef enum
FUNC_OBSOLETE = 0,
FUNC_DEPRECATED = 0,
/* command grouping (used only for building the documentation) */
/*!!!*/
FG_BINDING = 0,
FG_MODULE = 0,
FG_MENU = 0,
Expand Down
9 changes: 7 additions & 2 deletions libs/defaults.h
Original file line number Diff line number Diff line change
Expand Up @@ -361,8 +361,13 @@
#define DEF_FP_OVERRIDE_RELEASE_FOCUS 0
#define DEF_FP_SORT_WINDOWLIST_BY 0

/* Function execution */
#define MAX_FUNCTION_DEPTH 512
/* Function execution failsafe limits */
#define MAX_FUNCTION_DEPTH 100
#define MAX_FUNCTION_ITEMS 1000
/* The maximum number of function items that can be run by a top level function
* call. */
#define MAX_FUNCTION_ITEMS_RUN 10000


/* Tips */
#define FTIPS_DEFAULT_PLACEMENT FTIPS_PLACEMENT_AUTO_UPDOWN
Expand Down

0 comments on commit e8a20b2

Please sign in to comment.