diff --git a/rhbz1650371.patch b/rhbz1650371.patch new file mode 100644 index 0000000..7401c66 --- /dev/null +++ b/rhbz1650371.patch @@ -0,0 +1,134 @@ +commit fba365b4d365f54ab7ef60272996dc2889461640 +Author: Frank Ch. Eigler +Date: Thu Nov 15 16:27:58 2018 -0500 + + PR23890: tolerate f29+ style ELF files + + Reported by kenj@pcp, with mjw et al.'s help, we found out why + systemtap on fedora 29+ routinely fails to verify build-ids for + userspace programs. F29 adds a separate loadable segment with the + relevante .note's, before the main text segment. The runtime code + that listens to mmaps-in-progress now accepts this configuration. + As long as the .note section is loaded (time-wise and space-wise) + before the .text one(s), we're good. + +diff --git a/runtime/linux/uprobes-inode.c b/runtime/linux/uprobes-inode.c +index 6d450c90d87c..b9604e6385ce 100644 +--- a/runtime/linux/uprobes-inode.c ++++ b/runtime/linux/uprobes-inode.c +@@ -563,9 +563,11 @@ stapiu_change_plus(struct stapiu_target* target, struct task_struct *task, + return rc; + } + +- /* Actually do the check. */ ++ /* Actually do the check. NB: on F29+, offset may not equal 0 ++ for LOADable "R E" segments, because the read-only .note.* ++ stuff may have been loaded earlier, separately. PR23890. */ + if ((rc = _stp_usermodule_check(task, target->filename, +- relocation))) { ++ relocation - offset))) { + /* Be sure to release the inode on failure. */ + iput(target->inode); + target->inode = NULL; + +commit 824e9ab80108c1882842fc2a4b4abd1aee990ecc (upstream/master) +Author: Frank Ch. Eigler +Date: Thu Nov 15 20:22:34 2018 -0500 + + PR23890 bonus: show nicer messages upon a buildid mismatch + + Instead of producing only a one-byte error, we now compute the entire + builds into hex text strings, and report the whole shebang on an + error. (Also, ditch some 2.6.27 kernel-bug compatibiltiy fossil + in the area.) + +diff --git a/runtime/sym.c b/runtime/sym.c +index 60f0fa980964..111147ee555d 100644 +--- a/runtime/sym.c ++++ b/runtime/sym.c +@@ -636,30 +636,46 @@ unsigned long _stp_linenumber_lookup(unsigned long addr, struct task_struct *tas + return 0; + } + ++ ++// Compare two build-id hex strings, each of length m->build_id_len bytes. ++// Since mismatches can mystify, produce a hex-textual version of both ++// expected and actual strings, and compare textually. Failure messages ++// are more intelligible this way. + static int _stp_build_id_check (struct _stp_module *m, + unsigned long notes_addr, + struct task_struct *tsk) + { +- int j; ++ enum { max_buildid_hexstring = 65 }; ++ static const char hexnibble[16]="0123456789abcdef"; ++ char hexstring_theory[max_buildid_hexstring], hexstring_practice[max_buildid_hexstring]; ++ int buildid_len = min((max_buildid_hexstring-1)/2, m->build_id_len); ++ ++ int i, j; ++ ++ memset(hexstring_theory, '\0', max_buildid_hexstring); ++ for (i=0, j=0; jbuild_id_bits[j]; ++ hexstring_theory[i++] = hexnibble[theory >> 4]; ++ hexstring_theory[i++] = hexnibble[theory & 15]; ++ } + +- for (j = 0; j < m->build_id_len; j++) { ++ memset(hexstring_practice, '\0', max_buildid_hexstring); ++ for (i=0, j=0; jbuild_id_bits[j]; + set_fs(KERNEL_DS); + rc = probe_kernel_read(&practice, (void*)(notes_addr + j), 1); + } + else + #endif + { +- theory = m->build_id_bits[j]; + set_fs (tsk ? USER_DS : KERNEL_DS); + + /* +@@ -685,21 +701,19 @@ static int _stp_build_id_check (struct _stp_module *m, + } + set_fs(oldfs); + +- if (rc || (theory != practice)) { +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) +- _stp_error ("Build-id mismatch [man error::buildid]: \"%s\" byte %d (0x%02x vs 0x%02x) address %#lx rc %d\n", +- m->path, j, theory, practice, notes_addr, rc); ++ if (rc == 0) { // got actual data byte ++ hexstring_practice[i++] = hexnibble[practice >> 4]; ++ hexstring_practice[i++] = hexnibble[practice & 15]; ++ } ++ } ++ ++ // have two strings, will travel ++ if (strcmp (hexstring_practice, hexstring_theory)) { ++ _stp_error ("Build-id mismatch [man error::buildid]: \"%s\" address %#lx, expected %s actual %s\n", ++ m->path, notes_addr, hexstring_theory, hexstring_practice); + return 1; +-#else +- /* This branch is a surrogate for kernels affected by Fedora bug +- * #465873. */ +- _stp_warn (KERN_WARNING +- "Build-id mismatch [man error::buildid]: \"%s\" byte %d (0x%02x vs 0x%02x) rc %d\n", +- m->path, j, theory, practice, rc); +-#endif +- break; +- } /* end mismatch */ +- } /* end per-byte check loop */ ++ } ++ + return 0; + } + diff --git a/systemtap.spec b/systemtap.spec index afd579f..d430575 100644 --- a/systemtap.spec +++ b/systemtap.spec @@ -84,7 +84,7 @@ Name: systemtap Version: 4.0 -Release: 1%{?release_override}%{?dist} +Release: 2%{?release_override}%{?dist} # for version, see also configure.ac @@ -121,6 +121,8 @@ License: GPLv2+ URL: http://sourceware.org/systemtap/ Source: ftp://sourceware.org/pub/systemtap/releases/systemtap-%{version}.tar.gz +Patch10: rhbz1650371.patch + # Build* BuildRequires: gcc-c++ BuildRequires: cpio @@ -529,6 +531,8 @@ find . \( -name configure -o -name config.h.in \) -print | xargs touch cd .. %endif +%patch10 -p1 + %build %if %{with_bundled_elfutils} @@ -1271,6 +1275,9 @@ done # PRERELEASE %changelog +* Thu Nov 15 2018 Frank Ch. Eigler - 4.0-2 +- rhbz1650371 - buildid mismatch for uprobes + * Sat Oct 13 2018 Frank Ch. Eigler - 4.0-1 - Upstream release.