From patchwork Thu Mar 16 17:01:41 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Olsa X-Patchwork-Id: 13178083 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E849CC7618B for ; Thu, 16 Mar 2023 17:02:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229966AbjCPRCT (ORCPT ); Thu, 16 Mar 2023 13:02:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32860 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229842AbjCPRCQ (ORCPT ); Thu, 16 Mar 2023 13:02:16 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4FCF9E6DB2; Thu, 16 Mar 2023 10:02:12 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id AAFCFB820AD; Thu, 16 Mar 2023 17:02:10 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 94DD7C433EF; Thu, 16 Mar 2023 17:02:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1678986129; bh=rlnHUcArwM6SIvbHJnlNQfqpKxk+RvN2l+D5fdKLMa8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mko2AyIGWCfuAb/notSpksldx+wnHyuJJ4/SEak6IfxwljXnE+r8/+kMT7THTFZQ5 Wncxf77aMXc3FbAfZfDb08GQs5sdSXxJP/oxSMw5mFt26kNKx9/5wT/iIghXvWGrPt p/shHWVxwdSZ8CaChz7D04gE4GZtpXAlZNM9LhqY6aE2MbZAGy6rv+Yt6siwcFcTvz fMFLw05Y8JJ7ka5JyaIx/wptVp0ilYP5XRMB4WqQlNarQsTWdfLNtGysPEqe5mNwBC eGb6hOm37AxCLhqGwPJ7Uf6WZevagTDZ0Lmk5+qQ9EwJwNKT5AqiCYBFavWZH5OdJw czU9fH4Y2iLaw== From: Jiri Olsa To: Alexei Starovoitov , Andrii Nakryiko , Hao Luo , Andrew Morton , Alexander Viro , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Matthew Wilcox Cc: bpf@vger.kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-perf-users@vger.kernel.org, Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , Stanislav Fomichev , Daniel Borkmann , Namhyung Kim , Dave Chinner Subject: [PATCHv3 bpf-next 1/9] mm: Store build id in file object Date: Thu, 16 Mar 2023 18:01:41 +0100 Message-Id: <20230316170149.4106586-2-jolsa@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230316170149.4106586-1-jolsa@kernel.org> References: <20230316170149.4106586-1-jolsa@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Storing build id in file object for elf executable with build id defined. The build id is stored when file is mmaped. The build id object assignment to the file is locked with existing file->f_mapping semaphore. The f_build_id pointer points either build id object or carries the error the build id retrieval failed on. It's hidden behind new config option CONFIG_FILE_BUILD_ID. Signed-off-by: Jiri Olsa --- fs/file_table.c | 3 +++ include/linux/buildid.h | 17 +++++++++++++++++ include/linux/fs.h | 7 +++++++ lib/buildid.c | 42 +++++++++++++++++++++++++++++++++++++++++ mm/Kconfig | 9 +++++++++ mm/mmap.c | 18 ++++++++++++++++++ 6 files changed, 96 insertions(+) diff --git a/fs/file_table.c b/fs/file_table.c index 372653b92617..d72f72503268 100644 --- a/fs/file_table.c +++ b/fs/file_table.c @@ -29,6 +29,7 @@ #include #include #include +#include #include @@ -48,6 +49,7 @@ static void file_free_rcu(struct rcu_head *head) { struct file *f = container_of(head, struct file, f_rcuhead); + file_build_id_free(f); put_cred(f->f_cred); kmem_cache_free(filp_cachep, f); } @@ -413,6 +415,7 @@ void __init files_init(void) filp_cachep = kmem_cache_create("filp", sizeof(struct file), 0, SLAB_HWCACHE_ALIGN | SLAB_PANIC | SLAB_ACCOUNT, NULL); percpu_counter_init(&nr_files, 0, GFP_KERNEL); + build_id_init(); } /* diff --git a/include/linux/buildid.h b/include/linux/buildid.h index 3b7a0ff4642f..b8b2e00420d6 100644 --- a/include/linux/buildid.h +++ b/include/linux/buildid.h @@ -3,9 +3,15 @@ #define _LINUX_BUILDID_H #include +#include #define BUILD_ID_SIZE_MAX 20 +struct build_id { + u32 sz; + char data[BUILD_ID_SIZE_MAX]; +}; + int build_id_parse(struct vm_area_struct *vma, unsigned char *build_id, __u32 *size); int build_id_parse_buf(const void *buf, unsigned char *build_id, u32 buf_size); @@ -17,4 +23,15 @@ void init_vmlinux_build_id(void); static inline void init_vmlinux_build_id(void) { } #endif +#ifdef CONFIG_FILE_BUILD_ID +void __init build_id_init(void); +void build_id_free(struct build_id *bid); +void file_build_id_free(struct file *f); +void vma_read_build_id(struct vm_area_struct *vma, struct build_id **bidp); +#else +static inline void __init build_id_init(void) { } +static inline void build_id_free(struct build_id *bid) { } +static inline void file_build_id_free(struct file *f) { } +#endif /* CONFIG_FILE_BUILD_ID */ + #endif diff --git a/include/linux/fs.h b/include/linux/fs.h index c85916e9f7db..ce03fd965cdb 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -977,6 +977,13 @@ struct file { struct address_space *f_mapping; errseq_t f_wb_err; errseq_t f_sb_err; /* for syncfs */ +#ifdef CONFIG_FILE_BUILD_ID + /* + * Initialized when the file is mmaped (mmap_region), + * guarded by f_mapping lock. + */ + struct build_id *f_build_id; +#endif } __randomize_layout __attribute__((aligned(4))); /* lest something weird decides that 2 is OK */ diff --git a/lib/buildid.c b/lib/buildid.c index dfc62625cae4..04181c0b7c21 100644 --- a/lib/buildid.c +++ b/lib/buildid.c @@ -5,6 +5,7 @@ #include #include #include +#include #define BUILD_ID 3 @@ -189,3 +190,44 @@ void __init init_vmlinux_build_id(void) build_id_parse_buf(&__start_notes, vmlinux_build_id, size); } #endif + +#ifdef CONFIG_FILE_BUILD_ID + +/* SLAB cache for build_id structures */ +static struct kmem_cache *build_id_cachep; + +void vma_read_build_id(struct vm_area_struct *vma, struct build_id **bidp) +{ + struct build_id *bid = ERR_PTR(-ENOMEM); + int err; + + bid = kmem_cache_alloc(build_id_cachep, GFP_KERNEL); + if (!bid) + goto out; + err = build_id_parse(vma, bid->data, &bid->sz); + if (err) { + build_id_free(bid); + bid = ERR_PTR(err); + } +out: + *bidp = bid; +} + +void file_build_id_free(struct file *f) +{ + build_id_free(f->f_build_id); +} + +void build_id_free(struct build_id *bid) +{ + if (IS_ERR_OR_NULL(bid)) + return; + kmem_cache_free(build_id_cachep, bid); +} + +void __init build_id_init(void) +{ + build_id_cachep = kmem_cache_create("build_id", sizeof(struct build_id), 0, + SLAB_HWCACHE_ALIGN | SLAB_PANIC | SLAB_ACCOUNT, NULL); +} +#endif /* CONFIG_FILE_BUILD_ID */ diff --git a/mm/Kconfig b/mm/Kconfig index 4751031f3f05..5e9f48962703 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -1202,6 +1202,15 @@ config LRU_GEN_STATS This option has a per-memcg and per-node memory overhead. # } +config FILE_BUILD_ID + bool "Store build id in file object" + default n + help + Store build id in file object for elf executable with build id + defined. The build id is stored when file is mmaped. + + It's typically used by eBPF programs and perf subsystem. + source "mm/damon/Kconfig" endmenu diff --git a/mm/mmap.c b/mm/mmap.c index 20f21f0949dd..1c14e8c84d3a 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -2480,6 +2480,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr, pgoff_t vm_pgoff; int error; VMA_ITERATOR(vmi, mm, addr); + struct build_id *bid = NULL; /* Check against address space limit. */ if (!may_expand_vm(mm, vm_flags, len >> PAGE_SHIFT)) { @@ -2575,6 +2576,10 @@ unsigned long mmap_region(struct file *file, unsigned long addr, if (error) goto unmap_and_free_vma; +#ifdef CONFIG_FILE_BUILD_ID + if (vma->vm_flags & VM_EXEC && !file->f_build_id) + vma_read_build_id(vma, &bid); +#endif /* * Expansion is handled above, merging is handled below. * Drivers should not alter the address of the VMA. @@ -2647,6 +2652,12 @@ unsigned long mmap_region(struct file *file, unsigned long addr, if (vma->vm_flags & VM_SHARED) mapping_allow_writable(vma->vm_file->f_mapping); +#ifdef CONFIG_FILE_BUILD_ID + if (bid && !file->f_build_id) { + file->f_build_id = bid; + bid = NULL; + } +#endif flush_dcache_mmap_lock(vma->vm_file->f_mapping); vma_interval_tree_insert(vma, &vma->vm_file->f_mapping->i_mmap); flush_dcache_mmap_unlock(vma->vm_file->f_mapping); @@ -2667,6 +2678,12 @@ unsigned long mmap_region(struct file *file, unsigned long addr, expanded: perf_event_mmap(vma); + /* + * File can already have f_build_id assigned, so we need to release + * the build id we just read and did not assign. + */ + build_id_free(bid); + vm_stat_account(mm, vm_flags, len >> PAGE_SHIFT); if (vm_flags & VM_LOCKED) { if ((vm_flags & VM_SPECIAL) || vma_is_dax(vma) || @@ -2711,6 +2728,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr, mapping_unmap_writable(file->f_mapping); free_vma: vm_area_free(vma); + build_id_free(bid); unacct_error: if (charged) vm_unacct_memory(charged); From patchwork Thu Mar 16 17:01:42 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Olsa X-Patchwork-Id: 13178084 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C090AC7618B for ; Thu, 16 Mar 2023 17:02:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230164AbjCPRCd (ORCPT ); Thu, 16 Mar 2023 13:02:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33280 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230076AbjCPRCb (ORCPT ); Thu, 16 Mar 2023 13:02:31 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EE568E6DA8; Thu, 16 Mar 2023 10:02:24 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 7F41CB8227C; Thu, 16 Mar 2023 17:02:23 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0A54DC433EF; Thu, 16 Mar 2023 17:02:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1678986142; bh=wPkey4BWxoSwuVm0/JDcphsHh4pWF/uWOFmXxlWLkHg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=SNv/7OPwD0I0s7lhX5kbFYwqOHQ6BEeVp42wO+mX9PwyPyOWc9aJP8tpSf8pTSmc7 aJUi7ueFyPgrnzibcjii0GIA0zBfQ+oVxp0KrZ6owWC8EKweBWjgHUvuX4bvUsGb7K jRQt6UIxSQ6hmnmM4MFepJHDyU9d2by956YrhOlpGLKvW0kO976LhWUg9lFcytBy2I cOPXJzHAAG6XfhpiPaipKG4qKVWkQ9gVWf3V6V9dmCwMAjG+X0ldhsn8+xIPvtS/NU bs9dvCYweuoj4hon4v1BsbRdkf1cx44ZWcTyojzhvrOzQoSNM8qF+wi+IS6ht9pVT0 jD7VHR0ypnIDw== From: Jiri Olsa To: Alexei Starovoitov , Andrii Nakryiko , Hao Luo , Andrew Morton , Alexander Viro , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Matthew Wilcox Cc: bpf@vger.kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-perf-users@vger.kernel.org, Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , Stanislav Fomichev , Daniel Borkmann , Namhyung Kim , Dave Chinner Subject: [PATCHv3 bpf-next 2/9] perf: Use file object build id in perf_event_mmap_event Date: Thu, 16 Mar 2023 18:01:42 +0100 Message-Id: <20230316170149.4106586-3-jolsa@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230316170149.4106586-1-jolsa@kernel.org> References: <20230316170149.4106586-1-jolsa@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Use build id from file object when available for perf's MMAP2 event build id data. The file's f_build_id is available (for CONFIG_FILE_BUILD_ID option) when the file is mmap-ed and before the perf's callback is executed, so we can use it, instead of reading it again. Signed-off-by: Jiri Olsa --- kernel/events/core.c | 43 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index f79fd8b87f75..3a5398dda6f6 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -8527,6 +8527,9 @@ struct perf_mmap_event { u32 prot, flags; u8 build_id[BUILD_ID_SIZE_MAX]; u32 build_id_size; +#ifdef CONFIG_FILE_BUILD_ID + struct build_id *f_build_id; +#endif struct { struct perf_event_header header; @@ -8539,6 +8542,38 @@ struct perf_mmap_event { } event_id; }; +#ifdef CONFIG_FILE_BUILD_ID +static void build_id_read(struct perf_mmap_event *mmap_event) +{ + struct vm_area_struct *vma = mmap_event->vma; + + mmap_event->f_build_id = vma->vm_file ? vma->vm_file->f_build_id : NULL; +} + +static bool has_build_id(struct perf_mmap_event *mmap_event) +{ + return !IS_ERR_OR_NULL(mmap_event->f_build_id); +} + +#define build_id_data mmap_event->f_build_id->data +#define build_id_size mmap_event->f_build_id->sz +#else +static void build_id_read(struct perf_mmap_event *mmap_event) +{ + struct vm_area_struct *vma = mmap_event->vma; + + build_id_parse(vma, mmap_event->build_id, &mmap_event->build_id_size); +} + +static bool has_build_id(struct perf_mmap_event *mmap_event) +{ + return mmap_event->build_id_size; +} + +#define build_id_data mmap_event->build_id +#define build_id_size mmap_event->build_id_size +#endif + static int perf_event_mmap_match(struct perf_event *event, void *data) { @@ -8583,7 +8618,7 @@ static void perf_event_mmap_output(struct perf_event *event, mmap_event->event_id.pid = perf_event_pid(event, current); mmap_event->event_id.tid = perf_event_tid(event, current); - use_build_id = event->attr.build_id && mmap_event->build_id_size; + use_build_id = event->attr.build_id && has_build_id(mmap_event); if (event->attr.mmap2 && use_build_id) mmap_event->event_id.header.misc |= PERF_RECORD_MISC_MMAP_BUILD_ID; @@ -8592,10 +8627,10 @@ static void perf_event_mmap_output(struct perf_event *event, if (event->attr.mmap2) { if (use_build_id) { - u8 size[4] = { (u8) mmap_event->build_id_size, 0, 0, 0 }; + u8 size[4] = { (u8) build_id_size, 0, 0, 0 }; __output_copy(&handle, size, 4); - __output_copy(&handle, mmap_event->build_id, BUILD_ID_SIZE_MAX); + __output_copy(&handle, build_id_data, BUILD_ID_SIZE_MAX); } else { perf_output_put(&handle, mmap_event->maj); perf_output_put(&handle, mmap_event->min); @@ -8727,7 +8762,7 @@ static void perf_event_mmap_event(struct perf_mmap_event *mmap_event) mmap_event->event_id.header.size = sizeof(mmap_event->event_id) + size; if (atomic_read(&nr_build_id_events)) - build_id_parse(vma, mmap_event->build_id, &mmap_event->build_id_size); + build_id_read(mmap_event); perf_iterate_sb(perf_event_mmap_output, mmap_event, From patchwork Thu Mar 16 17:01:43 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Olsa X-Patchwork-Id: 13178085 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 44466C6FD1F for ; Thu, 16 Mar 2023 17:02:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230329AbjCPRCu (ORCPT ); Thu, 16 Mar 2023 13:02:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34090 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229870AbjCPRCt (ORCPT ); Thu, 16 Mar 2023 13:02:49 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 20889E7EF4; Thu, 16 Mar 2023 10:02:38 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 92B11B8227B; Thu, 16 Mar 2023 17:02:36 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 04ED5C433D2; Thu, 16 Mar 2023 17:02:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1678986155; bh=GA8tXS4Mul2elWYsjsHoBsAbirrUGLhRxbF2Iayc8rg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZhtVj376qlPRWZ1voHqasur/pICqPh2D1iv3o8cqWfD6Tqwvn3vzB/NHNzr5q2zvc Du2DgVvnZu67X8HekIq3/BB471wLGP+xMh44yTpxdsA6MJ4i52t9Npw6fiUxKq79AZ BVAKBWemUcdBpEcTGD1w7L96mTMWWbvInC9HuwInR990nvhl2XzxnJL/fE2VLgeg3z M1me3mgk3ZFsAMmRYmy1tCPnFvQsZ8E0lS7EnHJoajef6uFHZoErIYZA4oTQ5C+GUn /zyUjx1ODsI4xjPqeOEyO5tNqStX53VCPmBS3mjJtL3+81scbzKF/Kf3q+8KkHUC9A CKaZl7dtXKDTg== From: Jiri Olsa To: Alexei Starovoitov , Andrii Nakryiko , Hao Luo , Andrew Morton , Alexander Viro , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Matthew Wilcox Cc: bpf@vger.kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-perf-users@vger.kernel.org, Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , Stanislav Fomichev , Daniel Borkmann , Namhyung Kim , Dave Chinner Subject: [PATCHv3 bpf-next 3/9] bpf: Use file object build id in stackmap Date: Thu, 16 Mar 2023 18:01:43 +0100 Message-Id: <20230316170149.4106586-4-jolsa@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230316170149.4106586-1-jolsa@kernel.org> References: <20230316170149.4106586-1-jolsa@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Use build id from file object in stackmap if it's available. The file's f_build_id is available (for CONFIG_FILE_BUILD_ID option) when the file is mmap-ed, so it will be available (if present) when used by stackmap. Signed-off-by: Jiri Olsa Acked-by: Andrii Nakryiko --- kernel/bpf/stackmap.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/kernel/bpf/stackmap.c b/kernel/bpf/stackmap.c index 0f1d8dced933..14d27bd83081 100644 --- a/kernel/bpf/stackmap.c +++ b/kernel/bpf/stackmap.c @@ -124,6 +124,28 @@ static struct bpf_map *stack_map_alloc(union bpf_attr *attr) return ERR_PTR(err); } +#ifdef CONFIG_FILE_BUILD_ID +static int vma_get_build_id(struct vm_area_struct *vma, unsigned char *build_id) +{ + struct build_id *bid; + + if (!vma->vm_file) + return -EINVAL; + bid = vma->vm_file->f_build_id; + if (IS_ERR_OR_NULL(bid)) + return bid ? PTR_ERR(bid) : -ENOENT; + if (bid->sz > BUILD_ID_SIZE_MAX) + return -EINVAL; + memcpy(build_id, bid->data, bid->sz); + return 0; +} +#else +static int vma_get_build_id(struct vm_area_struct *vma, unsigned char *build_id) +{ + return build_id_parse(vma, build_id, NULL); +} +#endif + static void stack_map_get_build_id_offset(struct bpf_stack_build_id *id_offs, u64 *ips, u32 trace_nr, bool user) { @@ -156,7 +178,7 @@ static void stack_map_get_build_id_offset(struct bpf_stack_build_id *id_offs, goto build_id_valid; } vma = find_vma(current->mm, ips[i]); - if (!vma || build_id_parse(vma, id_offs[i].build_id, NULL)) { + if (!vma || vma_get_build_id(vma, id_offs[i].build_id)) { /* per entry fall back to ips */ id_offs[i].status = BPF_STACK_BUILD_ID_IP; id_offs[i].ip = ips[i]; From patchwork Thu Mar 16 17:01:44 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Olsa X-Patchwork-Id: 13178086 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EFA02C7618B for ; Thu, 16 Mar 2023 17:03:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230412AbjCPRDU (ORCPT ); Thu, 16 Mar 2023 13:03:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34420 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231231AbjCPRDL (ORCPT ); Thu, 16 Mar 2023 13:03:11 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 17CFCE6FFF; Thu, 16 Mar 2023 10:02:52 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 927D6620B5; Thu, 16 Mar 2023 17:02:48 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id B142AC4339E; Thu, 16 Mar 2023 17:02:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1678986168; bh=2rdENgg7fzhoKYPinTYmZkVwba8MoExnAAxutCEQK3M=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iqjfspNDqGz3klTZPT2+BpffWd9f4W6SLqgKqRFii0Qw4uBg0XdMAi+nls+GHm3dP t3EdFLYjAWxF/k0NhZwvPKEpRPiSt/sBefMLuZVCBpQQ/phZzHSKTTxgVN5tQN7nS0 +bF0J6oeBdA9BMVGZF72vgksl6td2ylD9b340n7jBfC2iB/AUqxhi1sYyMQb/MS7mB 6FTBsJwAG11kA6/pox2tkaZx1afavULyHXdBh9QmzYTCvrqBJjZtouKIfhTzrvlQ5I 4GsgMcdAxFBgxi3hL3OZ5O9QstrOLNsRV4iCd7w5//E6F0GNwJ7LHtIWx5ndQiJ9iA T+NEcJP1lLfdg== From: Jiri Olsa To: Alexei Starovoitov , Andrii Nakryiko , Hao Luo , Andrew Morton , Alexander Viro , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Matthew Wilcox Cc: bpf@vger.kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-perf-users@vger.kernel.org, Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , Stanislav Fomichev , Daniel Borkmann , Namhyung Kim , Dave Chinner Subject: [PATCHv3 bpf-next 4/9] bpf: Switch BUILD_ID_SIZE_MAX to enum Date: Thu, 16 Mar 2023 18:01:44 +0100 Message-Id: <20230316170149.4106586-5-jolsa@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230316170149.4106586-1-jolsa@kernel.org> References: <20230316170149.4106586-1-jolsa@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Switching BUILD_ID_SIZE_MAX to enum, so we expose it to BPF programs through vmlinux.h. Suggested-by: Andrii Nakryiko Signed-off-by: Jiri Olsa Acked-by: Andrii Nakryiko --- include/linux/buildid.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/linux/buildid.h b/include/linux/buildid.h index b8b2e00420d6..316971c634fe 100644 --- a/include/linux/buildid.h +++ b/include/linux/buildid.h @@ -5,7 +5,9 @@ #include #include -#define BUILD_ID_SIZE_MAX 20 +enum { + BUILD_ID_SIZE_MAX = 20 +}; struct build_id { u32 sz; From patchwork Thu Mar 16 17:01:45 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Olsa X-Patchwork-Id: 13178104 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B2E65C7618E for ; Thu, 16 Mar 2023 17:03:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230351AbjCPRDo (ORCPT ); Thu, 16 Mar 2023 13:03:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36096 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229717AbjCPRDm (ORCPT ); Thu, 16 Mar 2023 13:03:42 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 65D2DDC096; Thu, 16 Mar 2023 10:03:17 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 7BFE7620B8; Thu, 16 Mar 2023 17:03:01 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 84B9BC433EF; Thu, 16 Mar 2023 17:02:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1678986180; bh=Rj6UdNWuOo8DkLviQii3I1+Tk2Kvc/67ARrHkQm/dfw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GGxc9yi28eFc9bY1ajwWe10NyIStMwt4YOzdhNM/wiX7yOjelaepeo5UXwJfAytWI lDik7EeGavF+ShDZ3r/gpO2e1n4/59BQSSW8iv6Z7JNAXcztJowDqIeD/qF/a5nuNf QtVkOWTQ+AKS6CyZBXVFQ7EsGqj70MeAYMnQIKquZwZBIZPDhvAblZJFyFBmKbUnJP rH/8mHFzO8LPJnWLCse6i6Z32V7YnpbZh4+vysz014gw+q2mzA7e0t0ec7lFSilRnj shtyTlk6ESVFdmTJGfIG5cKbon9GjIAevOi6p1Ee6Sq9SEUJ6lgRL/cKjUQpcFHlNO jrdFLxifXhH/A== From: Jiri Olsa To: Alexei Starovoitov , Andrii Nakryiko , Hao Luo , Andrew Morton , Alexander Viro , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Matthew Wilcox Cc: bpf@vger.kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-perf-users@vger.kernel.org, Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , Stanislav Fomichev , Daniel Borkmann , Namhyung Kim , Dave Chinner Subject: [PATCHv3 bpf-next 5/9] selftests/bpf: Add read_buildid function Date: Thu, 16 Mar 2023 18:01:45 +0100 Message-Id: <20230316170149.4106586-6-jolsa@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230316170149.4106586-1-jolsa@kernel.org> References: <20230316170149.4106586-1-jolsa@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Adding read_build_id function that parses out build id from specified binary. It will replace extract_build_id and also be used in following changes. Signed-off-by: Jiri Olsa --- tools/testing/selftests/bpf/trace_helpers.c | 86 +++++++++++++++++++++ tools/testing/selftests/bpf/trace_helpers.h | 5 ++ 2 files changed, 91 insertions(+) diff --git a/tools/testing/selftests/bpf/trace_helpers.c b/tools/testing/selftests/bpf/trace_helpers.c index 934bf28fc888..72b38a41f574 100644 --- a/tools/testing/selftests/bpf/trace_helpers.c +++ b/tools/testing/selftests/bpf/trace_helpers.c @@ -11,6 +11,9 @@ #include #include #include "trace_helpers.h" +#include +#include +#include #define TRACEFS_PIPE "/sys/kernel/tracing/trace_pipe" #define DEBUGFS_PIPE "/sys/kernel/debug/tracing/trace_pipe" @@ -234,3 +237,86 @@ ssize_t get_rel_offset(uintptr_t addr) fclose(f); return -EINVAL; } + +static int +parse_build_id_buf(const void *note_start, Elf32_Word note_size, + char *build_id) +{ + Elf32_Word note_offs = 0, new_offs; + + while (note_offs + sizeof(Elf32_Nhdr) < note_size) { + Elf32_Nhdr *nhdr = (Elf32_Nhdr *)(note_start + note_offs); + + if (nhdr->n_type == 3 && nhdr->n_namesz == sizeof("GNU") && + !strcmp((char *)(nhdr + 1), "GNU") && nhdr->n_descsz > 0 && + nhdr->n_descsz <= BPF_BUILD_ID_SIZE) { + memcpy(build_id, note_start + note_offs + + ALIGN(sizeof("GNU"), 4) + sizeof(Elf32_Nhdr), nhdr->n_descsz); + memset(build_id + nhdr->n_descsz, 0, BPF_BUILD_ID_SIZE - nhdr->n_descsz); + return (int) nhdr->n_descsz; + } + + new_offs = note_offs + sizeof(Elf32_Nhdr) + + ALIGN(nhdr->n_namesz, 4) + ALIGN(nhdr->n_descsz, 4); + if (new_offs >= note_size) + break; + note_offs = new_offs; + } + + return -EINVAL; +} + +/* Reads binary from *path* file and returns it in the *build_id* + * which is expected to be at least BPF_BUILD_ID_SIZE bytes. + * Returns size of build id on success. On error the error value + * is returned. + */ +int read_build_id(const char *path, char *build_id) +{ + int fd, err = -EINVAL; + Elf *elf = NULL; + GElf_Ehdr ehdr; + size_t max, i; + + fd = open(path, O_RDONLY | O_CLOEXEC); + if (fd < 0) + return -errno; + + (void)elf_version(EV_CURRENT); + + elf = elf_begin(fd, ELF_C_READ, NULL); + if (!elf) + goto out; + if (elf_kind(elf) != ELF_K_ELF) + goto out; + if (gelf_getehdr(elf, &ehdr) == NULL) + goto out; + if (ehdr.e_ident[EI_CLASS] != ELFCLASS64) + goto out; + + for (i = 0; i < ehdr.e_phnum; i++) { + GElf_Phdr mem, *phdr; + char *data; + + phdr = gelf_getphdr(elf, i, &mem); + if (!phdr) + goto out; + if (phdr->p_type != PT_NOTE) + continue; + data = elf_rawfile(elf, &max); + if (!data) + goto out; + if (phdr->p_offset >= max || (phdr->p_offset + phdr->p_memsz >= max)) + goto out; + err = parse_build_id_buf(data + phdr->p_offset, phdr->p_memsz, build_id); + if (err > 0) + goto out; + err = -EINVAL; + } + +out: + if (elf) + elf_end(elf); + close(fd); + return err; +} diff --git a/tools/testing/selftests/bpf/trace_helpers.h b/tools/testing/selftests/bpf/trace_helpers.h index 53efde0e2998..bc3b92057033 100644 --- a/tools/testing/selftests/bpf/trace_helpers.h +++ b/tools/testing/selftests/bpf/trace_helpers.h @@ -4,6 +4,9 @@ #include +#define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask)) +#define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a)-1) + struct ksym { long addr; char *name; @@ -23,4 +26,6 @@ void read_trace_pipe(void); ssize_t get_uprobe_offset(const void *addr); ssize_t get_rel_offset(uintptr_t addr); +int read_build_id(const char *path, char *build_id); + #endif From patchwork Thu Mar 16 17:01:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Olsa X-Patchwork-Id: 13178105 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6EDABC7618E for ; Thu, 16 Mar 2023 17:03:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231216AbjCPRD6 (ORCPT ); Thu, 16 Mar 2023 13:03:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36310 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230447AbjCPRDr (ORCPT ); Thu, 16 Mar 2023 13:03:47 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6B682E6FFE; Thu, 16 Mar 2023 10:03:22 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 934CA62057; Thu, 16 Mar 2023 17:03:14 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id AE8B1C433EF; Thu, 16 Mar 2023 17:03:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1678986194; bh=XHhvrIWZe8yN3WAyFVo4Xi7J+OqocuCK7k5vskhhChE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=u/EISLQO2803reejxf8JO9MgqJ4NQbmCh7G+bn4fdRV+pQjJWe7KhKZRVVRMnw/ro ky1GblNRwpv7o43sqGdjR+vtMiXrfHmEkRy8GDHTp5zyIIcdCaW4MxkTblBR6l0SbR TAOctZXlkrbvfAr32VS7QCdN1vTKcd2FZpyaKwV6Mip5pPdN0fuTmWVv1nPd5jY5FD bZBxvJTG9trTD+BxrlJdfuicdsC4pgcFCE22xVsACPERaSCMmO+3odXdTcRCiUZbhM JiYpsGUKNn82I0dJFtheJV6qlT2BNNhuk7D4WYnHHcRnSXICVtX3RbdWfjsCO+7e5l iBrppzqNKKC5Q== From: Jiri Olsa To: Alexei Starovoitov , Andrii Nakryiko , Hao Luo , Andrew Morton , Alexander Viro , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Matthew Wilcox Cc: bpf@vger.kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-perf-users@vger.kernel.org, Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , Stanislav Fomichev , Daniel Borkmann , Namhyung Kim , Dave Chinner Subject: [PATCHv3 bpf-next 6/9] selftests/bpf: Add err.h header Date: Thu, 16 Mar 2023 18:01:46 +0100 Message-Id: <20230316170149.4106586-7-jolsa@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230316170149.4106586-1-jolsa@kernel.org> References: <20230316170149.4106586-1-jolsa@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Moving error macros from profiler.inc.h to new err.h header. It will be used in following changes. Also adding PTR_ERR macro that will be used in following changes. Signed-off-by: Jiri Olsa Acked-by: Andrii Nakryiko --- tools/testing/selftests/bpf/progs/err.h | 18 ++++++++++++++++++ .../testing/selftests/bpf/progs/profiler.inc.h | 3 +-- 2 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 tools/testing/selftests/bpf/progs/err.h diff --git a/tools/testing/selftests/bpf/progs/err.h b/tools/testing/selftests/bpf/progs/err.h new file mode 100644 index 000000000000..d66d283d9e59 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/err.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __ERR_H__ +#define __ERR_H__ + +#define MAX_ERRNO 4095 +#define IS_ERR_VALUE(x) (unsigned long)(void *)(x) >= (unsigned long)-MAX_ERRNO + +static inline int IS_ERR_OR_NULL(const void *ptr) +{ + return !ptr || IS_ERR_VALUE((unsigned long)ptr); +} + +static inline long PTR_ERR(const void *ptr) +{ + return (long) ptr; +} + +#endif /* __ERR_H__ */ diff --git a/tools/testing/selftests/bpf/progs/profiler.inc.h b/tools/testing/selftests/bpf/progs/profiler.inc.h index 875513866032..f799d87e8700 100644 --- a/tools/testing/selftests/bpf/progs/profiler.inc.h +++ b/tools/testing/selftests/bpf/progs/profiler.inc.h @@ -6,6 +6,7 @@ #include #include "profiler.h" +#include "err.h" #ifndef NULL #define NULL 0 @@ -16,7 +17,6 @@ #define O_DIRECTORY 00200000 #define __O_TMPFILE 020000000 #define O_TMPFILE (__O_TMPFILE | O_DIRECTORY) -#define MAX_ERRNO 4095 #define S_IFMT 00170000 #define S_IFSOCK 0140000 #define S_IFLNK 0120000 @@ -34,7 +34,6 @@ #define S_ISBLK(m) (((m)&S_IFMT) == S_IFBLK) #define S_ISFIFO(m) (((m)&S_IFMT) == S_IFIFO) #define S_ISSOCK(m) (((m)&S_IFMT) == S_IFSOCK) -#define IS_ERR_VALUE(x) (unsigned long)(void*)(x) >= (unsigned long)-MAX_ERRNO #define KILL_DATA_ARRAY_SIZE 8 From patchwork Thu Mar 16 17:01:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Olsa X-Patchwork-Id: 13178106 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 66C6CC7618B for ; Thu, 16 Mar 2023 17:04:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231445AbjCPREM (ORCPT ); Thu, 16 Mar 2023 13:04:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36816 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231252AbjCPRD6 (ORCPT ); Thu, 16 Mar 2023 13:03:58 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D09C52FCDD; Thu, 16 Mar 2023 10:03:28 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 2DE5F620AC; Thu, 16 Mar 2023 17:03:27 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 50A82C433D2; Thu, 16 Mar 2023 17:03:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1678986206; bh=A6fzow+FLPSwbgWXlTZg23xT6LzjnL6mQF7mmQVS3Xk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=KH/z1799tTYwpYi8mTwVuCoTeHCh5/KjKQiypM8ZlLUwhLLndHXLXZTrhTZSGRGiR 5gkkhFo+Jswe/IwHPf+B8R37UOejXaEE6vNYqwIIsDa+YrF+K9u8OA8Q2KWD05Y9oT mrUW5aVPslQW7Eas+AvOkBSf1q3i/0w+x64Z5DYLJsPXA76U4THoo9iZ61OiSfGP3T 9w5fWkO9ITikzpsEEQtbJ0Xi4yPCl5Y0u+93laTsNNjEk9EMU6iB9KUY+jX0EWB6G+ HTMLhKIjzd5BlOcemptFxmi3ozDZFUV1hyU9MgMxn3PiOC+aLgPNreRvTrBg9lKUuY pDAnnPluMdlxA== From: Jiri Olsa To: Alexei Starovoitov , Andrii Nakryiko , Hao Luo , Andrew Morton , Alexander Viro , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Matthew Wilcox Cc: bpf@vger.kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-perf-users@vger.kernel.org, Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , Stanislav Fomichev , Daniel Borkmann , Namhyung Kim , Dave Chinner Subject: [PATCHv3 bpf-next 7/9] selftests/bpf: Replace extract_build_id with read_build_id Date: Thu, 16 Mar 2023 18:01:47 +0100 Message-Id: <20230316170149.4106586-8-jolsa@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230316170149.4106586-1-jolsa@kernel.org> References: <20230316170149.4106586-1-jolsa@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Replacing extract_build_id with read_build_id that parses out build id directly from elf without using readelf tool. Acked-by: Andrii Nakryiko Signed-off-by: Jiri Olsa --- .../bpf/prog_tests/stacktrace_build_id.c | 19 ++++++-------- .../bpf/prog_tests/stacktrace_build_id_nmi.c | 17 +++++-------- tools/testing/selftests/bpf/test_progs.c | 25 ------------------- tools/testing/selftests/bpf/test_progs.h | 1 - 4 files changed, 13 insertions(+), 49 deletions(-) diff --git a/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id.c b/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id.c index 9ad09a6c538a..a2e75a976f04 100644 --- a/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id.c +++ b/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id.c @@ -7,13 +7,12 @@ void test_stacktrace_build_id(void) int control_map_fd, stackid_hmap_fd, stackmap_fd, stack_amap_fd; struct test_stacktrace_build_id *skel; - int err, stack_trace_len; + int err, stack_trace_len, build_id_size; __u32 key, prev_key, val, duration = 0; - char buf[256]; - int i, j; + char buf[BPF_BUILD_ID_SIZE]; struct bpf_stack_build_id id_offs[PERF_MAX_STACK_DEPTH]; int build_id_matches = 0; - int retry = 1; + int i, retry = 1; retry: skel = test_stacktrace_build_id__open_and_load(); @@ -52,9 +51,10 @@ void test_stacktrace_build_id(void) "err %d errno %d\n", err, errno)) goto cleanup; - err = extract_build_id(buf, 256); + build_id_size = read_build_id("urandom_read", buf); + err = build_id_size < 0 ? build_id_size : 0; - if (CHECK(err, "get build_id with readelf", + if (CHECK(err, "read_build_id", "err %d errno %d\n", err, errno)) goto cleanup; @@ -64,8 +64,6 @@ void test_stacktrace_build_id(void) goto cleanup; do { - char build_id[64]; - err = bpf_map_lookup_elem(stackmap_fd, &key, id_offs); if (CHECK(err, "lookup_elem from stackmap", "err %d, errno %d\n", err, errno)) @@ -73,10 +71,7 @@ void test_stacktrace_build_id(void) for (i = 0; i < PERF_MAX_STACK_DEPTH; ++i) if (id_offs[i].status == BPF_STACK_BUILD_ID_VALID && id_offs[i].offset != 0) { - for (j = 0; j < 20; ++j) - sprintf(build_id + 2 * j, "%02x", - id_offs[i].build_id[j] & 0xff); - if (strstr(buf, build_id) != NULL) + if (memcmp(buf, id_offs[i].build_id, build_id_size) == 0) build_id_matches = 1; } prev_key = key; diff --git a/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id_nmi.c b/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id_nmi.c index f4ea1a215ce4..4a1c5a692730 100644 --- a/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id_nmi.c +++ b/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id_nmi.c @@ -28,11 +28,10 @@ void test_stacktrace_build_id_nmi(void) .config = PERF_COUNT_HW_CPU_CYCLES, }; __u32 key, prev_key, val, duration = 0; - char buf[256]; - int i, j; + char buf[BPF_BUILD_ID_SIZE]; struct bpf_stack_build_id id_offs[PERF_MAX_STACK_DEPTH]; - int build_id_matches = 0; - int retry = 1; + int build_id_matches = 0, build_id_size; + int i, retry = 1; attr.sample_freq = read_perf_max_sample_freq(); @@ -94,7 +93,8 @@ void test_stacktrace_build_id_nmi(void) "err %d errno %d\n", err, errno)) goto cleanup; - err = extract_build_id(buf, 256); + build_id_size = read_build_id("urandom_read", buf); + err = build_id_size < 0 ? build_id_size : 0; if (CHECK(err, "get build_id with readelf", "err %d errno %d\n", err, errno)) @@ -106,8 +106,6 @@ void test_stacktrace_build_id_nmi(void) goto cleanup; do { - char build_id[64]; - err = bpf_map__lookup_elem(skel->maps.stackmap, &key, sizeof(key), id_offs, sizeof(id_offs), 0); if (CHECK(err, "lookup_elem from stackmap", @@ -116,10 +114,7 @@ void test_stacktrace_build_id_nmi(void) for (i = 0; i < PERF_MAX_STACK_DEPTH; ++i) if (id_offs[i].status == BPF_STACK_BUILD_ID_VALID && id_offs[i].offset != 0) { - for (j = 0; j < 20; ++j) - sprintf(build_id + 2 * j, "%02x", - id_offs[i].build_id[j] & 0xff); - if (strstr(buf, build_id) != NULL) + if (memcmp(buf, id_offs[i].build_id, build_id_size) == 0) build_id_matches = 1; } prev_key = key; diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c index 6d5e3022c75f..9813d53c4878 100644 --- a/tools/testing/selftests/bpf/test_progs.c +++ b/tools/testing/selftests/bpf/test_progs.c @@ -591,31 +591,6 @@ int compare_stack_ips(int smap_fd, int amap_fd, int stack_trace_len) return err; } -int extract_build_id(char *build_id, size_t size) -{ - FILE *fp; - char *line = NULL; - size_t len = 0; - - fp = popen("readelf -n ./urandom_read | grep 'Build ID'", "r"); - if (fp == NULL) - return -1; - - if (getline(&line, &len, fp) == -1) - goto err; - pclose(fp); - - if (len > size) - len = size; - memcpy(build_id, line, len); - build_id[len] = '\0'; - free(line); - return 0; -err: - pclose(fp); - return -1; -} - static int finit_module(int fd, const char *param_values, int flags) { return syscall(__NR_finit_module, fd, param_values, flags); diff --git a/tools/testing/selftests/bpf/test_progs.h b/tools/testing/selftests/bpf/test_progs.h index 3cbf005747ed..d91427bfe0d7 100644 --- a/tools/testing/selftests/bpf/test_progs.h +++ b/tools/testing/selftests/bpf/test_progs.h @@ -404,7 +404,6 @@ static inline void *u64_to_ptr(__u64 ptr) int bpf_find_map(const char *test, struct bpf_object *obj, const char *name); int compare_map_keys(int map1_fd, int map2_fd); int compare_stack_ips(int smap_fd, int amap_fd, int stack_trace_len); -int extract_build_id(char *build_id, size_t size); int kern_sync_rcu(void); int trigger_module_test_read(int read_sz); int trigger_module_test_write(int write_sz); From patchwork Thu Mar 16 17:01:48 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Olsa X-Patchwork-Id: 13178107 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8214FC6FD1F for ; Thu, 16 Mar 2023 17:04:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231438AbjCPRE2 (ORCPT ); Thu, 16 Mar 2023 13:04:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37360 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231248AbjCPREL (ORCPT ); Thu, 16 Mar 2023 13:04:11 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8D2CC2007C; Thu, 16 Mar 2023 10:03:45 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id C4E28B8227C; Thu, 16 Mar 2023 17:03:40 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 333CFC433EF; Thu, 16 Mar 2023 17:03:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1678986219; bh=BTNFjFR6qedMLNKodJS0I96kmDjan/r2p24kIgmK3/s=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=d8LC/I53yNMvhKiJ3Oq2YxbSToYguXOf9YL7kJ0By7G0BvjLuZlszeTUgYFPhKnB6 KllaisUOamvTTtPjic6nqgztIrsZwVGjjWK7vG8ozFTcCgp2HkZJ6X4LbSKvyuVkjT qcXbW0Ckyvbgso20/1phg1107C1gTiClR3Hj+lRcjG0M0Ki2RtZMhnjx3Mmkobv12K Xx2SF6Fu+XDxUx7rHArRgUS80ARKH6R5eLB3AJkRH4Tn9g3ZGexQwoFvU3DWzsHOsF 9xxpJNXwqQRN1HimKUC14dXXfdR2JKVwCqre7Kw9d/jzAuYtlvOVeUrVxp6AMWSvzO Dkxo8jLgLZv+w== From: Jiri Olsa To: Alexei Starovoitov , Andrii Nakryiko , Hao Luo , Andrew Morton , Alexander Viro , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Matthew Wilcox Cc: bpf@vger.kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-perf-users@vger.kernel.org, Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , Stanislav Fomichev , Daniel Borkmann , Namhyung Kim , Dave Chinner Subject: [PATCHv3 bpf-next 8/9] selftests/bpf: Add iter_task_vma_buildid test Date: Thu, 16 Mar 2023 18:01:48 +0100 Message-Id: <20230316170149.4106586-9-jolsa@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230316170149.4106586-1-jolsa@kernel.org> References: <20230316170149.4106586-1-jolsa@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Testing iterator access to build id in vma->vm_file object by storing each binary with build id into map and checking it against build id retrieved in user space. Signed-off-by: Jiri Olsa --- .../selftests/bpf/prog_tests/bpf_iter.c | 78 +++++++++++++++++++ .../bpf/progs/bpf_iter_task_vma_buildid.c | 56 +++++++++++++ 2 files changed, 134 insertions(+) create mode 100644 tools/testing/selftests/bpf/progs/bpf_iter_task_vma_buildid.c diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_iter.c b/tools/testing/selftests/bpf/prog_tests/bpf_iter.c index 1f02168103dd..c7dd89e7cad0 100644 --- a/tools/testing/selftests/bpf/prog_tests/bpf_iter.c +++ b/tools/testing/selftests/bpf/prog_tests/bpf_iter.c @@ -33,6 +33,7 @@ #include "bpf_iter_bpf_link.skel.h" #include "bpf_iter_ksym.skel.h" #include "bpf_iter_sockmap.skel.h" +#include "bpf_iter_task_vma_buildid.skel.h" static int duration; @@ -1536,6 +1537,81 @@ static void test_task_vma_dead_task(void) bpf_iter_task_vma__destroy(skel); } +#define D_PATH_BUF_SIZE 1024 + +struct build_id { + u32 sz; + char data[BPF_BUILD_ID_SIZE]; +}; + +static void test_task_vma_buildid(void) +{ + int err, iter_fd = -1, proc_maps_fd = -1, sz; + struct bpf_iter_task_vma_buildid *skel; + char key[D_PATH_BUF_SIZE], *prev_key; + char build_id[BPF_BUILD_ID_SIZE]; + int len, files_fd, cnt = 0; + struct build_id val; + char c; + + skel = bpf_iter_task_vma_buildid__open_and_load(); + if (!ASSERT_OK_PTR(skel, "bpf_iter_task_vma_buildid__open_and_load")) + return; + + skel->links.proc_maps = bpf_program__attach_iter( + skel->progs.proc_maps, NULL); + + if (!ASSERT_OK_PTR(skel->links.proc_maps, "bpf_program__attach_iter")) { + skel->links.proc_maps = NULL; + goto out; + } + + iter_fd = bpf_iter_create(bpf_link__fd(skel->links.proc_maps)); + if (!ASSERT_GE(iter_fd, 0, "create_iter")) + goto out; + + /* trigger the iterator, there's no output, just map */ + len = read(iter_fd, &c, 1); + ASSERT_EQ(len, 0, "len_check"); + + files_fd = bpf_map__fd(skel->maps.files); + + prev_key = NULL; + + while (true) { + err = bpf_map_get_next_key(files_fd, prev_key, &key); + if (err) { + if (errno == ENOENT) + err = 0; + break; + } + if (bpf_map_lookup_elem(files_fd, key, &val)) + break; + if (!ASSERT_LE(val.sz, BPF_BUILD_ID_SIZE, "buildid_size")) + break; + + sz = read_build_id(key, build_id); + /* If there's an error, the build id is not present or malformed, kernel + * should see the same result and bpf program pushed zero build id. + */ + if (sz < 0) { + memset(build_id, 0x0, BPF_BUILD_ID_SIZE); + sz = BPF_BUILD_ID_SIZE; + } + ASSERT_EQ(val.sz, sz, "build_id_size"); + ASSERT_MEMEQ(val.data, build_id, sz, "build_id_data"); + + prev_key = key; + cnt++; + } + + printf("checked %d files\n", cnt); +out: + close(proc_maps_fd); + close(iter_fd); + bpf_iter_task_vma_buildid__destroy(skel); +} + void test_bpf_sockmap_map_iter_fd(void) { struct bpf_iter_sockmap *skel; @@ -1659,6 +1735,8 @@ void test_bpf_iter(void) test_task_vma(); if (test__start_subtest("task_vma_dead_task")) test_task_vma_dead_task(); + if (test__start_subtest("task_vma_buildid")) + test_task_vma_buildid(); if (test__start_subtest("task_btf")) test_task_btf(); if (test__start_subtest("tcp4")) diff --git a/tools/testing/selftests/bpf/progs/bpf_iter_task_vma_buildid.c b/tools/testing/selftests/bpf/progs/bpf_iter_task_vma_buildid.c new file mode 100644 index 000000000000..11a59c0f1aba --- /dev/null +++ b/tools/testing/selftests/bpf/progs/bpf_iter_task_vma_buildid.c @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include "bpf_iter.h" +#include "err.h" +#include +#include + +char _license[] SEC("license") = "GPL"; + +#define VM_EXEC 0x00000004 +#define D_PATH_BUF_SIZE 1024 + +struct { + __uint(type, BPF_MAP_TYPE_HASH); + __uint(max_entries, 10000); + __type(key, char[D_PATH_BUF_SIZE]); + __type(value, struct build_id); +} files SEC(".maps"); + +static char path[D_PATH_BUF_SIZE]; +static struct build_id build_id; + +SEC("iter/task_vma") +int proc_maps(struct bpf_iter__task_vma *ctx) +{ + struct vm_area_struct *vma = ctx->vma; + struct task_struct *task = ctx->task; + struct file *file; + + if (task == (void *)0 || vma == (void *)0) + return 0; + + if (!(vma->vm_flags & VM_EXEC)) + return 0; + + file = vma->vm_file; + if (!file) + return 0; + + __builtin_memset(path, 0x0, D_PATH_BUF_SIZE); + bpf_d_path(&file->f_path, (char *) &path, D_PATH_BUF_SIZE); + + if (bpf_map_lookup_elem(&files, &path)) + return 0; + + if (IS_ERR_OR_NULL(file->f_build_id)) { + /* On error return empty build id. */ + __builtin_memset(&build_id.data, 0x0, sizeof(build_id.data)); + build_id.sz = BUILD_ID_SIZE_MAX; + } else { + __builtin_memcpy(&build_id, file->f_build_id, sizeof(*file->f_build_id)); + } + + bpf_map_update_elem(&files, &path, &build_id, 0); + return 0; +} From patchwork Thu Mar 16 17:01:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Olsa X-Patchwork-Id: 13178108 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 41BF6C7618B for ; Thu, 16 Mar 2023 17:05:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231495AbjCPREl (ORCPT ); Thu, 16 Mar 2023 13:04:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37266 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231474AbjCPREY (ORCPT ); Thu, 16 Mar 2023 13:04:24 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C4A0A7AB4; Thu, 16 Mar 2023 10:03:56 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id E2A5BB8227B; Thu, 16 Mar 2023 17:03:53 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 53045C433EF; Thu, 16 Mar 2023 17:03:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1678986232; bh=k3FKXivEZQL3axXlXOQ80+3Y8PlgcvRRWyE+8fiPDqw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HxOQsfSSGaoCqeogPae5AJUpOEd+YvVBDDuK+Eus7fUz8mbGY4O1QvXKR4yOLvQAA nn40HHqQ2kXbrnbDntkEm7qk9ztbPrj2IfSmKS+dfEEI+Uu8M/6aeuUXFhMI9axTfP HDkKdq5eKsi2Ix/bdr8XPpEslpQhCx7Qc5wgm0vwZYWd/45Z90H3PImim3RdiUWp1n 5AUn7e7JXRtiwiY9hQqUpXrbHw+IgKDUBiY/nzwm5WhYqV3qjk9ekZS9C5Zo5hARmK RJnlCcshgQi3iZksY69nnMeEW9c1TC7Plz9AHRDpGFuWX1cgHLvO4Hr0DTwXMfFjRk Tj4UwPziJK8aA== From: Jiri Olsa To: Alexei Starovoitov , Andrii Nakryiko , Hao Luo , Andrew Morton , Alexander Viro , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Matthew Wilcox Cc: bpf@vger.kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-perf-users@vger.kernel.org, Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , Stanislav Fomichev , Daniel Borkmann , Namhyung Kim , Dave Chinner Subject: [PATCHv3 bpf-next 9/9] selftests/bpf: Add file_build_id test Date: Thu, 16 Mar 2023 18:01:49 +0100 Message-Id: <20230316170149.4106586-10-jolsa@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230316170149.4106586-1-jolsa@kernel.org> References: <20230316170149.4106586-1-jolsa@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org The test attaches bpf program to sched_process_exec tracepoint and gets build of executed file from bprm->file object. We use urandom_read as the test program and in addition we also attach uprobe to liburandom_read.so:urandlib_read_without_sema and retrieve and check build id of that shared library. Also executing the no_build_id binary to verify the bpf program gets the error properly. Signed-off-by: Jiri Olsa Acked-by: Andrii Nakryiko --- tools/testing/selftests/bpf/Makefile | 7 +- tools/testing/selftests/bpf/no_build_id.c | 6 ++ .../selftests/bpf/prog_tests/file_build_id.c | 98 +++++++++++++++++++ .../selftests/bpf/progs/file_build_id.c | 70 +++++++++++++ tools/testing/selftests/bpf/test_progs.h | 10 ++ 5 files changed, 190 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/bpf/no_build_id.c create mode 100644 tools/testing/selftests/bpf/prog_tests/file_build_id.c create mode 100644 tools/testing/selftests/bpf/progs/file_build_id.c diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index 55811c448eb7..cf93a23c7962 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@ -88,7 +88,7 @@ TEST_GEN_PROGS_EXTENDED = test_sock_addr test_skb_cgroup_id_user \ xskxceiver xdp_redirect_multi xdp_synproxy veristat xdp_hw_metadata \ xdp_features -TEST_CUSTOM_PROGS = $(OUTPUT)/urandom_read $(OUTPUT)/sign-file +TEST_CUSTOM_PROGS = $(OUTPUT)/urandom_read $(OUTPUT)/sign-file $(OUTPUT)/no_build_id TEST_GEN_FILES += liburandom_read.so # Emit succinct information message describing current building step @@ -201,6 +201,10 @@ $(OUTPUT)/sign-file: ../../../../scripts/sign-file.c $< -o $@ \ $(shell $(HOSTPKG_CONFIG) --libs libcrypto 2> /dev/null || echo -lcrypto) +$(OUTPUT)/no_build_id: no_build_id.c + $(call msg,BINARY,,$@) + $(Q)$(CC) $^ -Wl,--build-id=none -o $@ + $(OUTPUT)/bpf_testmod.ko: $(VMLINUX_BTF) $(wildcard bpf_testmod/Makefile bpf_testmod/*.[ch]) $(call msg,MOD,,$@) $(Q)$(RM) bpf_testmod/bpf_testmod.ko # force re-compilation @@ -564,6 +568,7 @@ TRUNNER_EXTRA_FILES := $(OUTPUT)/urandom_read $(OUTPUT)/bpf_testmod.ko \ $(OUTPUT)/liburandom_read.so \ $(OUTPUT)/xdp_synproxy \ $(OUTPUT)/sign-file \ + $(OUTPUT)/no_build_id \ ima_setup.sh \ verify_sig_setup.sh \ $(wildcard progs/btf_dump_test_case_*.c) \ diff --git a/tools/testing/selftests/bpf/no_build_id.c b/tools/testing/selftests/bpf/no_build_id.c new file mode 100644 index 000000000000..a6f28f1c06d5 --- /dev/null +++ b/tools/testing/selftests/bpf/no_build_id.c @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 + +int main(void) +{ + return 0; +} diff --git a/tools/testing/selftests/bpf/prog_tests/file_build_id.c b/tools/testing/selftests/bpf/prog_tests/file_build_id.c new file mode 100644 index 000000000000..cb233cfd58cb --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/file_build_id.c @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include "file_build_id.skel.h" +#include "trace_helpers.h" + +static void +test_build_id(const char *bin, const char *lib, long bin_err, long lib_err) +{ + int err, child_pid = 0, child_status, c = 1, sz; + char build_id[BPF_BUILD_ID_SIZE]; + struct file_build_id *skel; + int go[2] = { -1, -1 }; + + if (!ASSERT_OK(pipe(go), "pipe")) + return; + + skel = file_build_id__open_and_load(); + if (!ASSERT_OK_PTR(skel, "file_build_id__open_and_load")) + goto out; + + child_pid = fork(); + if (child_pid < 0) + goto out; + + /* child */ + if (child_pid == 0) { + close(go[1]); + /* wait for parent's pid update */ + err = read(go[0], &c, 1); + if (!ASSERT_EQ(err, 1, "child_read_pipe")) + exit(err); + + execle(bin, bin, NULL, NULL); + exit(errno); + } + + /* parent, update child's pid and kick it */ + skel->bss->pid = child_pid; + + close(go[0]); + + err = file_build_id__attach(skel); + if (!ASSERT_OK(err, "file_build_id__attach")) + goto out; + + err = write(go[1], &c, 1); + if (!ASSERT_EQ(err, 1, "child_write_pipe")) + goto out; + + /* wait for child to exit */ + waitpid(child_pid, &child_status, 0); + child_pid = 0; + if (!ASSERT_EQ(WEXITSTATUS(child_status), 0, "child_exit_value")) + goto out; + + /* test binary */ + sz = read_build_id(bin, build_id); + err = sz > 0 ? 0 : sz; + + ASSERT_EQ((long) err, bin_err, "read_build_id_bin_err"); + ASSERT_EQ(skel->bss->build_id_bin_err, bin_err, "build_id_bin_err"); + + if (!err) { + ASSERT_EQ(skel->bss->build_id_bin_size, sz, "build_id_bin_size"); + ASSERT_MEMEQ(skel->bss->build_id_bin, build_id, sz, "build_id_bin"); + } + + /* test library if present */ + if (lib) { + sz = read_build_id(lib, build_id); + err = sz > 0 ? 0 : sz; + + ASSERT_EQ((long) err, lib_err, "read_build_id_lib_err"); + ASSERT_EQ(skel->bss->build_id_lib_err, lib_err, "build_id_lib_err"); + + if (!err) { + ASSERT_EQ(skel->bss->build_id_lib_size, sz, "build_id_lib_size"); + ASSERT_MEMEQ(skel->bss->build_id_lib, build_id, sz, "build_id_lib"); + } + } + +out: + close(go[1]); + close(go[0]); + if (child_pid) + waitpid(child_pid, &child_status, 0); + file_build_id__destroy(skel); +} + +void test_file_build_id(void) +{ + if (test__start_subtest("present")) + test_build_id("./urandom_read", "./liburandom_read.so", 0, 0); + if (test__start_subtest("missing")) + test_build_id("./no_build_id", NULL, -EINVAL, 0); +} diff --git a/tools/testing/selftests/bpf/progs/file_build_id.c b/tools/testing/selftests/bpf/progs/file_build_id.c new file mode 100644 index 000000000000..6dc10c8e17ac --- /dev/null +++ b/tools/testing/selftests/bpf/progs/file_build_id.c @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include "vmlinux.h" +#include "err.h" +#include +#include +#include + +char _license[] SEC("license") = "GPL"; + +int pid; + +u32 build_id_bin_size; +u32 build_id_lib_size; + +char build_id_bin[BUILD_ID_SIZE_MAX]; +char build_id_lib[BUILD_ID_SIZE_MAX]; + +long build_id_bin_err; +long build_id_lib_err; + +static int store_build_id(struct file *file, char *build_id, u32 *sz, long *err) +{ + struct build_id *bid; + + bid = file->f_build_id; + if (IS_ERR_OR_NULL(bid)) { + *err = PTR_ERR(bid); + return 0; + } + *sz = bid->sz; + if (bid->sz > sizeof(bid->data)) { + *err = 1; + return 0; + } + __builtin_memcpy(build_id, bid->data, sizeof(bid->data)); + *err = 0; + return 0; +} + +SEC("tp_btf/sched_process_exec") +int BPF_PROG(prog, struct task_struct *p, pid_t old_pid, struct linux_binprm *bprm) +{ + int cur_pid = bpf_get_current_pid_tgid() >> 32; + + if (pid != cur_pid) + return 0; + if (!bprm->file) + return 0; + return store_build_id(bprm->file, build_id_bin, &build_id_bin_size, &build_id_bin_err); +} + +static long check_vma(struct task_struct *task, struct vm_area_struct *vma, + void *data) +{ + if (!vma || !vma->vm_file || !vma->vm_file) + return 0; + return store_build_id(vma->vm_file, build_id_lib, &build_id_lib_size, &build_id_lib_err); +} + +SEC("uprobe/./liburandom_read.so:urandlib_read_without_sema") +int BPF_UPROBE(urandlib_read_without_sema) +{ + struct task_struct *task = bpf_get_current_task_btf(); + int cur_pid = bpf_get_current_pid_tgid() >> 32; + + if (pid != cur_pid) + return 0; + return bpf_find_vma(task, ctx->ip, check_vma, NULL, 0); +} diff --git a/tools/testing/selftests/bpf/test_progs.h b/tools/testing/selftests/bpf/test_progs.h index d91427bfe0d7..285dd5d91426 100644 --- a/tools/testing/selftests/bpf/test_progs.h +++ b/tools/testing/selftests/bpf/test_progs.h @@ -310,6 +310,16 @@ int test__join_cgroup(const char *path); ___ok; \ }) +#define ASSERT_MEMEQ(actual, expected, sz, name) ({ \ + static int duration = 0; \ + const char *___act = actual; \ + const char *___exp = expected; \ + bool ___ok = memcmp(___act, ___exp, sz) == 0; \ + CHECK(!___ok, (name), \ + "unexpected %s does not match\n", (name)); \ + ___ok; \ +}) + #define ASSERT_STRNEQ(actual, expected, len, name) ({ \ static int duration = 0; \ const char *___act = actual; \