@@ -1050,7 +1050,7 @@ struct fgraph_ops {
};
void *fgraph_reserve_data(int size_bytes);
-void *fgraph_retrieve_data(void);
+void *fgraph_retrieve_data(int *size_bytes);
/*
* Stack of return addresses for functions
@@ -289,6 +289,7 @@ void *fgraph_reserve_data(int size_bytes)
/**
* fgraph_retrieve_data - Retrieve stored data from fgraph_reserve_data()
+ * @size_bytes: pointer to retrieved data size.
*
* This is to be called by a fgraph_ops retfunc(), to retrieve data that
* was stored by the fgraph_ops entryfunc() on the function entry.
@@ -300,7 +301,7 @@ void *fgraph_reserve_data(int size_bytes)
* matching entryfunc() for the retfunc() this is called from.
* Or NULL if there was nothing stored.
*/
-void *fgraph_retrieve_data(void)
+void *fgraph_retrieve_data(int *size_bytes)
{
unsigned long val;
int curr_ret_stack = current->curr_ret_stack;
@@ -313,6 +314,8 @@ void *fgraph_retrieve_data(void)
val = current->ret_stack[curr_ret_stack - 2];
if (__get_type(val) != FGRAPH_TYPE_DATA)
return NULL;
+ if (size_bytes)
+ *size_bytes = (__get_data(val) - 1) * sizeof(long);
return ¤t->ret_stack[curr_ret_stack -
(__get_data(val) + 1)];
@@ -807,15 +807,23 @@ static __init void store_return(struct ftrace_graph_ret *trace,
const char *type = fgraph_store_type_name;
long long expect = 0;
long long found = -1;
+ int size;
char *p;
- p = fgraph_retrieve_data();
+ p = fgraph_retrieve_data(&size);
if (!p) {
snprintf(fgraph_error_str_buf, sizeof(fgraph_error_str_buf),
"Failed to retrieve %s\n", type);
fgraph_error_str = fgraph_error_str_buf;
return;
}
+ if (fgraph_store_size > size) {
+ snprintf(fgraph_error_str_buf, sizeof(fgraph_error_str_buf),
+ "Retrieved size %d is smaller than expected %d\n",
+ size, (int)fgraph_store_size);
+ fgraph_error_str = fgraph_error_str_buf;
+ return;
+ }
switch (fgraph_store_size) {
case 1: