[RFC][PATCH 2/3] vsprintf: Add support for %pf and %pF to vbin_printf()

From: Steven Rostedt
Date: Wed Jun 29 2016 - 16:12:32 EST


From: "Steven Rostedt (Red Hat)" <rostedt@xxxxxxxxxxx>

Some architectures require a dereference of function pointers (See powerpc).
The dereferenced poiner must be saved into the buffer in vbin_printf() to be
safe to access it later.

Cc: Frederic Weisbecker <fweisbec@xxxxxxxxx>
Cc: Jiri Olsa <jolsa@xxxxxxxxxx>
Signed-off-by: Steven Rostedt <rostedt@xxxxxxxxxxx>
---
lib/vsprintf.c | 44 ++++++++++++++++++++++++++++++++------------
1 file changed, 32 insertions(+), 12 deletions(-)

diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index b2a331d948a2..1eb4c7bc3509 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -2271,15 +2271,6 @@ static bool supported_bin_ptr(const char *fmt)
bool supported = false;

switch (fmt[0]) {
- case 'F':
- case 'f':
- /* Some archs dereference function pointers */
- if (vbin_printf ==
- dereference_function_descriptor(vbin_printf)) {
- supported = true;
- break;
- }
- /* Fall through */
case 'R':
case 'r':
case 'b':
@@ -2394,7 +2385,21 @@ do { \
}

case FORMAT_TYPE_PTR:
- save_arg(void *);
+ switch (fmt[0]) {
+ case 'F':
+ case 'f': {
+ void *ptr = va_arg(args, void *);
+
+ ptr = dereference_function_descriptor(ptr);
+ str = PTR_ALIGN(str, sizeof(u32));
+ if (str + sizeof(ptr) <= end)
+ *(void **)str = ptr;
+ str += sizeof(ptr);
+ break;
+ }
+ default:
+ save_arg(void *);
+ }
/* skip all alphanumeric pointer suffixes */
while (isalnum(*fmt))
fmt++;
@@ -2548,8 +2553,23 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)

case FORMAT_TYPE_PTR: {
const char *_fmt = fmt;
-
- if (!supported_bin_ptr(fmt)) {
+ char tmp_fmt[2];
+
+ if (supported_bin_ptr(fmt)) {
+ switch (fmt[0]) {
+ case 'F':
+ case 'f':
+ /*
+ * The saved pointer has already
+ * been derefenced. Convert the
+ * 'f' to 's' or 'F' to 'S'.
+ */
+ tmp_fmt[0] = 's' - ('f' - fmt[0]);
+ tmp_fmt[1] = 0;
+ _fmt = tmp_fmt;
+ break;
+ }
+ } else {
int len = sizeof(unsupported_str) + 1;

if (str + len <= end) {
--
2.8.1