| .. | .. |
|---|
| 417 | 417 | * event param, and is passed to the synthetic event |
|---|
| 418 | 418 | * invocation. |
|---|
| 419 | 419 | */ |
|---|
| 420 | | - unsigned int var_ref_idx[TRACING_MAP_VARS_MAX]; |
|---|
| 420 | + unsigned int var_ref_idx[SYNTH_FIELDS_MAX]; |
|---|
| 421 | 421 | struct synth_event *synth_event; |
|---|
| 422 | 422 | bool use_trace_keyword; |
|---|
| 423 | 423 | char *synth_event_name; |
|---|
| .. | .. |
|---|
| 1087 | 1087 | { |
|---|
| 1088 | 1088 | const char *field_name = ""; |
|---|
| 1089 | 1089 | |
|---|
| 1090 | + if (WARN_ON_ONCE(!field)) |
|---|
| 1091 | + return field_name; |
|---|
| 1092 | + |
|---|
| 1090 | 1093 | if (level > 1) |
|---|
| 1091 | 1094 | return field_name; |
|---|
| 1092 | 1095 | |
|---|
| .. | .. |
|---|
| 1646 | 1649 | unsigned long fl = flags & ~HIST_FIELD_FL_LOG2; |
|---|
| 1647 | 1650 | hist_field->fn = hist_field_log2; |
|---|
| 1648 | 1651 | hist_field->operands[0] = create_hist_field(hist_data, field, fl, NULL); |
|---|
| 1652 | + if (!hist_field->operands[0]) |
|---|
| 1653 | + goto free; |
|---|
| 1649 | 1654 | hist_field->size = hist_field->operands[0]->size; |
|---|
| 1650 | 1655 | hist_field->type = kstrdup(hist_field->operands[0]->type, GFP_KERNEL); |
|---|
| 1651 | 1656 | if (!hist_field->type) |
|---|
| .. | .. |
|---|
| 1846 | 1851 | return ref_field; |
|---|
| 1847 | 1852 | } |
|---|
| 1848 | 1853 | } |
|---|
| 1849 | | - |
|---|
| 1854 | + /* Sanity check to avoid out-of-bound write on 'hist_data->var_refs' */ |
|---|
| 1855 | + if (hist_data->n_var_refs >= TRACING_MAP_VARS_MAX) |
|---|
| 1856 | + return NULL; |
|---|
| 1850 | 1857 | ref_field = create_hist_field(var_field->hist_data, NULL, flags, NULL); |
|---|
| 1851 | 1858 | if (ref_field) { |
|---|
| 1852 | 1859 | if (init_var_ref(ref_field, var_field, system, event_name)) { |
|---|
| .. | .. |
|---|
| 3113 | 3120 | while (params) { |
|---|
| 3114 | 3121 | if (data->n_params >= SYNTH_FIELDS_MAX) { |
|---|
| 3115 | 3122 | hist_err(tr, HIST_ERR_TOO_MANY_PARAMS, 0); |
|---|
| 3123 | + ret = -EINVAL; |
|---|
| 3116 | 3124 | goto out; |
|---|
| 3117 | 3125 | } |
|---|
| 3118 | 3126 | |
|---|
| .. | .. |
|---|
| 3448 | 3456 | int var_ref_idx, ret = 0; |
|---|
| 3449 | 3457 | |
|---|
| 3450 | 3458 | lockdep_assert_held(&event_mutex); |
|---|
| 3459 | + |
|---|
| 3460 | + /* Sanity check to avoid out-of-bound write on 'data->var_ref_idx' */ |
|---|
| 3461 | + if (data->n_params > SYNTH_FIELDS_MAX) |
|---|
| 3462 | + return -EINVAL; |
|---|
| 3451 | 3463 | |
|---|
| 3452 | 3464 | if (data->use_trace_keyword) |
|---|
| 3453 | 3465 | synth_event_name = data->synth_event_name; |
|---|
| .. | .. |
|---|
| 5805 | 5817 | if (get_named_trigger_data(trigger_data)) |
|---|
| 5806 | 5818 | goto enable; |
|---|
| 5807 | 5819 | |
|---|
| 5808 | | - if (has_hist_vars(hist_data)) |
|---|
| 5809 | | - save_hist_vars(hist_data); |
|---|
| 5810 | | - |
|---|
| 5811 | 5820 | ret = create_actions(hist_data); |
|---|
| 5812 | 5821 | if (ret) |
|---|
| 5813 | 5822 | goto out_unreg; |
|---|
| 5823 | + |
|---|
| 5824 | + if (has_hist_vars(hist_data) || hist_data->n_var_refs) { |
|---|
| 5825 | + ret = save_hist_vars(hist_data); |
|---|
| 5826 | + if (ret) |
|---|
| 5827 | + goto out_unreg; |
|---|
| 5828 | + } |
|---|
| 5814 | 5829 | |
|---|
| 5815 | 5830 | ret = tracing_map_init(hist_data->map); |
|---|
| 5816 | 5831 | if (ret) |
|---|
| .. | .. |
|---|
| 5827 | 5842 | /* Just return zero, not the number of registered triggers */ |
|---|
| 5828 | 5843 | ret = 0; |
|---|
| 5829 | 5844 | out: |
|---|
| 5830 | | - if (ret == 0) |
|---|
| 5845 | + if (ret == 0 && glob[0]) |
|---|
| 5831 | 5846 | hist_err_clear(); |
|---|
| 5832 | 5847 | |
|---|
| 5833 | 5848 | return ret; |
|---|