From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751917AbcF2UM3 (ORCPT ); Wed, 29 Jun 2016 16:12:29 -0400 Received: from mail.kernel.org ([198.145.29.136]:59352 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751504AbcF2UM2 (ORCPT ); Wed, 29 Jun 2016 16:12:28 -0400 Message-Id: <20160629201224.546349056@goodmis.org> User-Agent: quilt/0.61-1 Date: Wed, 29 Jun 2016 16:05:24 -0400 From: Steven Rostedt To: linux-kernel@vger.kernel.org Cc: Andrew Morton , Rasmus Villemoes , Frederic Weisbecker , Andy Shevchenko , Jiri Olsa Subject: [RFC][PATCH 2/3] vsprintf: Add support for %pf and %pF to vbin_printf() References: <20160629200522.686965980@goodmis.org> MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-15 Content-Disposition: inline; filename=0002-vsprintf-Add-support-for-pf-and-pF-to-vbin_printf.patch Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: "Steven Rostedt (Red Hat)" 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 Cc: Jiri Olsa Signed-off-by: Steven Rostedt --- 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