From rmetrich at redhat.com Fri Mar 5 14:04:47 2021 From: rmetrich at redhat.com (=?UTF-8?Q?Renaud_M=c3=a9trich?=) Date: Fri, 5 Mar 2021 15:04:47 +0100 Subject: Proposing SELinux support in strace In-Reply-To: <2b816386-321d-5db6-6b84-19f987404863@redhat.com> References: <6a2213eb-d915-cbdd-36dd-3e68db47adc5@redhat.com> <20201117094724.GA4645@altlinux.org> <20201117112447.GB5280@altlinux.org> <2fd00185-9fc7-20e0-bc63-b3725c92c7d8@redhat.com> <20201121013040.GB815@altlinux.org> <9e17d94c-612f-3ab3-d6bd-da5d14de101b@redhat.com> <20210119231326.GA15157@altlinux.org> <20210217001009.GA8097@altlinux.org> <2b816386-321d-5db6-6b84-19f987404863@redhat.com> Message-ID: <8553b7c6-a0fa-e202-4f0d-edb8a878a697@redhat.com> Dear all, I reworked the code and created some unit tests. (PR https://github.com/strace/strace/pull/121) Unfortunately I'm not able to build correctly under the CI for several reasons: - code coverage breaks because the CI system has no SELinux labels, hence the new code is not covered - compilation with -m32 fails because there is no suitable selinux library for 32bits apparently e.g. 2021-03-05T13:17:54.4436301Z gcc-10 -Wall -Wempty-body -Wformat-security -Wignored-qualifiers -Wimplicit-fallthrough=5 -Winit-self -Wlogical-op -Wmissing-parameter-type -Wnested-externs -Wold-style-declaration -Wold-style-definition -Woverride-init -Wsign-compare -Wtype-limits -Wwrite-strings -Werror -g -O2 -DMPERS_IS_m32 -m32? -o chmod--secontext chmod--secontext.o -lselinux libtests.a 2021-03-05T13:17:54.4515828Z /usr/bin/ld: skipping incompatible /usr/lib/x86_64-linux-gnu/libselinux.a when searching for -lselinux 2021-03-05T13:17:54.4517295Z /usr/bin/ld: cannot find -lselinux 2021-03-05T13:17:54.4518771Z /usr/bin/ld: skipping incompatible /usr/lib/x86_64-linux-gnu/libselinux.so when searching for -lselinux 2021-03-05T13:17:54.4520200Z /usr/bin/ld: skipping incompatible /usr/lib/x86_64-linux-gnu/libselinux.a when searching for -lselinux 2021-03-05T13:17:54.4521300Z /usr/bin/ld: cannot find -lselinux 2021-03-05T13:17:54.4522032Z collect2: error: ld returned 1 exit status I have no idea what needs to be done to fix this. All I see is configure enables selinux support because the 64bit lib is installed, but apparently not the 32bit one. Renaud On 2/17/21 8:43 AM, Renaud M?trich wrote: > So far I modified the code to check for the mount namespace used by > the tracee and strace and avoid doing any selinux context resolution > upon having non-matching namespaces. > > I've also fixed the relative pathname issue by storing the dirfd and > checking against it if needed. > > However this also doesn't work all the time, in particular when the > relative path is beyond the rootdir of the process (because ../../../ > on "/" returns "/"). > > So there are clearly limitations I cannot handle easily for now. > > I will continue working on this after Devconf, in particular writing > new test cases. > > I'm already using this patch when debugging Red Hat customers issues > and so far it was really of great help already. > > Renaud. > > On 2/17/21 1:10 AM, Dmitry V. Levin wrote: >> On Thu, Jan 21, 2021 at 01:00:08PM +0100, Renaud M?trich wrote: >>> Right, it's broken, that cannot work all the time... >> Right, what do you suggest to do with that brokenness? >> >>> On 1/20/21 12:13 AM, Dmitry V. Levin wrote: >>>> On Sat, Nov 21, 2020 at 09:08:45PM +0100, Renaud M?trich wrote: >>>> [...] >>>>>> By the way, is it correct to hook selinux_getfilecon into >>>>>> printpathn? >>>>> I agree it's kind of a "hack", using "printpathn" is just the >>>>> simplest >>>>> way to get SELinux contexts when a path is used. >>>> How likely for the result to be correct if strace and the tracee have >>>> different root fs?? Also, would the result be correct when the path >>>> printed >>>> by printpathn is not an absolute file name? >>>> >>>> ? From implementation point of view, looks like you hooked into >>>> printpathn >>>> in a way that a non-nul-terminated string may be passed to >>>> selinux_getfilecon. >>>> >>>>>> Also, do you want to display secontext associated with file >>>>>> descriptors? >>>>> Thanks to hooking "printpathn", the context for file descriptors will >>>>> also be printed, e.g.: >>>>> >>>>> [unconfined_t] ... read(3 [lib_t], >>>>> "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\320\207\0\0\0\0\0\0"..., >>>>> >>>>> 832) = 832 <0.000015> >>>>> >>>>> That's why hooking "printpathn" is great here. >>>> You've explicitly hooked into printfd_pid to achieve that, haven't >>>> you? >> > -------------- next part -------------- A non-text attachment was scrubbed... Name: OpenPGP_signature Type: application/pgp-signature Size: 840 bytes Desc: OpenPGP digital signature URL: From ldv at altlinux.org Fri Mar 5 14:18:20 2021 From: ldv at altlinux.org (Dmitry V. Levin) Date: Fri, 5 Mar 2021 17:18:20 +0300 Subject: Proposing SELinux support in strace In-Reply-To: <8553b7c6-a0fa-e202-4f0d-edb8a878a697@redhat.com> References: <20201117112447.GB5280@altlinux.org> <2fd00185-9fc7-20e0-bc63-b3725c92c7d8@redhat.com> <20201121013040.GB815@altlinux.org> <9e17d94c-612f-3ab3-d6bd-da5d14de101b@redhat.com> <20210119231326.GA15157@altlinux.org> <20210217001009.GA8097@altlinux.org> <2b816386-321d-5db6-6b84-19f987404863@redhat.com> <8553b7c6-a0fa-e202-4f0d-edb8a878a697@redhat.com> Message-ID: <20210305141819.GB14087@altlinux.org> On Fri, Mar 05, 2021 at 03:04:47PM +0100, Renaud M?trich wrote: > Dear all, > > I reworked the code and created some unit tests. (PR > https://github.com/strace/strace/pull/121) > > Unfortunately I'm not able to build correctly under the CI for several > reasons: > > - code coverage breaks because the CI system has no SELinux labels, > hence the new code is not covered Unfortunately, github actions don't enable some Linux features. For example, they have no kvm support. But I think you can collect the coverage locally, publish it somewhere, and post the link here. > - compilation with -m32 fails because there is no suitable selinux > library for 32bits apparently > > e.g. > > 2021-03-05T13:17:54.4436301Z gcc-10 -Wall -Wempty-body -Wformat-security > -Wignored-qualifiers -Wimplicit-fallthrough=5 -Winit-self -Wlogical-op > -Wmissing-parameter-type -Wnested-externs -Wold-style-declaration > -Wold-style-definition -Woverride-init -Wsign-compare -Wtype-limits > -Wwrite-strings -Werror -g -O2 -DMPERS_IS_m32 -m32? -o chmod--secontext > chmod--secontext.o -lselinux libtests.a > 2021-03-05T13:17:54.4515828Z /usr/bin/ld: skipping incompatible > /usr/lib/x86_64-linux-gnu/libselinux.a when searching for -lselinux > 2021-03-05T13:17:54.4517295Z /usr/bin/ld: cannot find -lselinux > 2021-03-05T13:17:54.4518771Z /usr/bin/ld: skipping incompatible > /usr/lib/x86_64-linux-gnu/libselinux.so when searching for -lselinux > 2021-03-05T13:17:54.4520200Z /usr/bin/ld: skipping incompatible > /usr/lib/x86_64-linux-gnu/libselinux.a when searching for -lselinux > 2021-03-05T13:17:54.4521300Z /usr/bin/ld: cannot find -lselinux > 2021-03-05T13:17:54.4522032Z collect2: error: ld returned 1 exit status > > I have no idea what needs to be done to fix this. All I see is configure > enables selinux support because the 64bit lib is installed, but > apparently not the 32bit one. I suggest to implement something in m4/mpers.m4, similar to the way AC_CHECK_SIZEOF is used there, so that selinux tests could be enabled per mpers depending on the runtime availability. -- ldv From rmetrich at redhat.com Mon Mar 8 16:12:17 2021 From: rmetrich at redhat.com (=?UTF-8?Q?Renaud_M=c3=a9trich?=) Date: Mon, 8 Mar 2021 17:12:17 +0100 Subject: Proposing SELinux support in strace In-Reply-To: <20210305141819.GB14087@altlinux.org> References: <20201117112447.GB5280@altlinux.org> <2fd00185-9fc7-20e0-bc63-b3725c92c7d8@redhat.com> <20201121013040.GB815@altlinux.org> <9e17d94c-612f-3ab3-d6bd-da5d14de101b@redhat.com> <20210119231326.GA15157@altlinux.org> <20210217001009.GA8097@altlinux.org> <2b816386-321d-5db6-6b84-19f987404863@redhat.com> <8553b7c6-a0fa-e202-4f0d-edb8a878a697@redhat.com> <20210305141819.GB14087@altlinux.org> Message-ID: Hello, Please check the newer code on github (https://github.com/strace/strace/pull/121), I consider it's complete now. The "*CI / coverage*" and "*CI / clang10-x86_64-dw (pull_request)*" fail because of a test not related to the change (*pidns-cache.test* taking too much time). Renaud. On 3/5/21 3:18 PM, Dmitry V. Levin wrote: > On Fri, Mar 05, 2021 at 03:04:47PM +0100, Renaud M?trich wrote: >> Dear all, >> >> I reworked the code and created some unit tests. (PR >> https://github.com/strace/strace/pull/121) >> >> Unfortunately I'm not able to build correctly under the CI for several >> reasons: >> >> - code coverage breaks because the CI system has no SELinux labels, >> hence the new code is not covered > Unfortunately, github actions don't enable some Linux features. > For example, they have no kvm support. > But I think you can collect the coverage locally, publish it somewhere, > and post the link here. > >> - compilation with -m32 fails because there is no suitable selinux >> library for 32bits apparently >> >> e.g. >> >> 2021-03-05T13:17:54.4436301Z gcc-10 -Wall -Wempty-body -Wformat-security >> -Wignored-qualifiers -Wimplicit-fallthrough=5 -Winit-self -Wlogical-op >> -Wmissing-parameter-type -Wnested-externs -Wold-style-declaration >> -Wold-style-definition -Woverride-init -Wsign-compare -Wtype-limits >> -Wwrite-strings -Werror -g -O2 -DMPERS_IS_m32 -m32? -o chmod--secontext >> chmod--secontext.o -lselinux libtests.a >> 2021-03-05T13:17:54.4515828Z /usr/bin/ld: skipping incompatible >> /usr/lib/x86_64-linux-gnu/libselinux.a when searching for -lselinux >> 2021-03-05T13:17:54.4517295Z /usr/bin/ld: cannot find -lselinux >> 2021-03-05T13:17:54.4518771Z /usr/bin/ld: skipping incompatible >> /usr/lib/x86_64-linux-gnu/libselinux.so when searching for -lselinux >> 2021-03-05T13:17:54.4520200Z /usr/bin/ld: skipping incompatible >> /usr/lib/x86_64-linux-gnu/libselinux.a when searching for -lselinux >> 2021-03-05T13:17:54.4521300Z /usr/bin/ld: cannot find -lselinux >> 2021-03-05T13:17:54.4522032Z collect2: error: ld returned 1 exit status >> >> I have no idea what needs to be done to fix this. All I see is configure >> enables selinux support because the 64bit lib is installed, but >> apparently not the 32bit one. > I suggest to implement something in m4/mpers.m4, similar to the way > AC_CHECK_SIZEOF is used there, so that selinux tests could be enabled per > mpers depending on the runtime availability. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: OpenPGP_signature Type: application/pgp-signature Size: 840 bytes Desc: OpenPGP digital signature URL: From amerey at redhat.com Mon Mar 8 17:53:21 2021 From: amerey at redhat.com (Aaron Merey) Date: Mon, 8 Mar 2021 12:53:21 -0500 Subject: [RFC] Add gdb remote protocol backend to strace Message-ID: Hello, I'm interested in updating the patch that adds a gdb remote protocol backend (https://lists.strace.io/pipermail/strace-devel/2020-December/010284.html) in order to prepare it for merging. As it stands we need to rebase the patch on top of the current master branch, fix any whitespace/formatting issues and split the patch into chunks which all pass the testsuite. Any suggestions on how to best split up the patch so that it's easier to review? Are there any particular ways of organizing these changes that you are looking for? Thanks, Aaron Merey From rmetrich at redhat.com Wed Mar 10 09:42:21 2021 From: rmetrich at redhat.com (=?UTF-8?Q?Renaud_M=c3=a9trich?=) Date: Wed, 10 Mar 2021 10:42:21 +0100 Subject: Proposing SELinux support in strace In-Reply-To: References: <20201117112447.GB5280@altlinux.org> <2fd00185-9fc7-20e0-bc63-b3725c92c7d8@redhat.com> <20201121013040.GB815@altlinux.org> <9e17d94c-612f-3ab3-d6bd-da5d14de101b@redhat.com> <20210119231326.GA15157@altlinux.org> <20210217001009.GA8097@altlinux.org> <2b816386-321d-5db6-6b84-19f987404863@redhat.com> <8553b7c6-a0fa-e202-4f0d-edb8a878a697@redhat.com> <20210305141819.GB14087@altlinux.org> Message-ID: Hello, Please find the latest patch attached. PR's build is green. Renaud. On 3/8/21 5:12 PM, Renaud M?trich wrote: > > Hello, > > Please check the newer code on github > (https://github.com/strace/strace/pull/121), I consider it's complete now. > > The "*CI / coverage*" and "*CI / clang10-x86_64-dw (pull_request)*" > fail because of a test not related to the change (*pidns-cache.test* > taking too much time). > > Renaud. > > On 3/5/21 3:18 PM, Dmitry V. Levin wrote: >> On Fri, Mar 05, 2021 at 03:04:47PM +0100, Renaud M?trich wrote: >>> Dear all, >>> >>> I reworked the code and created some unit tests. (PR >>> https://github.com/strace/strace/pull/121) >>> >>> Unfortunately I'm not able to build correctly under the CI for several >>> reasons: >>> >>> - code coverage breaks because the CI system has no SELinux labels, >>> hence the new code is not covered >> Unfortunately, github actions don't enable some Linux features. >> For example, they have no kvm support. >> But I think you can collect the coverage locally, publish it somewhere, >> and post the link here. >> >>> - compilation with -m32 fails because there is no suitable selinux >>> library for 32bits apparently >>> >>> e.g. >>> >>> 2021-03-05T13:17:54.4436301Z gcc-10 -Wall -Wempty-body -Wformat-security >>> -Wignored-qualifiers -Wimplicit-fallthrough=5 -Winit-self -Wlogical-op >>> -Wmissing-parameter-type -Wnested-externs -Wold-style-declaration >>> -Wold-style-definition -Woverride-init -Wsign-compare -Wtype-limits >>> -Wwrite-strings -Werror -g -O2 -DMPERS_IS_m32 -m32? -o chmod--secontext >>> chmod--secontext.o -lselinux libtests.a >>> 2021-03-05T13:17:54.4515828Z /usr/bin/ld: skipping incompatible >>> /usr/lib/x86_64-linux-gnu/libselinux.a when searching for -lselinux >>> 2021-03-05T13:17:54.4517295Z /usr/bin/ld: cannot find -lselinux >>> 2021-03-05T13:17:54.4518771Z /usr/bin/ld: skipping incompatible >>> /usr/lib/x86_64-linux-gnu/libselinux.so when searching for -lselinux >>> 2021-03-05T13:17:54.4520200Z /usr/bin/ld: skipping incompatible >>> /usr/lib/x86_64-linux-gnu/libselinux.a when searching for -lselinux >>> 2021-03-05T13:17:54.4521300Z /usr/bin/ld: cannot find -lselinux >>> 2021-03-05T13:17:54.4522032Z collect2: error: ld returned 1 exit status >>> >>> I have no idea what needs to be done to fix this. All I see is configure >>> enables selinux support because the 64bit lib is installed, but >>> apparently not the 32bit one. >> I suggest to implement something in m4/mpers.m4, similar to the way >> AC_CHECK_SIZEOF is used there, so that selinux tests could be enabled per >> mpers depending on the runtime availability. >> >> -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-Print-SELinux-contexts-when-enabling-secontext-full-.patch Type: text/x-patch Size: 83991 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: OpenPGP_signature Type: application/pgp-signature Size: 840 bytes Desc: OpenPGP digital signature URL: From baruch at tkos.co.il Thu Mar 11 04:51:10 2021 From: baruch at tkos.co.il (Baruch Siach) Date: Thu, 11 Mar 2021 06:51:10 +0200 Subject: [PATCH] disable_ptrace_get_syscall_info, disable_ptrace_getregset: require fork() Message-ID: <84536a993417f3bfff4a54830fa34a3f91f5716e.1615438270.git.baruch@tkos.co.il> These helper programs require fork(), so they are incompatible with no-MMU systems. Make the code depend on HAVE_FORK. --- src/disable_ptrace_request.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/disable_ptrace_request.c b/src/disable_ptrace_request.c index 57163e77f0f4..715006941572 100644 --- a/src/disable_ptrace_request.c +++ b/src/disable_ptrace_request.c @@ -41,7 +41,8 @@ init(int argc, char **argv) && defined PR_SET_NO_NEW_PRIVS \ && defined PR_SET_SECCOMP \ && defined BPF_JUMP \ - && defined BPF_STMT + && defined BPF_STMT \ + && defined HAVE_FORK static unsigned int get_arch(void) -- 2.30.1 From ldv at altlinux.org Fri Mar 12 01:19:44 2021 From: ldv at altlinux.org (Dmitry V. Levin) Date: Fri, 12 Mar 2021 04:19:44 +0300 Subject: [PATCH] disable_ptrace_get_syscall_info, disable_ptrace_getregset: require fork() In-Reply-To: <84536a993417f3bfff4a54830fa34a3f91f5716e.1615438270.git.baruch@tkos.co.il> References: <84536a993417f3bfff4a54830fa34a3f91f5716e.1615438270.git.baruch@tkos.co.il> Message-ID: <20210312011944.GA20940@altlinux.org> On Thu, Mar 11, 2021 at 06:51:10AM +0200, Baruch Siach wrote: > These helper programs require fork(), so they are incompatible with > no-MMU systems. Make the code depend on HAVE_FORK. > --- > src/disable_ptrace_request.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/src/disable_ptrace_request.c b/src/disable_ptrace_request.c > index 57163e77f0f4..715006941572 100644 > --- a/src/disable_ptrace_request.c > +++ b/src/disable_ptrace_request.c > @@ -41,7 +41,8 @@ init(int argc, char **argv) > && defined PR_SET_NO_NEW_PRIVS \ > && defined PR_SET_SECCOMP \ > && defined BPF_JUMP \ > - && defined BPF_STMT > + && defined BPF_STMT \ > + && defined HAVE_FORK > > static unsigned int > get_arch(void) Applied, thanks. -- ldv From srikavinramkumar at gmail.com Sun Mar 14 22:34:38 2021 From: srikavinramkumar at gmail.com (Srikavin Ramkumar) Date: Sun, 14 Mar 2021 18:34:38 -0400 Subject: [GSOC] Introduction and Microproject Message-ID: Hi everyone, I'm Srikavin, and I'm currently studying Computer Science and Math at University of Maryland. I have experience with C and a working understanding of system internals, and I've used strace in the past to aid with reverse engineering unknown binaries. I have not decided on a project idea yet, but I'm looking at "Implement a syscall parser / parser test generator". I'm still gaining an understanding of syzkaller's syscall representation [1] and strace's internals. Would writing more tests for prctl.c [2] be a good microproject? [1]: https://github.com/google/syzkaller/blob/master/docs/syscall_descriptions_syntax.md [2]: https://codecov.io/gh/strace/strace/src/master/src/prctl.c -- Srikavin Ramkumar From ldv at altlinux.org Mon Mar 15 01:10:00 2021 From: ldv at altlinux.org (Dmitry V. Levin) Date: Mon, 15 Mar 2021 04:10:00 +0300 Subject: Proposing SELinux support in strace In-Reply-To: References: <20201121013040.GB815@altlinux.org> <9e17d94c-612f-3ab3-d6bd-da5d14de101b@redhat.com> <20210119231326.GA15157@altlinux.org> <20210217001009.GA8097@altlinux.org> <2b816386-321d-5db6-6b84-19f987404863@redhat.com> <8553b7c6-a0fa-e202-4f0d-edb8a878a697@redhat.com> <20210305141819.GB14087@altlinux.org> Message-ID: <20210315011000.GA3123@altlinux.org> Hi, On Wed, Mar 10, 2021 at 10:42:21AM +0100, Renaud M?trich wrote: > Hello, > > Please find the latest patch attached. PR's build is green. Thanks, this is a big step forward. I've got quite a few comments, see below. > --- a/bootstrap > +++ b/bootstrap > @@ -24,11 +24,17 @@ for m in m32 mx32; do > s/^MPERS_NAME$s=.*/& $m/; > s/^\\(CC$s=\\).*/\\1 @CC_FOR_${m_upper}@/; > s/^MPERS_CC_FLAGS$s=.*/& @CFLAGS_FOR_${m_upper}@ @cc_flags_$m@/; > - s/^ARCH_MFLAGS$s=.*/& -DMPERS_IS_\$(MPERS_NAME) \$(MPERS_CC_FLAGS)/" \ > + s/^ARCH_MFLAGS$s=.*/& -DMPERS_IS_\$(MPERS_NAME) \$(MPERS_CC_FLAGS)/; \ > + s/HAVE_SELINUX_RUNTIME/HAVE_${m_upper}_SELINUX_RUNTIME/" \ > tests/Makefile.am > $tests/Makefile.am > for f in tests/*; do > - case "${f##*/}" in > + fname="${f##*/}" > + case "$fname" in > Makefile*) continue;; > + *--secontext.c) > + sed "s/HAVE_SELINUX_RUNTIME/HAVE_${m_upper}_SELINUX_RUNTIME/" \ > + "$f" > $tests/"$fname" > + continue;; > esac > ln -s ../"$f" $tests/ > done OK > diff --git a/configure.ac b/configure.ac > index f801dc677..7e3194216 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -619,6 +619,8 @@ AC_CHECK_TOOL([READELF], [readelf]) > > st_STACKTRACE > > +st_SELINUX > + > if test "$arch" = mips && test "$no_create" != yes; then > mkdir -p src/linux/mips > if $srcdir/src/linux/mips/genstub.sh \ OK > diff --git a/m4/mpers.m4 b/m4/mpers.m4 > index 510aabe84..c1c5d38f1 100644 > --- a/m4/mpers.m4 > +++ b/m4/mpers.m4 > @@ -63,9 +63,11 @@ pushdef([mpers_name], [$1]) > pushdef([MPERS_NAME], translit([$1], [a-z], [A-Z])) > pushdef([HAVE_MPERS], [HAVE_]MPERS_NAME[_MPERS]) > pushdef([HAVE_RUNTIME], [HAVE_]MPERS_NAME[_RUNTIME]) > +pushdef([HAVE_SELINUX_RUNTIME], [HAVE_]MPERS_NAME[_SELINUX_RUNTIME]) > pushdef([MPERS_CFLAGS], [$cc_flags_$1]) > pushdef([st_cv_cc], [st_cv_$1_cc]) > pushdef([st_cv_runtime], [st_cv_$1_runtime]) > +pushdef([st_cv_selinux_runtime], [st_cv_$1_selinux_runtime]) > pushdef([st_cv_mpers], [st_cv_$1_mpers]) > > pushdef([EXEEXT], MPERS_NAME[_EXEEXT])dnl OK > @@ -126,6 +128,18 @@ case "$arch" in > else > st_cv_mpers=no > fi]) > + AC_CACHE_CHECK([whether selinux runtime works with mpers_name personality], > + [st_cv_selinux_runtime], > + [ > + saved_LIBS="$LIBS" > + LIBS="-lselinux $LIBS" > + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], > + [[return 0]])], > + [st_cv_selinux_runtime=yes], > + [st_cv_selinux_runtime=no], > + [st_cv_selinux_runtime=no]) > + LIBS="$saved_LIBS" > + ]) > if test $st_cv_mpers = yes; then > AC_DEFINE(HAVE_MPERS, [1], > [Define to 1 if you have mpers_name mpers support]) Since st_MPERS code is executed after st_SELINUX, its results can be used here. If with_secontexts was set to "no" by st_SELINUX, there is no need to bother about selinux runtime here. Also, if st_cv_runtime was set to "no" by earlier checks, there is no need to check selinux runtime either. For example: AS_IF([test "x$with_secontexts$st_cv_mpers$st_cv_runtime" = xyesyesyes], [AC_CACHE_CHECK([whether selinux runtime works with mpers_name personality], [st_cv_selinux_runtime], [saved_CPPFLAGS="$CPPFLAGS" saved_LDFLAGS="$LDFLAGS" saved_LIBS="$LIBS" CPPFLAGS="$CPPFLAGS libselinux_CPPFLAGS" LDFLAGS="$LDFLAGS libselinux_LDFLAGS" LIBS="$LIBS libselinux_LIBS" AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[return 0]])], [st_cv_selinux_runtime=yes], [st_cv_selinux_runtime=no], [st_cv_selinux_runtime=no]) LIBS="$saved_LIBS" LDFLAGS="$saved_LDFLAGS" CPPFLAGS="$saved_CPPFLAGS" ]) ], [st_cv_selinux_runtime=no]) > @@ -165,6 +179,7 @@ case "$arch" in > *) # case "$enable_mpers" > st_cv_runtime=no > st_cv_mpers=no > + st_cv_selinux_runtime=no > ;; > esac > > @@ -187,6 +202,7 @@ case "$arch" in > esac > > AM_CONDITIONAL(HAVE_RUNTIME, [test "$st_cv_mpers$st_cv_runtime" = yesyes]) > +AM_CONDITIONAL(HAVE_SELINUX_RUNTIME, [test "$st_cv_mpers$st_cv_selinux_runtime" = yesyes]) > AM_CONDITIONAL(HAVE_MPERS, [test "$st_cv_mpers" = yes]) > > st_RESTORE_VAR([CC]) > @@ -201,9 +217,11 @@ popdef([EXEEXT])dnl > > popdef([st_cv_mpers]) > popdef([st_cv_runtime]) > +popdef([st_cv_selinux_runtime]) > popdef([st_cv_cc]) > popdef([MPERS_CFLAGS]) > popdef([HAVE_RUNTIME]) > +popdef([HAVE_SELINUX_RUNTIME]) > popdef([HAVE_MPERS]) > popdef([MPERS_NAME]) > popdef([mpers_name]) OK > diff --git a/m4/st_selinux.m4 b/m4/st_selinux.m4 > new file mode 100644 > index 000000000..e9f1eda84 > --- /dev/null > +++ b/m4/st_selinux.m4 > @@ -0,0 +1,80 @@ > +#!/usr/bin/m4 > +# > +# Copyright (c) 2020 The strace developers. > +# All rights reserved. > +# > +# SPDX-License-Identifier: LGPL-2.1-or-later > + > +AC_DEFUN([st_SELINUX], [dnl > + > +libselinux_CPPFLAGS= > +libselinux_LDFLAGS= > +libselinux_LIBS= > +with_secontexts=no > + > +AC_ARG_WITH([libselinux], > + [AS_HELP_STRING([--with-libselinux], > + [use libselinux to collect security contexts])], > + [case "${withval}" in > + yes|no|check) ;; > + *) with_libselinux=yes > + libselinux_CPPFLAGS="-I${withval}/include" > + libselinux_LDFLAGS="-L${withval}/lib" ;; > + esac], > + [with_libselinux=check] > +) > + > +AS_IF([test "x$with_libselinux" != xno], > + [saved_CPPFLAGS="$CPPFLAGS" > + CPPFLAGS="$CPPFLAGS $libselinux_CPPFLAGS" > + found_selinux_h=no > + AC_CHECK_HEADERS([selinux/selinux.h], > + [found_selinux_h=yes]) > + CPPFLAGS="$saved_CPPFLAGS" > + AS_IF([test "x$found_selinux_h" = xyes], > + [saved_LDFLAGS="$LDFLAGS" > + LDFLAGS="$LDFLAGS $libselinux_LDFLAGS" > + AC_CHECK_LIB([selinux],[getpidcon], > + [libselinux_LIBS="-lselinux" > + with_secontexts=yes > + ], > + [if test "x$with_libselinux" != xcheck; then > + AC_MSG_FAILURE([failed to find getpidcon in libselinux]) > + fi > + ] > + ) > + AC_CHECK_LIB([selinux],[getfilecon], > + [libselinux_LIBS="-lselinux" > + with_secontexts=yes > + ], > + [if test "x$with_libselinux" != xcheck; then > + AC_MSG_FAILURE([failed to find getfilecon in libselinux]) > + fi > + ] > + ) > + LDFLAGS="$saved_LDFLAGS" > + ], > + [if test "x$with_libselinux" != xcheck; then > + AC_MSG_FAILURE([failed to find selinux.h]) > + fi > + ] > + ) > + ] > +) > + > +AC_MSG_CHECKING([whether to enable security contexts support]) > +AS_IF([test "x$with_secontexts" = xyes], > + [AC_DEFINE([USE_SELINUX], [1], > + [Define to enable SELinux security contexts support]) > + AC_DEFINE([HAVE_SELINUX_RUNTIME], [1], > + [Define to enable SELinux security contexts testing]) > + AC_SUBST(libselinux_LIBS) > + AC_SUBST(libselinux_LDFLAGS) > + AC_SUBST(libselinux_CPPFLAGS) > + AC_MSG_RESULT([yes])], > + [AC_MSG_RESULT([no])]) > + > +AM_CONDITIONAL([USE_SELINUX], [test "x$with_secontexts" = xyes]) > +AM_CONDITIONAL([HAVE_SELINUX_RUNTIME], [test "x$with_secontexts" = xyes]) > + > +]) OK > diff --git a/src/Makefile.am b/src/Makefile.am > index ee9415ea5..e5553918a 100644 > --- a/src/Makefile.am > +++ b/src/Makefile.am > @@ -186,6 +186,7 @@ libstrace_a_SOURCES = \ > mmap_notify.c \ > mmap_notify.h \ > mmsghdr.c \ > + mntns.c \ > mount.c \ > move_mount.c \ > mpers_type.h \ > @@ -303,6 +304,7 @@ libstrace_a_SOURCES = \ > sched_attr.h \ > scsi.c \ > seccomp.c \ > + selinux.h \ > sendfile.c \ > sg_io_v3.c \ > sg_io_v4.c \ > @@ -406,6 +408,13 @@ strace_LDADD += $(libiberty_LIBS) > endif > endif > > +if USE_SELINUX > +libstrace_a_SOURCES += selinux.c > +strace_CPPFLAGS += $(libselinux_CPPFLAGS) > +strace_LDFLAGS += $(libselinux_LDFLAGS) > +strace_LDADD += $(libselinux_LIBS) > +endif > + > strace_CPPFLAGS += $(CODE_COVERAGE_CPPFLAGS) > strace_CFLAGS += $(CODE_COVERAGE_CFLAGS) > strace_LDADD += $(CODE_COVERAGE_LIBS) It's an interesting question whether you want to compile mntns.c when selinux support is not enabled. Maybe some day in the future mntns.c might be used outside USE_SELINUX code, bit currently it looks like we would better off without mntns.c when USE_SELINUX is not enabled. In other words, let's move mntns.c and selinux.h into "if USE_SELINUX" case. > diff --git a/src/access.c b/src/access.c > index 2936242f7..81b78889b 100644 > --- a/src/access.c > +++ b/src/access.c > @@ -34,8 +34,10 @@ decode_faccessat(struct tcb *tcp) > { > /* dirfd */ > print_dirfd(tcp, tcp->u_arg[0]); > +#ifdef USE_SELINUX > + tcp->dirfd = (int)(tcp->u_arg[0]); > +#endif > tprint_arg_next(); > - > decode_access(tcp, 1); > } > > diff --git a/src/chmod.c b/src/chmod.c > index 6935fbfec..1e634722d 100644 > --- a/src/chmod.c > +++ b/src/chmod.c > @@ -29,6 +29,9 @@ SYS_FUNC(fchmodat) > { > /* dirfd */ > print_dirfd(tcp, tcp->u_arg[0]); > +#ifdef USE_SELINUX > + tcp->dirfd = (int)(tcp->u_arg[0]); > +#endif > tprint_arg_next(); > > decode_chmod(tcp, 1); > diff --git a/src/execve.c b/src/execve.c > index a9224543b..22820b564 100644 > --- a/src/execve.c > +++ b/src/execve.c > @@ -119,6 +119,9 @@ SYS_FUNC(execveat) > { > /* dirfd */ > print_dirfd(tcp, tcp->u_arg[0]); > +#ifdef USE_SELINUX > + tcp->dirfd = (int)(tcp->u_arg[0]); > +#endif > tprint_arg_next(); > > /* pathname, argv, envp */ > diff --git a/src/fanotify.c b/src/fanotify.c > index 9e8071009..a87233418 100644 > --- a/src/fanotify.c > +++ b/src/fanotify.c > @@ -57,8 +57,12 @@ SYS_FUNC(fanotify_mark) > tprints(", "); > if ((int) tcp->u_arg[argn] == FAN_NOFD) > print_xlat_d(FAN_NOFD); > - else > + else { > print_dirfd(tcp, tcp->u_arg[argn]); > +#ifdef USE_SELINUX > + tcp->dirfd = (int)(tcp->u_arg[argn]); > +#endif > + } > tprints(", "); > printpath(tcp, tcp->u_arg[argn + 1]); > > diff --git a/src/fchownat.c b/src/fchownat.c > index 25602a48e..99e911abb 100644 > --- a/src/fchownat.c > +++ b/src/fchownat.c > @@ -11,6 +11,9 @@ SYS_FUNC(fchownat) > { > /* dirfd */ > print_dirfd(tcp, tcp->u_arg[0]); > +#ifdef USE_SELINUX > + tcp->dirfd = (int)(tcp->u_arg[0]); > +#endif > tprint_arg_next(); > > /* pathname */ > diff --git a/src/file_handle.c b/src/file_handle.c > index 7a6ef1022..4da3013c2 100644 > --- a/src/file_handle.c > +++ b/src/file_handle.c > @@ -43,6 +43,9 @@ SYS_FUNC(name_to_handle_at) > if (entering(tcp)) { > /* dirfd */ > print_dirfd(tcp, tcp->u_arg[0]); > +#ifdef USE_SELINUX > + tcp->dirfd = (int)(tcp->u_arg[0]); > +#endif > tprint_arg_next(); > > /* pathname */ > diff --git a/src/fspick.c b/src/fspick.c > index 2db30f768..c5d244596 100644 > --- a/src/fspick.c > +++ b/src/fspick.c > @@ -13,6 +13,9 @@ SYS_FUNC(fspick) > { > /* dirfd */ > print_dirfd(tcp, tcp->u_arg[0]); > +#ifdef USE_SELINUX > + tcp->dirfd = (int)(tcp->u_arg[0]); > +#endif > tprint_arg_next(); > > /* pathname */ > diff --git a/src/link.c b/src/link.c > index bad2302c9..60ad2958e 100644 > --- a/src/link.c > +++ b/src/link.c > @@ -27,10 +27,16 @@ SYS_FUNC(link) > SYS_FUNC(linkat) > { > print_dirfd(tcp, tcp->u_arg[0]); > +#ifdef USE_SELINUX > + tcp->dirfd = (int)(tcp->u_arg[0]); > +#endif > tprints(", "); > printpath(tcp, tcp->u_arg[1]); > tprints(", "); > print_dirfd(tcp, tcp->u_arg[2]); > +#ifdef USE_SELINUX > + tcp->dirfd = (int)(tcp->u_arg[2]); > +#endif > tprints(", "); > printpath(tcp, tcp->u_arg[3]); > tprints(", "); > @@ -42,6 +48,9 @@ SYS_FUNC(linkat) > SYS_FUNC(unlinkat) > { > print_dirfd(tcp, tcp->u_arg[0]); > +#ifdef USE_SELINUX > + tcp->dirfd = (int)(tcp->u_arg[0]); > +#endif > tprints(", "); > printpath(tcp, tcp->u_arg[1]); > tprints(", "); > @@ -55,6 +64,9 @@ SYS_FUNC(symlinkat) > printpath(tcp, tcp->u_arg[0]); > tprints(", "); > print_dirfd(tcp, tcp->u_arg[1]); > +#ifdef USE_SELINUX > + tcp->dirfd = (int)(tcp->u_arg[1]); > +#endif > tprints(", "); > printpath(tcp, tcp->u_arg[2]); > > diff --git a/src/mknod.c b/src/mknod.c > index e1950621a..e2f97c655 100644 > --- a/src/mknod.c > +++ b/src/mknod.c > @@ -46,6 +46,9 @@ SYS_FUNC(mknod) > SYS_FUNC(mknodat) > { > print_dirfd(tcp, tcp->u_arg[0]); > +#ifdef USE_SELINUX > + tcp->dirfd = (int)(tcp->u_arg[0]); > +#endif > tprints(", "); > decode_mknod(tcp, 1); > > diff --git a/src/move_mount.c b/src/move_mount.c > index 2fb571713..f8b1e387d 100644 > --- a/src/move_mount.c > +++ b/src/move_mount.c > @@ -12,10 +12,16 @@ > SYS_FUNC(move_mount) > { > print_dirfd(tcp, tcp->u_arg[0]); > +#ifdef USE_SELINUX > + tcp->dirfd = (int)(tcp->u_arg[0]); > +#endif > tprints(", "); > printpath(tcp, tcp->u_arg[1]); > tprints(", "); > print_dirfd(tcp, tcp->u_arg[2]); > +#ifdef USE_SELINUX > + tcp->dirfd = (int)(tcp->u_arg[2]); > +#endif > tprints(", "); > printpath(tcp, tcp->u_arg[3]); > tprints(", "); > diff --git a/src/open.c b/src/open.c > index 365693b6b..d563b3da2 100644 > --- a/src/open.c > +++ b/src/open.c > @@ -137,6 +137,9 @@ print_open_how(struct tcb *tcp, kernel_ulong_t addr, kernel_ulong_t size) > SYS_FUNC(openat) > { > print_dirfd(tcp, tcp->u_arg[0]); > +#ifdef USE_SELINUX > + tcp->dirfd = (int)(tcp->u_arg[0]); > +#endif > tprints(", "); > return decode_open(tcp, 1); > } > @@ -144,6 +147,9 @@ SYS_FUNC(openat) > SYS_FUNC(openat2) > { > print_dirfd(tcp, tcp->u_arg[0]); > +#ifdef USE_SELINUX > + tcp->dirfd = (int)(tcp->u_arg[0]); > +#endif > tprints(", "); > printpath(tcp, tcp->u_arg[1]); > tprints(", "); > diff --git a/src/open_tree.c b/src/open_tree.c > index 75a20cd9f..8dbe80d1d 100644 > --- a/src/open_tree.c > +++ b/src/open_tree.c > @@ -14,6 +14,9 @@ > SYS_FUNC(open_tree) > { > print_dirfd(tcp, tcp->u_arg[0]); > +#ifdef USE_SELINUX > + tcp->dirfd = (int)(tcp->u_arg[0]); > +#endif > tprints(", "); > printpath(tcp, tcp->u_arg[1]); > tprints(", "); > diff --git a/src/readlink.c b/src/readlink.c > index a602f6c26..8c055315f 100644 > --- a/src/readlink.c > +++ b/src/readlink.c > @@ -46,6 +46,9 @@ SYS_FUNC(readlinkat) > { > if (entering(tcp)) { > print_dirfd(tcp, tcp->u_arg[0]); > +#ifdef USE_SELINUX > + tcp->dirfd = (int)(tcp->u_arg[0]); > +#endif > tprints(", "); > } > return decode_readlink(tcp, 1); > diff --git a/src/renameat.c b/src/renameat.c > index a854117df..264c564fd 100644 > --- a/src/renameat.c > +++ b/src/renameat.c > @@ -11,10 +11,16 @@ static void > decode_renameat(struct tcb *tcp) > { > print_dirfd(tcp, tcp->u_arg[0]); > +#ifdef USE_SELINUX > + tcp->dirfd = (int)(tcp->u_arg[0]); > +#endif > tprints(", "); > printpath(tcp, tcp->u_arg[1]); > tprints(", "); > print_dirfd(tcp, tcp->u_arg[2]); > +#ifdef USE_SELINUX > + tcp->dirfd = (int)(tcp->u_arg[2]); > +#endif > tprints(", "); > printpath(tcp, tcp->u_arg[3]); > } > diff --git a/src/stat.c b/src/stat.c > index 903750ded..33396785a 100644 > --- a/src/stat.c > +++ b/src/stat.c > @@ -44,6 +44,9 @@ SYS_FUNC(newfstatat) > { > if (entering(tcp)) { > print_dirfd(tcp, tcp->u_arg[0]); > +#ifdef USE_SELINUX > + tcp->dirfd = (int)(tcp->u_arg[0]); > +#endif > tprints(", "); > printpath(tcp, tcp->u_arg[1]); > tprints(", "); > diff --git a/src/stat64.c b/src/stat64.c > index 33d6ca366..75440b1e7 100644 > --- a/src/stat64.c > +++ b/src/stat64.c > @@ -44,6 +44,9 @@ SYS_FUNC(fstatat64) > { > if (entering(tcp)) { > print_dirfd(tcp, tcp->u_arg[0]); > +#ifdef USE_SELINUX > + tcp->dirfd = (int)(tcp->u_arg[0]); > +#endif > tprints(", "); > printpath(tcp, tcp->u_arg[1]); > tprints(", "); > diff --git a/src/statx.c b/src/statx.c > index a0e040f17..4a2d6909d 100644 > --- a/src/statx.c > +++ b/src/statx.c > @@ -31,6 +31,9 @@ SYS_FUNC(statx) > { > if (entering(tcp)) { > print_dirfd(tcp, tcp->u_arg[0]); > +#ifdef USE_SELINUX > + tcp->dirfd = (int)(tcp->u_arg[0]); > +#endif > tprints(", "); > printpath(tcp, tcp->u_arg[1]); > tprints(", "); > diff --git a/src/utimes.c b/src/utimes.c > index 5bcd82e3a..5d4de6d47 100644 > --- a/src/utimes.c > +++ b/src/utimes.c > @@ -26,6 +26,9 @@ SYS_FUNC(utimes) > SYS_FUNC(futimesat) > { > print_dirfd(tcp, tcp->u_arg[0]); > +#ifdef USE_SELINUX > + tcp->dirfd = (int)(tcp->u_arg[0]); > +#endif > tprints(", "); > printpath(tcp, tcp->u_arg[1]); > tprints(", "); > @@ -38,6 +41,9 @@ static int > do_utimensat(struct tcb *const tcp, const print_obj_by_addr_fn print_ts) > { > print_dirfd(tcp, tcp->u_arg[0]); > +#ifdef USE_SELINUX > + tcp->dirfd = (int)(tcp->u_arg[0]); > +#endif > tprints(", "); > printpath(tcp, tcp->u_arg[1]); > tprints(", "); You've added a lot of such tcp->dirfd assignments. Apparently, they are added after every print_dirfd invocation except one (and that one seems to be omitted by mistake). If you want to cache dirfd processed by print_dirfd, it would be much easier if you just moved this assignment inside print_dirfd. > diff --git a/src/defs.h b/src/defs.h > index 08a293130..673e86539 100644 > --- a/src/defs.h > +++ b/src/defs.h > @@ -293,6 +293,17 @@ struct tcb { > */ > unsigned int pid_ns; > > + /* > + * The ID of the MOUNT namespace of this process > + * (inode number of /proc//ns/mnt) > + * (0: not initialized) > + */ > + unsigned int mnt_ns; > + > +#ifdef USE_SELINUX > + int dirfd; /* Use AT_FDCWD for 'not set' */ > +#endif > + > struct mmap_cache_t *mmap_cache; > > /* Since mnt_ns shouldn't be used outside USE_SELINUX yet, let's move it inside USE_SELINUX. Also, dirfd seems to be too short, I'd like to rename it to something more descriptive, e.g. last_dirfd. > @@ -1046,8 +1057,13 @@ print_local_array_ex(struct tcb *tcp, > extern kernel_ulong_t * > fetch_indirect_syscall_args(struct tcb *, kernel_ulong_t addr, unsigned int n_args); > > +extern unsigned int get_mnt_ns(struct tcb *tcp); > +extern unsigned int get_our_mnt_ns(void); > + > extern void pidns_init(void); > > +extern const char *pid_to_str(pid_t pid); > + > /** > * Returns the pid of the tracee as present in /proc of the tracer (can be > * different from tcp->pid if /proc and the tracer process are in different PID You can move these declarations inside USE_SELINUX, but it's not necessary. > diff --git a/src/mntns.c b/src/mntns.c > new file mode 100644 > index 000000000..ac6cddbf6 > --- /dev/null > +++ b/src/mntns.c > @@ -0,0 +1,72 @@ > +/* > + * Copyright (c) 2021 The strace developers. > + * All rights reserved. > + * > + * SPDX-License-Identifier: LGPL-2.1-or-later > + */ > + > +#include "defs.h" > + > +#include > +#include > +#include > + > +#include "largefile_wrappers.h" > +#include "xstring.h" > + > +static unsigned int > +get_mnt_ns_of_pid(int pid) > +{ > + unsigned int ns = 0; > + char path[PATH_MAX + 1]; > + xsprintf(path, "/proc/%s/ns/mnt", pid_to_str(pid)); > + > + int fd = open_file(path, O_RDONLY); > + if (fd < 0) > + return 0; > + strace_stat_t st; > + if (fstat_fd(fd, &st)) > + goto out; > + ns = st.st_ino; > +out: > + close(fd); Wouldn't it be easier to read if the last 5 lines were written this way: if (fstat_fd(fd, &st) == 0) ns = st.st_ino; close(fd); I'd go even further: if (fd >= 0) { strace_stat_t st; if (fstat_fd(fd, &st) == 0) ns = st.st_ino; close(fd); } > + > + return ns; > +} > + > +/** > + * Returns the MOUNT namespace of the tracee > + */ > +unsigned int > +get_mnt_ns(struct tcb *tcp) > +{ > + if (tcp->mnt_ns) > + return tcp->mnt_ns; > + > + int proc_pid = 0; > + translate_pid(NULL, tcp->pid, PT_TID, &proc_pid); > + > + if (!proc_pid) > + return 0; > + > + tcp->mnt_ns = get_mnt_ns_of_pid(proc_pid); Wouldn't it be easier to read if the last 4 lines were written this way: if (proc_pid) tcp->mnt_ns = get_mnt_ns_of_pid(proc_pid); > + > + return tcp->mnt_ns; > +} > + > +/** > + * Returns the MOUNT namespace of strace > + */ > +unsigned int > +get_our_mnt_ns(void) > +{ > + static unsigned int our_ns = 0; > + static bool our_ns_initialised = false; > + > + if (!our_ns_initialised) { > + our_ns = get_mnt_ns_of_pid((int)getpid()); I don't think this explicit cast is really needed here. > + our_ns_initialised = true; > + } > + > + return our_ns; > +} The rest of this file is OK > diff --git a/src/pidns.c b/src/pidns.c > index dbcf52b91..6221f902b 100644 > --- a/src/pidns.c > +++ b/src/pidns.c > @@ -142,7 +142,7 @@ get_cached_proc_pid(unsigned int ns, int ns_pid, enum pid_type type) > * Helper function, converts pid to string, or to "self" for pid == 0. > * Uses static buffer for operation. > */ > -static const char * > +const char * > pid_to_str(pid_t pid) > { > if (!pid) OK > diff --git a/src/selinux.c b/src/selinux.c > new file mode 100644 > index 000000000..0ea9e46ee > --- /dev/null > +++ b/src/selinux.c > @@ -0,0 +1,179 @@ > +/* > + * Copyright (c) 2020-2021 The strace developers. > + * All rights reserved. > + * > + * SPDX-License-Identifier: LGPL-2.1-or-later > + */ > + > +#include > +#include > +#include > +#include > + > +#include "defs.h" "defs.h" must be included first. Also, I prefer to have included before . > +#include "number_set.h" > +#include "selinux.h" > +#include "xstring.h" > + > +#ifndef AT_FDCWD > +# define AT_FDCWD -100 > +#endif > + > +bool selinux_context = false; > +bool selinux_context_full = false; > + > +enum selinux_objtype { > + SELINUX_PID, > + SELINUX_PATH > +}; > + > +typedef struct { > + enum selinux_objtype type; > + union { > + pid_t pid; > + char *path; > + } obj; > +} selinux_obj_t; > + > +static int getcontext(selinux_obj_t *obj, char **context); > + > +/* > + * Retrieves the SELinux context of the given PID (extracted from the tcb). > + * Memory must be freed. > + * Returns 0 on success, -1 on failure. > + */ > +int > +selinux_getpidcon(struct tcb *tcp, char **context) > +{ > + int proc_pid = 0; > + translate_pid(NULL, tcp->pid, PT_TID, &proc_pid); > + if (!proc_pid) > + return -1; Let's check selinux_context first and return from this function if selinux_context is not enabled. > + > + selinux_obj_t obj; > + obj.type = SELINUX_PID; > + obj.obj.pid = (pid_t)proc_pid; > + > + return getcontext(&obj, context); > +} > + > +/* > + * Retrieves the SELinux context of the given path. > + * Memory must be freed. > + * Returns 0 on success, -1 on failure. > + */ > +int > +selinux_getfilecon(struct tcb *tcp, char *path, char **context) Let's change "char *path" to "const char *path". > +{ > + /* > + * Current limitation: we cannot query the path if we are in different > + * mount namespaces. > + */ > + if (get_mnt_ns(tcp) != get_our_mnt_ns()) > + return -1; Let's check selinux_context first and return from this function if selinux_context is not enabled. > + > + selinux_obj_t obj; > + obj.type = SELINUX_PATH; > + obj.obj.path = path; > + > + if (path[0] == '/') > + return getcontext(&obj, context); > + > + char resolved[PATH_MAX + 1]; > + char pathtoresolve[2 * PATH_MAX + 2]; > + int proc_pid = 0; > + translate_pid(NULL, tcp->pid, PT_TID, &proc_pid); > + if (!proc_pid) > + return -1; > + > + /* > + * If we have a relative pathname and 'dirfd' == AT_FDCWD, we need to > + * prepend by the CWD. > + */ > + if (tcp->dirfd == AT_FDCWD) { > + char linkpath[sizeof("/proc/%u/cwd") + sizeof(int)*3]; > + ssize_t n; > + > + xsprintf(linkpath, "/proc/%u/cwd", proc_pid); > + n = readlink(linkpath, resolved, sizeof(resolved) - 1); > + /* > + * NB: if buffer is too small, readlink doesn't fail, > + * it returns truncated result. > + */ > + if (n == sizeof(resolved) - 1) > + return -1; > + resolved[n] = '\0'; > + } else { > + if (number_set_array_is_empty(decode_fd_set, 0) || Interesting. This means that --decode-fds should have effect on selinux_getfilecon. I wonder why. > + getfdpath_pid(proc_pid, tcp->dirfd, resolved, sizeof(resolved)) < 0) > + return -1; getfdpath_pid itself uses translate_pid to translate it's first argument. > + } > + xsprintf(pathtoresolve, "%s/%s", resolved, path); > + if (realpath(pathtoresolve, resolved) == NULL) { Interesting. Why realpath? Would stat_file be enough? > + /* > + * This can happen in multiple cases: > + * - there was an error different than ENOENT > + * - if path doesn't exist > + * - path is below root directory, e.g. root dir and cwd are > + * '/home//chroot' and path is below root directory, > + * e.g. '../../bin/ls' > + */ > + return -1; > + } > + obj.obj.path = resolved; > + > + return getcontext(&obj, context); > +} > + > +static int > +getcontext(selinux_obj_t *obj, char **context) > +{ > + int res; > + char *secontext; > + > + if (!selinux_context) > + goto fail; > + > + switch (obj->type) { > + case SELINUX_PID: > + res = getpidcon(obj->obj.pid, &secontext); > + break; > + case SELINUX_PATH: > + res = getfilecon(obj->obj.path, &secontext); > + break; > + default: > + /* XXX Assert instead */ > + goto fail; This is the reason why I don't like this enum/case approach: it creates unreachable code. > + } > + > + if (res == -1) > + goto fail; > + > + if (selinux_context_full) { > + *context = xstrdup(secontext); > + } else { > + char *saveptr = NULL; > + char *secontext_copy = xstrdup(secontext); > + const char *token; > + int i; > + > + /* > + * We only want to keep the type (3rd field, ':' separator). > + */ > + *context = NULL; > + for (token = strtok_r(secontext_copy, ":", &saveptr), i = 0; > + token; token = strtok_r(NULL, ":", &saveptr), i++) { > + if (i == 2) { > + *context = xstrdup(token); > + break; > + } > + } > + if (*context == NULL) > + *context = xstrdup(secontext); > + free(secontext_copy); > + } > + freecon(secontext); > + return 0; > +fail: > + return -1; > +} I suggest some rewriting, for example: #include "defs.h" #include #include #include #include #include "number_set.h" #include "selinux.h" #include "xstring.h" #ifndef AT_FDCWD # define AT_FDCWD -100 #endif bool selinux_context = false; bool selinux_context_full = false; static int getcontext(int rc, char **secontext, char **result) { if (rc < 0) return rc; *result = NULL; if (!selinux_context_full) { char *saveptr = NULL; char *secontext_copy = xstrdup(*secontext); const char *token; unsigned int i; /* * We only want to keep the type (3rd field, ':' separator). */ for (token = strtok_r(secontext_copy, ":", &saveptr), i = 0; token; token = strtok_r(NULL, ":", &saveptr), i++) { if (i == 2) { *result = xstrdup(token); break; } } free(secontext_copy); } if (*result == NULL) *result = xstrdup(*secontext); freecon(*secontext); return 0; } /* * Retrieves the SELinux context of the given PID (extracted from the tcb). * Memory must be freed. * Returns 0 on success, -1 on failure. */ int selinux_getpidcon(struct tcb *tcp, char **result) { if (!selinux_context) return -1; int proc_pid = 0; translate_pid(NULL, tcp->pid, PT_TID, &proc_pid); if (!proc_pid) return -1; char *secontext; return getcontext(getpidcon(proc_pid, &secontext), &secontext, result); } /* * Retrieves the SELinux context of the given path. * Memory must be freed. * Returns 0 on success, -1 on failure. */ int selinux_getfilecon(struct tcb *tcp, const char *path, char **result) { if (!selinux_context) return -1; /* * Current limitation: we cannot query the path if we are in different * mount namespaces. */ if (get_mnt_ns(tcp) != get_our_mnt_ns()) return -1; char *secontext; if (path[0] == '/') return getcontext(getfilecon(path, &secontext), &secontext, result); char resolved[PATH_MAX + 1]; /* * If we have a relative pathname and 'dirfd' == AT_FDCWD, we need to * prepend by the CWD. */ if (tcp->last_dirfd == AT_FDCWD) { int proc_pid = 0; translate_pid(NULL, tcp->pid, PT_TID, &proc_pid); if (!proc_pid) return -1; char linkpath[sizeof("/proc/%u/cwd") + sizeof(int)*3]; xsprintf(linkpath, "/proc/%u/cwd", proc_pid); ssize_t n = readlink(linkpath, resolved, sizeof(resolved) - 1); /* * NB: if buffer is too small, readlink doesn't fail, * it returns truncated result. */ if (n == sizeof(resolved) - 1) return -1; resolved[n] = '\0'; } else { if (getfdpath_pid(tcp->pid, tcp->last_dirfd, resolved, sizeof(resolved)) < 0) return -1; } char pathtoresolve[2 * PATH_MAX + 2]; xsprintf(pathtoresolve, "%s/%s", resolved, path); /* XXX Why realpath? Would stat_file be enough? */ if (realpath(pathtoresolve, resolved) == NULL) { /* * This can happen in multiple cases: * - there was an error different than ENOENT * - if path doesn't exist * - path is below root directory, e.g. root dir and cwd are * '/home//chroot' and path is below root directory, * e.g. '../../bin/ls' */ return -1; } return getcontext(getfilecon(resolved, &secontext), &secontext, result); } > diff --git a/src/selinux.h b/src/selinux.h > new file mode 100644 > index 000000000..028e87617 > --- /dev/null > +++ b/src/selinux.h > @@ -0,0 +1,24 @@ > +/* > + * SELinux interface. > + * > + * Copyright (c) 2020 The strace developers. 2020-2021 > + * > + * SPDX-License-Identifier: LGPL-2.1-or-later > + */ > + > +#ifndef STRACE_SELINUX_H > +#define STRACE_SELINUX_H > + > +#include "defs.h" > + > +#ifdef USE_SELINUX > + > +extern bool selinux_context; > +extern bool selinux_context_full; > + > +int selinux_getpidcon(struct tcb *tcp, char **context); > +int selinux_getfilecon(struct tcb *tcp, char *path, char **context); Let's change "char *path" to "const char *path". > + > +#endif > + > +#endif /* !STRACE_SELINUX_H */ The rest of this file is OK. > diff --git a/src/strace.c b/src/strace.c > index 7e7920d31..9035c6de4 100644 > --- a/src/strace.c > +++ b/src/strace.c > @@ -40,6 +40,7 @@ > #include "xstring.h" > #include "delay.h" > #include "wait.h" > +#include "selinux.h" > > /* In some libc, these aren't declared. Do it ourself: */ > extern char **environ; > @@ -240,6 +241,9 @@ print_version(void) > " no-mx32-mpers" > # endif > #endif /* SUPPORTED_PERSONALITIES > 2 */ > +#ifdef USE_SELINUX > + " secontext" > +#endif > ""; > > printf("%s -- version %s\n" > @@ -258,12 +262,18 @@ usage(void) > # define K_OPT "k" > #else > # define K_OPT "" > +#endif > +#ifdef USE_SELINUX > +# define SELINUX_OPT "[--secontext[=full]]\n" > +#else > +# define SELINUX_OPT "" > #endif > > printf("\ > Usage: strace [-ACdffhi" K_OPT "qqrtttTvVwxxyyzZ] [-I N] [-b execve] [-e EXPR]...\n\ > [-a COLUMN] [-o FILE] [-s STRSIZE] [-X FORMAT] [-O OVERHEAD]\n\ > - [-S SORTBY] [-P PATH]... [-p PID]... [-U COLUMNS] [--seccomp-bpf]\n\ > + [-S SORTBY] [-P PATH]... [-p PID]... [-U COLUMNS] [--seccomp-bpf]\n"\ > + SELINUX_OPT "\ > { -p PID | [-DDD] [-E VAR=VAL]... [-u USERNAME] PROG [ARGS] }\n\ > or: strace -c[dfwzZ] [-I N] [-b execve] [-e EXPR]... [-O OVERHEAD]\n\ > [-S SORTBY] [-P PATH]... [-p PID]... [-U COLUMNS] [--seccomp-bpf]\n\ > @@ -445,6 +455,14 @@ Miscellaneous:\n\ > -d, --debug enable debug output to stderr\n\ > -h, --help print help message\n\ > --seccomp-bpf enable seccomp-bpf filtering\n\ > +" > +#ifdef USE_SELINUX > +"\ > + --secontext[=full]\n\ > + print SELinux contexts (type only unless 'full' is specified)\n\ > +" > +#endif > +"\ > -V, --version print version\n\ > " > /* ancient, no one should use it > @@ -783,6 +801,14 @@ printleader(struct tcb *tcp) > else if (nprocs > 1 && !outfname) > tprintf("[pid %5u] ", tcp->pid); > > +#ifdef USE_SELINUX > + char *context; > + if (!selinux_getpidcon(tcp, &context)) { > + tprintf("[%s] ", context); > + free(context); > + } > +#endif > + > if (tflag_format) { > struct timespec ts; > clock_gettime(CLOCK_REALTIME, &ts); OK > @@ -896,6 +922,13 @@ alloctcb(int pid) > tcp->pid = pid; > #if SUPPORTED_PERSONALITIES > 1 > tcp->currpers = current_personality; > +#endif > +#ifdef USE_SELINUX > +#ifndef AT_FDCWD > +# define AT_FDCWD>------100 > +#endif What is this? :) > + > + tcp->dirfd = AT_FDCWD; > #endif > nprocs++; > debug_msg("new tcb for pid %d, active tcbs:%d", > @@ -2037,6 +2070,9 @@ init(int argc, char *argv[]) > GETOPT_OUTPUT_SEPARATELY, > GETOPT_TS, > GETOPT_PIDNS_TRANSLATION, > +#ifdef USE_SELINUX > + GETOPT_SELINUX_CONTEXT, > +#endif > > GETOPT_QUAL_TRACE, > GETOPT_QUAL_ABBREV, > @@ -2093,6 +2129,9 @@ init(int argc, char *argv[]) > { "failed-only", no_argument, 0, 'Z' }, > { "failing-only", no_argument, 0, 'Z' }, > { "seccomp-bpf", no_argument, 0, GETOPT_SECCOMP }, > +#ifdef USE_SELINUX > + { "secontext", optional_argument, 0, GETOPT_SELINUX_CONTEXT }, > +#endif > > { "trace", required_argument, 0, GETOPT_QUAL_TRACE }, > { "abbrev", required_argument, 0, GETOPT_QUAL_ABBREV }, > @@ -2321,6 +2360,17 @@ init(int argc, char *argv[]) > case GETOPT_SECCOMP: > seccomp_filtering = true; > break; > +#ifdef USE_SELINUX > + case GETOPT_SELINUX_CONTEXT: > + selinux_context = true; > + if (optarg) { > + if (!strcmp(optarg, "full")) > + selinux_context_full = true; > + else > + error_opt_arg(c, lopt, optarg); > + } > + break; > +#endif > case GETOPT_QUAL_TRACE: > qualify_trace(optarg); > break; > @@ -2503,6 +2553,11 @@ init(int argc, char *argv[]) > if (!number_set_array_is_empty(decode_fd_set, 0)) > error_msg("-y/--decode-fds has no effect " > "with -c/--summary-only"); > +#ifdef USE_SELINUX > + if (selinux_context) > + error_msg("--secontext has no effect with " > + "-c/--summary-only"); > +#endif > } > > if (!outfname) { OK > @@ -3220,6 +3275,9 @@ next_event(void) > if (!tcp) > goto next_event_wait_next; > } > +#ifdef USE_SELINUX > + tcp->dirfd = AT_FDCWD; > +#endif > > if (cflag) { > tcp->stime.tv_sec = ru.ru_stime.tv_sec; I'm not sure this is the most optimal place to reset tcp->last_dirfd. For example, if you want to assign it on entering syscall and use it on exiting (e.g. in case of getdents below), this is not the right place to reset it. > diff --git a/src/util.c b/src/util.c > index 9cb555ecb..509b12f7f 100644 > --- a/src/util.c > +++ b/src/util.c > @@ -26,6 +26,7 @@ > #include "largefile_wrappers.h" > #include "number_set.h" > #include "print_utils.h" > +#include "selinux.h" > #include "static_assert.h" > #include "string_to_uint.h" > #include "xlat.h" > @@ -664,6 +665,13 @@ printfd_pid(struct tcb *tcp, pid_t pid, int fd) > > printed: > tprints(">"); > +#ifdef USE_SELINUX > + char *context; > + if (!selinux_getfilecon(tcp, path, &context)) { > + tprintf(" [%s]", context); > + free(context); > + } > +#endif > } else { > tprintf("%d", fd); > } > @@ -959,6 +967,14 @@ printpathn(struct tcb *const tcp, const kernel_ulong_t addr, unsigned int n) > else { > path[n++] = !nul_seen; > print_quoted_cstring(path, n); > + > +#ifdef USE_SELINUX > + char *context; > + if (nul_seen && !selinux_getfilecon(tcp, path, &context)) { > + tprintf(" [%s]", context); > + free(context); > + } > +#endif > } > > return nul_seen; This is OK, but there are few places in the code where printpathn is used in different contexts where this wouldn't be appropriate: - all readdir/getdents contexts, printpathn is used there relative to the corresponding directory, a solution is to assign tcp->last_dirfd inside SYS_FUNC(readdir) and xgetdents; - memfd_create and sock_ioctl use printpathn to print something that's not a filesystem object at all, probably they should use printstrn instead. > diff --git a/strace.spec.in b/strace.spec.in > index c8f281f18..b3a2895d4 100644 > --- a/strace.spec.in > +++ b/strace.spec.in > @@ -29,11 +29,13 @@ BuildRequires: pkgconfig(bluez) > # Install binutils-devel to enable symbol demangling. > %if 0%{?fedora} >= 20 || 0%{?centos} >= 6 || 0%{?rhel} >= 6 > %define buildrequires_stacktrace BuildRequires: elfutils-devel binutils-devel > +%define buildrequires_selinux BuildRequires: libselinux-devel > %endif > %if 0%{?suse_version} >= 1100 > %define buildrequires_stacktrace BuildRequires: libdw-devel binutils-devel > %endif > %{?buildrequires_stacktrace} > +%{?buildrequires_selinux} > > # OBS compatibility > %{?!buildroot:BuildRoot: %_tmppath/buildroot-%name-%version-%release} Maybe opensuse also provides libselinux-devel that could be used here. > diff --git a/tests/.gitignore b/tests/.gitignore > index a2f3419b0..b9a13bcdf 100644 > --- a/tests/.gitignore > +++ b/tests/.gitignore > @@ -3,6 +3,8 @@ > *.log > *.o > *.trs > +*--secontext > +*--secontext_full > _newselect > _newselect-P > accept OK I haven't reviewed the tests yet, just tried to build and run them. I needed to apply the following change to make them pass: diff --git a/tests/gen_tests.in b/tests/gen_tests.in index 3f41959a9..c674c9891 100644 --- a/tests/gen_tests.in +++ b/tests/gen_tests.in @@ -10,8 +10,8 @@ _newselect-P -e trace=_newselect -P /dev/full 9>>/dev/full accept -a22 accept4 -a37 access -a30 --trace-path=access_sample -access--secontext --secontext --trace-path=access_sample -e trace=access -access--secontext_full --secontext=full --trace-path=access_sample -e trace=access +access--secontext -a30 --secontext --trace-path=access_sample -e trace=access +access--secontext_full -a30 --secontext=full --trace-path=access_sample -e trace=access acct -a20 add_key -a30 -s12 adjtimex -a15 @@ -27,8 +27,8 @@ bpf-v -a20 -v -e trace=bpf btrfs +ioctl.test chdir -a10 chmod -a28 -chmod--secontext --secontext -e trace=chmod -chmod--secontext_full --secontext=full -e trace=chmod +chmod--secontext -a28 --secontext -e trace=chmod +chmod--secontext_full -a28 --secontext=full -e trace=chmod chown -a28 chown32 -a31 chroot -a13 @@ -103,15 +103,15 @@ fadvise64_64 +fadvise64.test fallocate -a18 fanotify_init fanotify_mark -a32 -fanotify_mark--secontext --secontext -y -e trace=fanotify_mark -fanotify_mark--secontext_full --secontext=full -y -e trace=fanotify_mark +fanotify_mark--secontext -a32 --secontext -y -e trace=fanotify_mark +fanotify_mark--secontext_full -a32 --secontext=full -y -e trace=fanotify_mark fanotify_mark-Xabbrev -a32 -Xabbrev -e trace=fanotify_mark fanotify_mark-Xraw -a32 -Xraw -e trace=fanotify_mark fanotify_mark-Xverbose -a32 -Xverbose -e trace=fanotify_mark fchdir -a11 fchmod -a15 -fchmod--secontext --secontext -y -e trace=fchmod -fchmod--secontext_full --secontext=full -y -e trace=fchmod +fchmod--secontext -a15 --secontext -y -e trace=fchmod +fchmod--secontext_full -a15 --secontext=full -y -e trace=fchmod fchmodat fchmodat--secontext --secontext -y -e trace=fchmodat fchmodat--secontext_full --secontext=full -y -e trace=fchmodat @@ -516,8 +516,8 @@ open -a30 -P $NAME.sample open_tree -a30 -y open_tree-P -a30 --decode-fds -P /dev/full -e trace=open_tree openat -a36 -P $NAME.sample -openat--secontext -P openat.sample -P $PWD/openat.sample --secontext -y -e trace=openat -openat--secontext_full -P openat.sample -P $PWD/openat.sample --secontext=full -y -e trace=openat +openat--secontext -a36 -P openat.sample -P $PWD/openat.sample --secontext -y -e trace=openat +openat--secontext_full -a36 -P openat.sample -P $PWD/openat.sample --secontext=full -y -e trace=openat openat2 -a35 openat2-Xabbrev --trace=openat2 -a35 -Xabbrev openat2-Xraw --trace=openat2 -a32 -Xraw Also please note that you can use asprintf and functions from xmalloc.h in tests, not need to use complicated malloc's followed by asserts. -- ldv From ldv at altlinux.org Mon Mar 15 01:40:46 2021 From: ldv at altlinux.org (Dmitry V. Levin) Date: Mon, 15 Mar 2021 04:40:46 +0300 Subject: [GSOC] Introduction and Microproject In-Reply-To: References: Message-ID: <20210315014045.GB3123@altlinux.org> Hi Srikavin, On Sun, Mar 14, 2021 at 06:34:38PM -0400, Srikavin Ramkumar wrote: > Hi everyone, > > I'm Srikavin, and I'm currently studying Computer Science and Math at > University of Maryland. I have experience with C and a working > understanding of system internals, and I've used strace in the past to > aid with reverse engineering unknown binaries. > > I have not decided on a project idea yet, but I'm looking at "Implement > a syscall parser / parser test generator". I'm still gaining an > understanding of syzkaller's syscall representation [1] and strace's > internals. Thank you for showing your interest in contributing to the strace project. > Would writing more tests for prctl.c [2] be a good microproject? Yes, you're spot on, prctl.c is one of few files with low code coverage, and writing tests for those parts of prctl.c that are lacking code coverage should be relatively easy. -- ldv From rmetrich at redhat.com Mon Mar 15 17:09:34 2021 From: rmetrich at redhat.com (=?UTF-8?Q?Renaud_M=c3=a9trich?=) Date: Mon, 15 Mar 2021 18:09:34 +0100 Subject: Proposing SELinux support in strace In-Reply-To: <20210315011000.GA3123@altlinux.org> References: <20201121013040.GB815@altlinux.org> <9e17d94c-612f-3ab3-d6bd-da5d14de101b@redhat.com> <20210119231326.GA15157@altlinux.org> <20210217001009.GA8097@altlinux.org> <2b816386-321d-5db6-6b84-19f987404863@redhat.com> <8553b7c6-a0fa-e202-4f0d-edb8a878a697@redhat.com> <20210305141819.GB14087@altlinux.org> <20210315011000.GA3123@altlinux.org> Message-ID: <2a0ba13b-620c-0bf6-11c7-c123947f0050@redhat.com> Hi Dmitry, thanks for the review. Please see inline. Attached is the newest patch with your recommendations. Thanks, Renaud. On 3/15/21 2:10 AM, Dmitry V. Levin wrote: > >> @@ -126,6 +128,18 @@ case "$arch" in >> else >> st_cv_mpers=no >> fi]) >> + AC_CACHE_CHECK([whether selinux runtime works with mpers_name personality], >> + [st_cv_selinux_runtime], >> + [ >> + saved_LIBS="$LIBS" >> + LIBS="-lselinux $LIBS" >> + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], >> + [[return 0]])], >> + [st_cv_selinux_runtime=yes], >> + [st_cv_selinux_runtime=no], >> + [st_cv_selinux_runtime=no]) >> + LIBS="$saved_LIBS" >> + ]) >> if test $st_cv_mpers = yes; then >> AC_DEFINE(HAVE_MPERS, [1], >> [Define to 1 if you have mpers_name mpers support]) > Since st_MPERS code is executed after st_SELINUX, its results can be used > here. If with_secontexts was set to "no" by st_SELINUX, there is no need > to bother about selinux runtime here. Also, if st_cv_runtime was set to > "no" by earlier checks, there is no need to check selinux runtime either. > > For example: > > AS_IF([test "x$with_secontexts$st_cv_mpers$st_cv_runtime" = xyesyesyes], > [AC_CACHE_CHECK([whether selinux runtime works with mpers_name personality], > [st_cv_selinux_runtime], > [saved_CPPFLAGS="$CPPFLAGS" > saved_LDFLAGS="$LDFLAGS" > saved_LIBS="$LIBS" > CPPFLAGS="$CPPFLAGS libselinux_CPPFLAGS" > LDFLAGS="$LDFLAGS libselinux_LDFLAGS" > LIBS="$LIBS libselinux_LIBS" > AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], > [[return 0]])], > [st_cv_selinux_runtime=yes], > [st_cv_selinux_runtime=no], > [st_cv_selinux_runtime=no]) > LIBS="$saved_LIBS" > LDFLAGS="$saved_LDFLAGS" > CPPFLAGS="$saved_CPPFLAGS" > ]) > ], > [st_cv_selinux_runtime=no]) OK > diff --git a/src/Makefile.am b/src/Makefile.am >> index ee9415ea5..e5553918a 100644 >> --- a/src/Makefile.am >> +++ b/src/Makefile.am >> @@ -186,6 +186,7 @@ libstrace_a_SOURCES = \ >> mmap_notify.c \ >> mmap_notify.h \ >> mmsghdr.c \ >> + mntns.c \ >> mount.c \ >> move_mount.c \ >> mpers_type.h \ >> @@ -303,6 +304,7 @@ libstrace_a_SOURCES = \ >> sched_attr.h \ >> scsi.c \ >> seccomp.c \ >> + selinux.h \ >> sendfile.c \ >> sg_io_v3.c \ >> sg_io_v4.c \ >> @@ -406,6 +408,13 @@ strace_LDADD += $(libiberty_LIBS) >> endif >> endif >> >> +if USE_SELINUX >> +libstrace_a_SOURCES += selinux.c >> +strace_CPPFLAGS += $(libselinux_CPPFLAGS) >> +strace_LDFLAGS += $(libselinux_LDFLAGS) >> +strace_LDADD += $(libselinux_LIBS) >> +endif >> + >> strace_CPPFLAGS += $(CODE_COVERAGE_CPPFLAGS) >> strace_CFLAGS += $(CODE_COVERAGE_CFLAGS) >> strace_LDADD += $(CODE_COVERAGE_LIBS) > It's an interesting question whether you want to compile mntns.c when > selinux support is not enabled. Maybe some day in the future mntns.c might > be used outside USE_SELINUX code, bit currently it looks like we would > better off without mntns.c when USE_SELINUX is not enabled. > > In other words, let's move mntns.c and selinux.h into "if USE_SELINUX" > case. OK >> diff --git a/src/access.c b/src/access.c >> index 2936242f7..81b78889b 100644 >> --- a/src/access.c >> +++ b/src/access.c >> @@ -34,8 +34,10 @@ decode_faccessat(struct tcb *tcp) >> { >> /* dirfd */ >> print_dirfd(tcp, tcp->u_arg[0]); >> +#ifdef USE_SELINUX >> + tcp->dirfd = (int)(tcp->u_arg[0]); >> +#endif >> tprint_arg_next(); >> - >> decode_access(tcp, 1); >> } >> [...] >> You've added a lot of such tcp->dirfd assignments. Apparently, >> they are added after every print_dirfd invocation except one (and that one >> seems to be omitted by mistake). If you want to cache dirfd processed by >> print_dirfd, it would be much easier if you just moved this assignment >> inside print_dirfd. Initially I had this idea as well but then thought it was ugly to have this state saved in print_dirfd(). Additionally we need to really know when to set the dirfd: there may be cases where print_dirfd() is called but the next arguments to the syscall won't use that dirfd as "reference". Hence it's safer to assign dirfd in the syscall handler itself. >> diff --git a/src/defs.h b/src/defs.h >> index 08a293130..673e86539 100644 >> --- a/src/defs.h >> +++ b/src/defs.h >> @@ -293,6 +293,17 @@ struct tcb { >> */ >> unsigned int pid_ns; >> >> + /* >> + * The ID of the MOUNT namespace of this process >> + * (inode number of /proc//ns/mnt) >> + * (0: not initialized) >> + */ >> + unsigned int mnt_ns; >> + >> +#ifdef USE_SELINUX >> + int dirfd; /* Use AT_FDCWD for 'not set' */ >> +#endif >> + >> struct mmap_cache_t *mmap_cache; >> >> /* > Since mnt_ns shouldn't be used outside USE_SELINUX yet, let's move it > inside USE_SELINUX. > > Also, dirfd seems to be too short, I'd like to rename it to something more > descriptive, e.g. last_dirfd. > OK >> @@ -1046,8 +1057,13 @@ print_local_array_ex(struct tcb *tcp, >> extern kernel_ulong_t * >> fetch_indirect_syscall_args(struct tcb *, kernel_ulong_t addr, unsigned int n_args); >> >> +extern unsigned int get_mnt_ns(struct tcb *tcp); >> +extern unsigned int get_our_mnt_ns(void); >> + >> extern void pidns_init(void); >> >> +extern const char *pid_to_str(pid_t pid); >> + >> /** >> * Returns the pid of the tracee as present in /proc of the tracer (can be >> * different from tcp->pid if /proc and the tracer process are in different PID > You can move these declarations inside USE_SELINUX, but it's not > necessary. OK >> diff --git a/src/mntns.c b/src/mntns.c >> new file mode 100644 >> index 000000000..ac6cddbf6 >> --- /dev/null >> +++ b/src/mntns.c >> @@ -0,0 +1,72 @@ >> +/* >> + * Copyright (c) 2021 The strace developers. >> + * All rights reserved. >> + * >> + * SPDX-License-Identifier: LGPL-2.1-or-later >> + */ >> + >> +#include "defs.h" >> + >> +#include >> +#include >> +#include >> + >> +#include "largefile_wrappers.h" >> +#include "xstring.h" >> + >> +static unsigned int >> +get_mnt_ns_of_pid(int pid) >> +{ >> + unsigned int ns = 0; >> + char path[PATH_MAX + 1]; >> + xsprintf(path, "/proc/%s/ns/mnt", pid_to_str(pid)); >> + >> + int fd = open_file(path, O_RDONLY); >> + if (fd < 0) >> + return 0; >> + strace_stat_t st; >> + if (fstat_fd(fd, &st)) >> + goto out; >> + ns = st.st_ino; >> +out: >> + close(fd); > Wouldn't it be easier to read if the last 5 lines were written this way: > > if (fstat_fd(fd, &st) == 0) > ns = st.st_ino; > close(fd); > > I'd go even further: > > if (fd >= 0) { > strace_stat_t st; > if (fstat_fd(fd, &st) == 0) > ns = st.st_ino; > close(fd); > } OK >> + >> + return ns; >> +} >> + >> +/** >> + * Returns the MOUNT namespace of the tracee >> + */ >> +unsigned int >> +get_mnt_ns(struct tcb *tcp) >> +{ >> + if (tcp->mnt_ns) >> + return tcp->mnt_ns; >> + >> + int proc_pid = 0; >> + translate_pid(NULL, tcp->pid, PT_TID, &proc_pid); >> + >> + if (!proc_pid) >> + return 0; >> + >> + tcp->mnt_ns = get_mnt_ns_of_pid(proc_pid); > Wouldn't it be easier to read if the last 4 lines were written this way: > > if (proc_pid) > tcp->mnt_ns = get_mnt_ns_of_pid(proc_pid); > OK >> + >> + return tcp->mnt_ns; >> +} >> + >> +/** >> + * Returns the MOUNT namespace of strace >> + */ >> +unsigned int >> +get_our_mnt_ns(void) >> +{ >> + static unsigned int our_ns = 0; >> + static bool our_ns_initialised = false; >> + >> + if (!our_ns_initialised) { >> + our_ns = get_mnt_ns_of_pid((int)getpid()); > I don't think this explicit cast is really needed here. OK >> + our_ns_initialised = true; >> + } >> + >> + return our_ns; >> +} > The rest of this file is OK > >> diff --git a/src/pidns.c b/src/pidns.c >> index dbcf52b91..6221f902b 100644 >> --- a/src/pidns.c >> +++ b/src/pidns.c >> @@ -142,7 +142,7 @@ get_cached_proc_pid(unsigned int ns, int ns_pid, enum pid_type type) >> * Helper function, converts pid to string, or to "self" for pid == 0. >> * Uses static buffer for operation. >> */ >> -static const char * >> +const char * >> pid_to_str(pid_t pid) >> { >> if (!pid) > OK > >> diff --git a/src/selinux.c b/src/selinux.c >> new file mode 100644 >> index 000000000..0ea9e46ee >> --- /dev/null >> +++ b/src/selinux.c >> @@ -0,0 +1,179 @@ >> +/* >> + * Copyright (c) 2020-2021 The strace developers. >> + * All rights reserved. >> + * >> + * SPDX-License-Identifier: LGPL-2.1-or-later >> + */ >> + >> +#include >> +#include >> +#include >> +#include >> + >> +#include "defs.h" > "defs.h" must be included first. > > Also, I prefer to have included before . OK >> +#include "number_set.h" >> +#include "selinux.h" >> +#include "xstring.h" >> + >> +#ifndef AT_FDCWD >> +# define AT_FDCWD -100 >> +#endif >> + >> +bool selinux_context = false; >> +bool selinux_context_full = false; >> + >> +enum selinux_objtype { >> + SELINUX_PID, >> + SELINUX_PATH >> +}; >> + >> +typedef struct { >> + enum selinux_objtype type; >> + union { >> + pid_t pid; >> + char *path; >> + } obj; >> +} selinux_obj_t; >> + >> +static int getcontext(selinux_obj_t *obj, char **context); >> + >> +/* >> + * Retrieves the SELinux context of the given PID (extracted from the tcb). >> + * Memory must be freed. >> + * Returns 0 on success, -1 on failure. >> + */ >> +int >> +selinux_getpidcon(struct tcb *tcp, char **context) >> +{ >> + int proc_pid = 0; >> + translate_pid(NULL, tcp->pid, PT_TID, &proc_pid); >> + if (!proc_pid) >> + return -1; > Let's check selinux_context first and return from this function > if selinux_context is not enabled. I don't understand. We need *proc_pid* to get the context, so the translation must be performed initially. >> + >> + selinux_obj_t obj; >> + obj.type = SELINUX_PID; >> + obj.obj.pid = (pid_t)proc_pid; >> + >> + return getcontext(&obj, context); >> +} >> + >> +/* >> + * Retrieves the SELinux context of the given path. >> + * Memory must be freed. >> + * Returns 0 on success, -1 on failure. >> + */ >> +int >> +selinux_getfilecon(struct tcb *tcp, char *path, char **context) > Let's change "char *path" to "const char *path". OK >> +{ >> + /* >> + * Current limitation: we cannot query the path if we are in different >> + * mount namespaces. >> + */ >> + if (get_mnt_ns(tcp) != get_our_mnt_ns()) >> + return -1; > Let's check selinux_context first and return from this function > if selinux_context is not enabled. Here, if we are not in the right context, then getfilecon() will return false positives, so I think the first thing to check is that we can indeed retrieve a valid context. >> + >> + selinux_obj_t obj; >> + obj.type = SELINUX_PATH; >> + obj.obj.path = path; >> + >> + if (path[0] == '/') >> + return getcontext(&obj, context); >> + >> + char resolved[PATH_MAX + 1]; >> + char pathtoresolve[2 * PATH_MAX + 2]; >> + int proc_pid = 0; >> + translate_pid(NULL, tcp->pid, PT_TID, &proc_pid); >> + if (!proc_pid) >> + return -1; >> + >> + /* >> + * If we have a relative pathname and 'dirfd' == AT_FDCWD, we need to >> + * prepend by the CWD. >> + */ >> + if (tcp->dirfd == AT_FDCWD) { >> + char linkpath[sizeof("/proc/%u/cwd") + sizeof(int)*3]; >> + ssize_t n; >> + >> + xsprintf(linkpath, "/proc/%u/cwd", proc_pid); >> + n = readlink(linkpath, resolved, sizeof(resolved) - 1); >> + /* >> + * NB: if buffer is too small, readlink doesn't fail, >> + * it returns truncated result. >> + */ >> + if (n == sizeof(resolved) - 1) >> + return -1; >> + resolved[n] = '\0'; >> + } else { >> + if (number_set_array_is_empty(decode_fd_set, 0) || > Interesting. This means that --decode-fds should have effect on > selinux_getfilecon. I wonder why. From my research, there is no way to get a path from a dirfd, hence we need implicitly --decode-fds for this to work, since the latter will have the mapping fd -> pathname for us. But actually I removed the number_set_array_is_empty() and it just works ... >> + getfdpath_pid(proc_pid, tcp->dirfd, resolved, sizeof(resolved)) < 0) >> + return -1; > getfdpath_pid itself uses translate_pid to translate it's first argument. > OK, I'm wrong indeed. >> + } >> + xsprintf(pathtoresolve, "%s/%s", resolved, path); >> + if (realpath(pathtoresolve, resolved) == NULL) { > Interesting. Why realpath? Would stat_file be enough? No, because the path to check needs to be absolute, or else cwd of strace will be used for resolving the context, which is wrong. >> + /* >> + * This can happen in multiple cases: >> + * - there was an error different than ENOENT >> + * - if path doesn't exist >> + * - path is below root directory, e.g. root dir and cwd are >> + * '/home//chroot' and path is below root directory, >> + * e.g. '../../bin/ls' >> + */ >> + return -1; >> + } >> + obj.obj.path = resolved; >> + >> + return getcontext(&obj, context); >> +} >> + >> +static int >> +getcontext(selinux_obj_t *obj, char **context) >> +{ >> + int res; >> + char *secontext; >> + >> + if (!selinux_context) >> + goto fail; >> + >> + switch (obj->type) { >> + case SELINUX_PID: >> + res = getpidcon(obj->obj.pid, &secontext); >> + break; >> + case SELINUX_PATH: >> + res = getfilecon(obj->obj.path, &secontext); >> + break; >> + default: >> + /* XXX Assert instead */ >> + goto fail; > This is the reason why I don't like this enum/case approach: > it creates unreachable code. OK changed into if/else >> + } >> + >> + if (res == -1) >> + goto fail; >> + >> + if (selinux_context_full) { >> + *context = xstrdup(secontext); >> + } else { >> + char *saveptr = NULL; >> + char *secontext_copy = xstrdup(secontext); >> + const char *token; >> + int i; >> + >> + /* >> + * We only want to keep the type (3rd field, ':' separator). >> + */ >> + *context = NULL; >> + for (token = strtok_r(secontext_copy, ":", &saveptr), i = 0; >> + token; token = strtok_r(NULL, ":", &saveptr), i++) { >> + if (i == 2) { >> + *context = xstrdup(token); >> + break; >> + } >> + } >> + if (*context == NULL) >> + *context = xstrdup(secontext); >> + free(secontext_copy); >> + } >> + freecon(secontext); >> + return 0; >> +fail: >> + return -1; >> +} > I suggest some rewriting, for example: > > #include "defs.h" > > #include > #include > #include > #include > > #include "number_set.h" > #include "selinux.h" > #include "xstring.h" > > #ifndef AT_FDCWD > # define AT_FDCWD -100 > #endif > > bool selinux_context = false; > bool selinux_context_full = false; > > static int > getcontext(int rc, char **secontext, char **result) > { > if (rc < 0) > return rc; > > *result = NULL; > if (!selinux_context_full) { > char *saveptr = NULL; > char *secontext_copy = xstrdup(*secontext); > const char *token; > unsigned int i; > > /* > * We only want to keep the type (3rd field, ':' separator). > */ > for (token = strtok_r(secontext_copy, ":", &saveptr), i = 0; > token; token = strtok_r(NULL, ":", &saveptr), i++) { > if (i == 2) { > *result = xstrdup(token); > break; > } > } > free(secontext_copy); > } > > if (*result == NULL) > *result = xstrdup(*secontext); > freecon(*secontext); > return 0; > } > > /* > * Retrieves the SELinux context of the given PID (extracted from the tcb). > * Memory must be freed. > * Returns 0 on success, -1 on failure. > */ > int > selinux_getpidcon(struct tcb *tcp, char **result) > { > if (!selinux_context) > return -1; > > int proc_pid = 0; > translate_pid(NULL, tcp->pid, PT_TID, &proc_pid); > if (!proc_pid) > return -1; > > char *secontext; > return getcontext(getpidcon(proc_pid, &secontext), &secontext, result); > } > > /* > * Retrieves the SELinux context of the given path. > * Memory must be freed. > * Returns 0 on success, -1 on failure. > */ > int > selinux_getfilecon(struct tcb *tcp, const char *path, char **result) > { > if (!selinux_context) > return -1; > > /* > * Current limitation: we cannot query the path if we are in different > * mount namespaces. > */ > if (get_mnt_ns(tcp) != get_our_mnt_ns()) > return -1; > > char *secontext; > > if (path[0] == '/') > return getcontext(getfilecon(path, &secontext), &secontext, result); > > char resolved[PATH_MAX + 1]; > > /* > * If we have a relative pathname and 'dirfd' == AT_FDCWD, we need to > * prepend by the CWD. > */ > if (tcp->last_dirfd == AT_FDCWD) { > int proc_pid = 0; > translate_pid(NULL, tcp->pid, PT_TID, &proc_pid); > if (!proc_pid) > return -1; > > char linkpath[sizeof("/proc/%u/cwd") + sizeof(int)*3]; > xsprintf(linkpath, "/proc/%u/cwd", proc_pid); > ssize_t n = readlink(linkpath, resolved, sizeof(resolved) - 1); > /* > * NB: if buffer is too small, readlink doesn't fail, > * it returns truncated result. > */ > if (n == sizeof(resolved) - 1) > return -1; > resolved[n] = '\0'; > } else { > if (getfdpath_pid(tcp->pid, tcp->last_dirfd, > resolved, sizeof(resolved)) < 0) > return -1; > } > > char pathtoresolve[2 * PATH_MAX + 2]; > xsprintf(pathtoresolve, "%s/%s", resolved, path); > /* XXX Why realpath? Would stat_file be enough? */ > if (realpath(pathtoresolve, resolved) == NULL) { > /* > * This can happen in multiple cases: > * - there was an error different than ENOENT > * - if path doesn't exist > * - path is below root directory, e.g. root dir and cwd are > * '/home//chroot' and path is below root directory, > * e.g. '../../bin/ls' > */ > return -1; > } > > return getcontext(getfilecon(resolved, &secontext), &secontext, result); > } OK, smarter code indeed. > @@ -896,6 +922,13 @@ alloctcb(int pid) >> tcp->pid = pid; >> #if SUPPORTED_PERSONALITIES > 1 >> tcp->currpers = current_personality; >> +#endif >> +#ifdef USE_SELINUX >> +#ifndef AT_FDCWD >> +# define AT_FDCWD>------100 >> +#endif > What is this? :) Well, that was defined multiple times in the pre 5.11 sources. I removed this right now. > >> @@ -3220,6 +3275,9 @@ next_event(void) >> if (!tcp) >> goto next_event_wait_next; >> } >> +#ifdef USE_SELINUX >> + tcp->dirfd = AT_FDCWD; >> +#endif >> >> if (cflag) { >> tcp->stime.tv_sec = ru.ru_stime.tv_sec; > I'm not sure this is the most optimal place to reset tcp->last_dirfd. > For example, if you want to assign it on entering syscall and use it on > exiting (e.g. in case of getdents below), this is not the right place > to reset it. Actually this has to be done in trace_syscall() upon entering the syscall. >> diff --git a/src/util.c b/src/util.c >> index 9cb555ecb..509b12f7f 100644 >> --- a/src/util.c >> +++ b/src/util.c >> @@ -26,6 +26,7 @@ >> #include "largefile_wrappers.h" >> #include "number_set.h" >> #include "print_utils.h" >> +#include "selinux.h" >> #include "static_assert.h" >> #include "string_to_uint.h" >> #include "xlat.h" >> @@ -664,6 +665,13 @@ printfd_pid(struct tcb *tcp, pid_t pid, int fd) >> >> printed: >> tprints(">"); >> +#ifdef USE_SELINUX >> + char *context; >> + if (!selinux_getfilecon(tcp, path, &context)) { >> + tprintf(" [%s]", context); >> + free(context); >> + } >> +#endif >> } else { >> tprintf("%d", fd); >> } >> @@ -959,6 +967,14 @@ printpathn(struct tcb *const tcp, const kernel_ulong_t addr, unsigned int n) >> else { >> path[n++] = !nul_seen; >> print_quoted_cstring(path, n); >> + >> +#ifdef USE_SELINUX >> + char *context; >> + if (nul_seen && !selinux_getfilecon(tcp, path, &context)) { >> + tprintf(" [%s]", context); >> + free(context); >> + } >> +#endif >> } >> >> return nul_seen; > This is OK, but there are few places in the code where printpathn is used > in different contexts where this wouldn't be appropriate: > - all readdir/getdents contexts, printpathn is used there relative to the > corresponding directory, a solution is to assign tcp->last_dirfd inside > SYS_FUNC(readdir) and xgetdents; > - memfd_create and sock_ioctl use printpathn to print something that's not > a filesystem object at all, probably they should use printstrn instead. I missed some cases indeed, I was checking print_dirfd() callers only. I however didn't replace printpathn() for memfd_create and sock_ioctl by printstrn() because it should be another commit I guess. > >> diff --git a/strace.spec.in b/strace.spec.in >> index c8f281f18..b3a2895d4 100644 >> --- a/strace.spec.in >> +++ b/strace.spec.in >> @@ -29,11 +29,13 @@ BuildRequires: pkgconfig(bluez) >> # Install binutils-devel to enable symbol demangling. >> %if 0%{?fedora} >= 20 || 0%{?centos} >= 6 || 0%{?rhel} >= 6 >> %define buildrequires_stacktrace BuildRequires: elfutils-devel binutils-devel >> +%define buildrequires_selinux BuildRequires: libselinux-devel >> %endif >> %if 0%{?suse_version} >= 1100 >> %define buildrequires_stacktrace BuildRequires: libdw-devel binutils-devel >> %endif >> %{?buildrequires_stacktrace} >> +%{?buildrequires_selinux} >> >> # OBS compatibility >> %{?!buildroot:BuildRoot: %_tmppath/buildroot-%name-%version-%release} > Maybe opensuse also provides libselinux-devel that could be used here. Indeed there is. Actually I tested on RHEL and Fedora only. > > I haven't reviewed the tests yet, just tried to build and run them. > I needed to apply the following change to make them pass: > > diff --git a/tests/gen_tests.in b/tests/gen_tests.in > index 3f41959a9..c674c9891 100644 > --- a/tests/gen_tests.in > +++ b/tests/gen_tests.in > @@ -10,8 +10,8 @@ _newselect-P -e trace=_newselect -P /dev/full 9>>/dev/full > accept -a22 > accept4 -a37 > access -a30 --trace-path=access_sample > -access--secontext --secontext --trace-path=access_sample -e trace=access > -access--secontext_full --secontext=full --trace-path=access_sample -e trace=access > +access--secontext -a30 --secontext --trace-path=access_sample -e trace=access > +access--secontext_full -a30 --secontext=full --trace-path=access_sample -e trace=access OK, I wasn't sure about the need to "-aXX" option, so removed all this because I didn't see any difference on my systems. > Also please note that you can use asprintf and functions from xmalloc.h > in tests, not need to use complicated malloc's followed by asserts. OK -------------- next part -------------- A non-text attachment was scrubbed... Name: 0002-ldv-s-comments-integration.patch Type: text/x-patch Size: 25860 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: OpenPGP_signature Type: application/pgp-signature Size: 840 bytes Desc: OpenPGP digital signature URL: From ldv at altlinux.org Mon Mar 15 20:33:28 2021 From: ldv at altlinux.org (Dmitry V. Levin) Date: Mon, 15 Mar 2021 23:33:28 +0300 Subject: Proposing SELinux support in strace In-Reply-To: <2a0ba13b-620c-0bf6-11c7-c123947f0050@redhat.com> References: <20210119231326.GA15157@altlinux.org> <20210217001009.GA8097@altlinux.org> <2b816386-321d-5db6-6b84-19f987404863@redhat.com> <8553b7c6-a0fa-e202-4f0d-edb8a878a697@redhat.com> <20210305141819.GB14087@altlinux.org> <20210315011000.GA3123@altlinux.org> <2a0ba13b-620c-0bf6-11c7-c123947f0050@redhat.com> Message-ID: <20210315203328.GA17962@altlinux.org> On Mon, Mar 15, 2021 at 06:09:34PM +0100, Renaud M?trich wrote: [...] > On 3/15/21 2:10 AM, Dmitry V. Levin wrote: > > For example: > > > > AS_IF([test "x$with_secontexts$st_cv_mpers$st_cv_runtime" = xyesyesyes], > > [AC_CACHE_CHECK([whether selinux runtime works with mpers_name personality], > > [st_cv_selinux_runtime], > > [saved_CPPFLAGS="$CPPFLAGS" > > saved_LDFLAGS="$LDFLAGS" > > saved_LIBS="$LIBS" > > CPPFLAGS="$CPPFLAGS libselinux_CPPFLAGS" > > LDFLAGS="$LDFLAGS libselinux_LDFLAGS" > > LIBS="$LIBS libselinux_LIBS" Oops, I've made a typo, of course it should be $libselinux_CPPFLAGS, $libselinux_LDFLAGS, and $libselinux_LIBS. [...] > >> diff --git a/src/access.c b/src/access.c > >> index 2936242f7..81b78889b 100644 > >> --- a/src/access.c > >> +++ b/src/access.c > >> @@ -34,8 +34,10 @@ decode_faccessat(struct tcb *tcp) > >> { > >> /* dirfd */ > >> print_dirfd(tcp, tcp->u_arg[0]); > >> +#ifdef USE_SELINUX > >> + tcp->dirfd = (int)(tcp->u_arg[0]); > >> +#endif > >> tprint_arg_next(); > >> - > >> decode_access(tcp, 1); > >> } > >> [...] > >> You've added a lot of such tcp->dirfd assignments. Apparently, > >> they are added after every print_dirfd invocation except one (and that one > >> seems to be omitted by mistake). If you want to cache dirfd processed by > >> print_dirfd, it would be much easier if you just moved this assignment > >> inside print_dirfd. > > Initially I had this idea as well but then thought it was ugly to have > this state saved in print_dirfd(). > > Additionally we need to really know when to set the dirfd: there may be > cases where print_dirfd() is called but the next arguments to the > syscall won't use that dirfd as "reference". > > Hence it's safer to assign dirfd in the syscall handler itself. I did "git grep -A1 'print_dirfd(' src/*.c" just to confirm that the only place where print_dirfd invocation is not followed by "#ifdef USE_SELINUX" is fsconfig where print_dirfd is used to print the last syscall argument. [...] > >> + } > >> + xsprintf(pathtoresolve, "%s/%s", resolved, path); > >> + if (realpath(pathtoresolve, resolved) == NULL) { > > Interesting. Why realpath? Would stat_file be enough? > No, because the path to check needs to be absolute, or else cwd of > strace will be used for resolving the context, which is wrong. realpath is very expensive because it performs canonicalization. To check whether resolved/path is an absolute path, all we need is to check whether resolved[0] == '/'. -- ldv From ldv at altlinux.org Mon Mar 15 22:34:15 2021 From: ldv at altlinux.org (Dmitry V. Levin) Date: Tue, 16 Mar 2021 01:34:15 +0300 Subject: Proposing SELinux support in strace In-Reply-To: <2a0ba13b-620c-0bf6-11c7-c123947f0050@redhat.com> References: <20210119231326.GA15157@altlinux.org> <20210217001009.GA8097@altlinux.org> <2b816386-321d-5db6-6b84-19f987404863@redhat.com> <8553b7c6-a0fa-e202-4f0d-edb8a878a697@redhat.com> <20210305141819.GB14087@altlinux.org> <20210315011000.GA3123@altlinux.org> <2a0ba13b-620c-0bf6-11c7-c123947f0050@redhat.com> Message-ID: <20210315223415.GB19335@altlinux.org> On Mon, Mar 15, 2021 at 06:09:34PM +0100, Renaud M?trich wrote: [...] > > @@ -896,6 +922,13 @@ alloctcb(int pid) > >> tcp->pid = pid; > >> #if SUPPORTED_PERSONALITIES > 1 > >> tcp->currpers = current_personality; > >> +#endif > >> +#ifdef USE_SELINUX > >> +#ifndef AT_FDCWD > >> +# define AT_FDCWD>------100 > >> +#endif > > What is this? :) > Well, that was defined multiple times in the pre 5.11 sources. I removed > this right now. Anyway, "# define AT_FDCWD>------100" is not quite preprocessor-friendly. > >> @@ -3220,6 +3275,9 @@ next_event(void) > >> if (!tcp) > >> goto next_event_wait_next; > >> } > >> +#ifdef USE_SELINUX > >> + tcp->dirfd = AT_FDCWD; > >> +#endif > >> > >> if (cflag) { > >> tcp->stime.tv_sec = ru.ru_stime.tv_sec; > > I'm not sure this is the most optimal place to reset tcp->last_dirfd. > > For example, if you want to assign it on entering syscall and use it on > > exiting (e.g. in case of getdents below), this is not the right place > > to reset it. > Actually this has to be done in trace_syscall() upon entering the syscall. I'd suggest syscall_exiting_finish() for that kind of resets. -- ldv From ldv at altlinux.org Tue Mar 16 01:30:26 2021 From: ldv at altlinux.org (Dmitry V. Levin) Date: Tue, 16 Mar 2021 04:30:26 +0300 Subject: Proposing SELinux support in strace In-Reply-To: <2a0ba13b-620c-0bf6-11c7-c123947f0050@redhat.com> References: <20210119231326.GA15157@altlinux.org> <20210217001009.GA8097@altlinux.org> <2b816386-321d-5db6-6b84-19f987404863@redhat.com> <8553b7c6-a0fa-e202-4f0d-edb8a878a697@redhat.com> <20210305141819.GB14087@altlinux.org> <20210315011000.GA3123@altlinux.org> <2a0ba13b-620c-0bf6-11c7-c123947f0050@redhat.com> Message-ID: <20210316013026.GA21789@altlinux.org> On Mon, Mar 15, 2021 at 06:09:34PM +0100, Renaud M?trich wrote: [...] > diff --git a/tests/linkat--secontext.c b/tests/linkat--secontext.c > index f2fd003d7..4818d676b 100644 > --- a/tests/linkat--secontext.c > +++ b/tests/linkat--secontext.c > @@ -20,6 +20,7 @@ > # include > # include > # include > +# include > > /* for getcwd()/opendir() */ > # include > @@ -97,9 +98,7 @@ main(void) > perror_msg_and_fail("dirfd"); > > static const char sample_2_dir[] = "new"; > - char *new_sample_2 = malloc(strlen(sample_2_dir) + 1 + strlen(sample_2) + 1); > - if (new_sample_2 == NULL) > - perror_msg_and_fail("malloc"); > + char *new_sample_2 = xmalloc(strlen(sample_2_dir) + 1 + strlen(sample_2) + 1); > sprintf(new_sample_2, "%s/%s", sample_2_dir, sample_2); I've added xasprintf to xmalloc, now you can write this as simple as char *new_sample_2 = xasprintf("%s/%s", sample_2_dir, sample_2); -- ldv From rmetrich at redhat.com Tue Mar 16 10:44:14 2021 From: rmetrich at redhat.com (=?UTF-8?Q?Renaud_M=c3=a9trich?=) Date: Tue, 16 Mar 2021 11:44:14 +0100 Subject: Proposing SELinux support in strace In-Reply-To: <20210315203328.GA17962@altlinux.org> References: <20210119231326.GA15157@altlinux.org> <20210217001009.GA8097@altlinux.org> <2b816386-321d-5db6-6b84-19f987404863@redhat.com> <8553b7c6-a0fa-e202-4f0d-edb8a878a697@redhat.com> <20210305141819.GB14087@altlinux.org> <20210315011000.GA3123@altlinux.org> <2a0ba13b-620c-0bf6-11c7-c123947f0050@redhat.com> <20210315203328.GA17962@altlinux.org> Message-ID: <007c7593-deb3-e39f-e63a-b2f541c308f7@redhat.com> See inline. On 3/15/21 9:33 PM, Dmitry V. Levin wrote: > >>> AS_IF([test "x$with_secontexts$st_cv_mpers$st_cv_runtime" = xyesyesyes], >>> [AC_CACHE_CHECK([whether selinux runtime works with mpers_name personality], >>> [st_cv_selinux_runtime], >>> [saved_CPPFLAGS="$CPPFLAGS" >>> saved_LDFLAGS="$LDFLAGS" >>> saved_LIBS="$LIBS" >>> CPPFLAGS="$CPPFLAGS libselinux_CPPFLAGS" >>> LDFLAGS="$LDFLAGS libselinux_LDFLAGS" >>> LIBS="$LIBS libselinux_LIBS" > Oops, I've made a typo, of course it should be $libselinux_CPPFLAGS, > $libselinux_LDFLAGS, and $libselinux_LIBS. My bad, just copy/pasted indeed ... > [...] >>>> diff --git a/src/access.c b/src/access.c >>>> index 2936242f7..81b78889b 100644 >>>> --- a/src/access.c >>>> +++ b/src/access.c >>>> @@ -34,8 +34,10 @@ decode_faccessat(struct tcb *tcp) >>>> { >>>> /* dirfd */ >>>> print_dirfd(tcp, tcp->u_arg[0]); >>>> +#ifdef USE_SELINUX >>>> + tcp->dirfd = (int)(tcp->u_arg[0]); >>>> +#endif >>>> tprint_arg_next(); >>>> - >>>> decode_access(tcp, 1); >>>> } >>>> [...] >>>> You've added a lot of such tcp->dirfd assignments. Apparently, >>>> they are added after every print_dirfd invocation except one (and that one >>>> seems to be omitted by mistake). If you want to cache dirfd processed by >>>> print_dirfd, it would be much easier if you just moved this assignment >>>> inside print_dirfd. >> Initially I had this idea as well but then thought it was ugly to have >> this state saved in print_dirfd(). >> >> Additionally we need to really know when to set the dirfd: there may be >> cases where print_dirfd() is called but the next arguments to the >> syscall won't use that dirfd as "reference". >> >> Hence it's safer to assign dirfd in the syscall handler itself. > I did "git grep -A1 'print_dirfd(' src/*.c" just to confirm that the only > place where print_dirfd invocation is not followed by "#ifdef USE_SELINUX" > is fsconfig where print_dirfd is used to print the last syscall argument. So you really prefer having this in print_dirfd() even though there would be a side effect and we cannot guarantee how print_dirfd() will be used in the future? If so, OK, I'll change this, it simplifies the code for sure. > [...] >>>> + } >>>> + xsprintf(pathtoresolve, "%s/%s", resolved, path); >>>> + if (realpath(pathtoresolve, resolved) == NULL) { >>> Interesting. Why realpath? Would stat_file be enough? >> No, because the path to check needs to be absolute, or else cwd of >> strace will be used for resolving the context, which is wrong. > realpath is very expensive because it performs canonicalization. > To check whether resolved/path is an absolute path, all we need is > to check whether resolved[0] == '/'. > Well actually realpath() is not needed at all, getfilecon() just works on paths with "/some/absolute/../relative/../" as well. -------------- next part -------------- A non-text attachment was scrubbed... Name: OpenPGP_signature Type: application/pgp-signature Size: 840 bytes Desc: OpenPGP digital signature URL: From ldv at altlinux.org Tue Mar 16 10:53:09 2021 From: ldv at altlinux.org (Dmitry V. Levin) Date: Tue, 16 Mar 2021 13:53:09 +0300 Subject: Proposing SELinux support in strace In-Reply-To: <007c7593-deb3-e39f-e63a-b2f541c308f7@redhat.com> References: <20210217001009.GA8097@altlinux.org> <2b816386-321d-5db6-6b84-19f987404863@redhat.com> <8553b7c6-a0fa-e202-4f0d-edb8a878a697@redhat.com> <20210305141819.GB14087@altlinux.org> <20210315011000.GA3123@altlinux.org> <2a0ba13b-620c-0bf6-11c7-c123947f0050@redhat.com> <20210315203328.GA17962@altlinux.org> <007c7593-deb3-e39f-e63a-b2f541c308f7@redhat.com> Message-ID: <20210316105309.GA28115@altlinux.org> On Tue, Mar 16, 2021 at 11:44:14AM +0100, Renaud M?trich wrote: [...] > So you really prefer having this in print_dirfd() even though there > would be a side effect and we cannot guarantee how print_dirfd() will be > used in the future? Yes, that's fine, let's add a comment about this side effect in defs.h where print_dirfd is declared, that should be enough. -- ldv From rmetrich at redhat.com Tue Mar 16 13:43:29 2021 From: rmetrich at redhat.com (=?UTF-8?Q?Renaud_M=c3=a9trich?=) Date: Tue, 16 Mar 2021 14:43:29 +0100 Subject: Proposing SELinux support in strace In-Reply-To: <20210316105309.GA28115@altlinux.org> References: <20210217001009.GA8097@altlinux.org> <2b816386-321d-5db6-6b84-19f987404863@redhat.com> <8553b7c6-a0fa-e202-4f0d-edb8a878a697@redhat.com> <20210305141819.GB14087@altlinux.org> <20210315011000.GA3123@altlinux.org> <2a0ba13b-620c-0bf6-11c7-c123947f0050@redhat.com> <20210315203328.GA17962@altlinux.org> <007c7593-deb3-e39f-e63a-b2f541c308f7@redhat.com> <20210316105309.GA28115@altlinux.org> Message-ID: OK, done. Final (?) patch in attachment. GitHub PR: https://github.com/strace/strace/pull/121 On 3/16/21 11:53 AM, Dmitry V. Levin wrote: > On Tue, Mar 16, 2021 at 11:44:14AM +0100, Renaud M?trich wrote: > [...] >> So you really prefer having this in print_dirfd() even though there >> would be a side effect and we cannot guarantee how print_dirfd() will be >> used in the future? > Yes, that's fine, let's add a comment about this side effect in defs.h > where print_dirfd is declared, that should be enough. > > -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-Print-SELinux-contexts-when-enabling-secontext-full-.patch Type: text/x-patch Size: 76953 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: OpenPGP_signature Type: application/pgp-signature Size: 840 bytes Desc: OpenPGP digital signature URL: From ldv at altlinux.org Wed Mar 17 01:15:59 2021 From: ldv at altlinux.org (Dmitry V. Levin) Date: Wed, 17 Mar 2021 04:15:59 +0300 Subject: Proposing SELinux support in strace In-Reply-To: References: <8553b7c6-a0fa-e202-4f0d-edb8a878a697@redhat.com> <20210305141819.GB14087@altlinux.org> <20210315011000.GA3123@altlinux.org> <2a0ba13b-620c-0bf6-11c7-c123947f0050@redhat.com> <20210315203328.GA17962@altlinux.org> <007c7593-deb3-e39f-e63a-b2f541c308f7@redhat.com> <20210316105309.GA28115@altlinux.org> Message-ID: <20210317011559.GA4853@altlinux.org> On Tue, Mar 16, 2021 at 02:43:29PM +0100, Renaud M?trich wrote: > OK, done. Final (?) patch in attachment. Not the final yet, but very close. Unless you want to keep the feature buried in the source code, please document it in doc/strace.1.in and mention --secontext in NEWS. There are also a few minor issues that have to be addressed, see below. With regards to CI, have you tried to add libselinux-dev to ci/install-dependencies.sh, does it make any difference? > diff --git a/m4/mpers.m4 b/m4/mpers.m4 > index 510aabe84..6fb40926d 100644 > --- a/m4/mpers.m4 > +++ b/m4/mpers.m4 > @@ -63,9 +63,11 @@ pushdef([mpers_name], [$1]) > pushdef([MPERS_NAME], translit([$1], [a-z], [A-Z])) > pushdef([HAVE_MPERS], [HAVE_]MPERS_NAME[_MPERS]) > pushdef([HAVE_RUNTIME], [HAVE_]MPERS_NAME[_RUNTIME]) > +pushdef([HAVE_SELINUX_RUNTIME], [HAVE_]MPERS_NAME[_SELINUX_RUNTIME]) > pushdef([MPERS_CFLAGS], [$cc_flags_$1]) > pushdef([st_cv_cc], [st_cv_$1_cc]) > pushdef([st_cv_runtime], [st_cv_$1_runtime]) > +pushdef([st_cv_selinux_runtime], [st_cv_$1_selinux_runtime]) > pushdef([st_cv_mpers], [st_cv_$1_mpers]) > > pushdef([EXEEXT], MPERS_NAME[_EXEEXT])dnl > @@ -126,6 +128,26 @@ case "$arch" in > else > st_cv_mpers=no > fi]) > + AS_IF([test "x$with_secontexts$st_cv_mpers$st_cv_runtime" = xyesyesyes], > + AC_CACHE_CHECK([whether selinux runtime works with mpers_name personality], > + [st_cv_selinux_runtime], > + [saved_CPPFLAGS="$CPPFLAGS" > + saved_LDFLAGS="$LDFLAGS" > + saved_LIBS="$LIBS" > + CPPFLAGS="$CPPFLAGS $libselinux_CPPFLAGS" > + LDFLAGS="$LDFLAGS $libselinux_LDFLAGS" > + LIBS="$LIBS $libselinux_LIBS" > + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], > + [[return 0]])], > + [st_cv_selinux_runtime=yes], > + [st_cv_selinux_runtime=no], > + [st_cv_selinux_runtime=no]) > + LIBS="$saved_LIBS" > + LDFLAGS="$saved_LDFLAGS" > + CPPFLAGS="$saved_CPPFLAGS" > + ], > + [st_cv_selinux_runtime=no]) > + ) The last [st_cv_selinux_runtime=no] should be the "else" branch of AS_IF. > diff --git a/src/access.c b/src/access.c > index 2936242f7..214a32f6d 100644 > --- a/src/access.c > +++ b/src/access.c > @@ -35,7 +35,6 @@ decode_faccessat(struct tcb *tcp) > /* dirfd */ > print_dirfd(tcp, tcp->u_arg[0]); > tprint_arg_next(); > - > decode_access(tcp, 1); > } > Please drop this. > diff --git a/src/dirent.c b/src/dirent.c > index 3c2c09e9b..ca56f15cd 100644 > --- a/src/dirent.c > +++ b/src/dirent.c > @@ -106,6 +106,9 @@ SYS_FUNC(readdir) > if (entering(tcp)) { > /* fd */ > printfd(tcp, tcp->u_arg[0]); > +#ifdef USE_SELINUX > + tcp->last_dirfd = (int)(tcp->u_arg[0]); > +#endif > tprint_arg_next(); > } else { > /* dirp */ OK > diff --git a/src/fanotify.c b/src/fanotify.c > index 9e8071009..f60dcf09c 100644 > --- a/src/fanotify.c > +++ b/src/fanotify.c > @@ -57,8 +57,9 @@ SYS_FUNC(fanotify_mark) > tprints(", "); > if ((int) tcp->u_arg[argn] == FAN_NOFD) > print_xlat_d(FAN_NOFD); > - else > + else { > print_dirfd(tcp, tcp->u_arg[argn]); > + } > tprints(", "); > printpath(tcp, tcp->u_arg[argn + 1]); > Please drop this. > diff --git a/src/open.c b/src/open.c > index b48fc087a..a364c56a5 100644 > --- a/src/open.c > +++ b/src/open.c > @@ -33,6 +33,9 @@ print_dirfd(struct tcb *tcp, int fd) > print_xlat_d(AT_FDCWD); > else > printfd(tcp, fd); > +#ifdef USE_SELINUX > + tcp->last_dirfd = fd; > +#endif > } > > /* OK > diff --git a/src/selinux.c b/src/selinux.c > new file mode 100644 > index 000000000..5e9fc9126 > --- /dev/null > +++ b/src/selinux.c > @@ -0,0 +1,128 @@ > +/* > + * Copyright (c) 2020-2021 The strace developers. > + * All rights reserved. > + * > + * SPDX-License-Identifier: LGPL-2.1-or-later > + */ > + > +#include "defs.h" > + > +#include > +#include > +#include > +#include > + > +#include "selinux.h" > +#include "xstring.h" > + > +bool selinux_context = false; > +bool selinux_context_full = false; > + > +static int > +getcontext(int rc, char **secontext, char **result) > +{ > + if (rc < 0) > + return rc; > + > + *result = NULL; > + if (!selinux_context_full) { > + char *saveptr = NULL; > + char *secontext_copy = xstrdup(*secontext); > + const char *token; > + unsigned int i; > + > + /* > + * We only want to keep the type (3rd field, ':' separator). > + */ > + for (token = strtok_r(secontext_copy, ":", &saveptr), i = 0; > + token; token = strtok_r(NULL, ":", &saveptr), i++) { > + if (i == 2) { > + *result = xstrdup(token); > + break; > + } > + } > + free(secontext_copy); > + } > + > + if (*result == NULL) > + *result = xstrdup(*secontext); > + freecon(*secontext); > + return 0; > +} > +/* > + * Retrieves the SELinux context of the given PID (extracted from the tcb). > + * Memory must be freed. > + * Returns 0 on success, -1 on failure. > + */ > +int > +selinux_getpidcon(struct tcb *tcp, char **result) > +{ > + if (!selinux_context) > + return -1; > + > + int proc_pid = 0; > + translate_pid(NULL, tcp->pid, PT_TID, &proc_pid); > + if (!proc_pid) > + return -1; > + > + char *secontext; > + return getcontext(getpidcon(proc_pid, &secontext), &secontext, result); > +} > + > +/* > + * Retrieves the SELinux context of the given path. > + * Memory must be freed. > + * Returns 0 on success, -1 on failure. > + */ > +int > +selinux_getfilecon(struct tcb *tcp, const char *path, char **result) > +{ > + if (!selinux_context) > + return -1; > + > + /* > + * Current limitation: we cannot query the path if we are in different > + * mount namespaces. > + */ > + if (get_mnt_ns(tcp) != get_our_mnt_ns()) > + return -1; > + > + char *secontext; > + > + if (path[0] == '/') > + return getcontext(getfilecon(path, &secontext), &secontext, result); > + > + char resolved[PATH_MAX + 1]; > + > + /* > + * If we have a relative pathname and 'last_dirfd' == AT_FDCWD, we need > + * to prepend by the CWD. > + */ > + if (tcp->last_dirfd == AT_FDCWD) { > + int proc_pid = 0; > + translate_pid(NULL, tcp->pid, PT_TID, &proc_pid); > + if (!proc_pid) > + return -1; > + > + char linkpath[sizeof("/proc/%u/cwd") + sizeof(int)*3]; > + xsprintf(linkpath, "/proc/%u/cwd", proc_pid); > + > + ssize_t n = readlink(linkpath, resolved, sizeof(resolved) - 1); > + /* > + * NB: if buffer is too small, readlink doesn't fail, > + * it returns truncated result. > + */ > + if (n == sizeof(resolved) - 1) > + return -1; > + resolved[n] = '\0'; > + } else { > + if (getfdpath_pid(tcp->pid, tcp->last_dirfd, > + resolved, sizeof(resolved)) < 0) > + return -1; > + } Since readlink can return a path that doesn't start with '/', let's be on the safe side and check against that: if (resolved[0] != '/') return -1; > + > + char pathtoresolve[2 * PATH_MAX + 2]; > + xsprintf(pathtoresolve, "%s/%s", resolved, path); > + > + return getcontext(getfilecon(pathtoresolve, &secontext), &secontext, result); > +} [...] > @@ -2321,6 +2356,17 @@ init(int argc, char *argv[]) > case GETOPT_SECCOMP: > seccomp_filtering = true; > break; > +#ifdef USE_SELINUX > + case GETOPT_SELINUX_CONTEXT: > + selinux_context = true; > + if (optarg) { > + if (!strcmp(optarg, "full")) > + selinux_context_full = true; > + else > + error_opt_arg(c, lopt, optarg); > + } > + break; > +#endif The "else" branch is not covered by the test suite. > case GETOPT_QUAL_TRACE: > qualify_trace(optarg); > break; > @@ -2503,6 +2549,11 @@ init(int argc, char *argv[]) > if (!number_set_array_is_empty(decode_fd_set, 0)) > error_msg("-y/--decode-fds has no effect " > "with -c/--summary-only"); > +#ifdef USE_SELINUX > + if (selinux_context) > + error_msg("--secontext has no effect with " > + "-c/--summary-only"); > +#endif This is not covered by the test suite. > diff --git a/src/syscall.c b/src/syscall.c > index d143f257b..245cc7419 100644 > --- a/src/syscall.c > +++ b/src/syscall.c > @@ -24,6 +24,7 @@ > #include "poke.h" > #include "retval.h" > #include > +#include > > /* for struct iovec */ > #include > @@ -1019,6 +1020,10 @@ syscall_exiting_finish(struct tcb *tcp) > tcp->sys_func_rval = 0; > free_tcb_priv_data(tcp); > > +#ifdef USE_SELINUX > + tcp->last_dirfd = AT_FDCWD; > +#endif > + > if (cflag) > tcp->ltime = tcp->stime; > } OK > diff --git a/src/xgetdents.c b/src/xgetdents.c > index 4de5fbc10..6a0144bbf 100644 > --- a/src/xgetdents.c > +++ b/src/xgetdents.c > @@ -122,6 +122,9 @@ xgetdents(struct tcb *const tcp, const unsigned int header_size, > { > if (entering(tcp)) { > printfd(tcp, tcp->u_arg[0]); > +#ifdef USE_SELINUX > + tcp->last_dirfd = (int)(tcp->u_arg[0]); > +#endif > tprints(", "); > return 0; > } OK > diff --git a/tests/Makefile.am b/tests/Makefile.am > index b8efce824..8076719da 100644 > --- a/tests/Makefile.am > +++ b/tests/Makefile.am > @@ -292,6 +292,63 @@ check_PROGRAMS = $(PURE_EXECUTABLES) \ > zeroargc \ > # end of check_PROGRAMS > > +check_PROGRAMS += \ > + access--secontext \ > + access--secontext_full \ > + chmod--secontext \ > + chmod--secontext_full \ > + execve--secontext \ > + execve--secontext_full \ > + execveat--secontext \ > + execveat--secontext_full \ > + faccessat--secontext \ > + faccessat--secontext_full \ > + fanotify_mark--secontext \ > + fanotify_mark--secontext_full \ > + fchmod--secontext \ > + fchmod--secontext_full \ > + fchmodat--secontext \ > + fchmodat--secontext_full \ > + fchownat--secontext \ > + fchownat--secontext_full \ > + file_handle--secontext \ > + file_handle--secontext_full \ > + linkat--secontext \ > + linkat--secontext_full \ > + openat--secontext \ > + openat--secontext_full Could you put this list to secontext_PROGRAMS and add $(secontext_PROGRAMS) to check_PROGRAMS instead, please? > diff --git a/tests/access--secontext.c b/tests/access--secontext.c > new file mode 100644 > index 000000000..8ba2c02df > --- /dev/null > +++ b/tests/access--secontext.c > @@ -0,0 +1,57 @@ > +/* > + * Copyright (c) 2021 The strace developers. > + * All rights reserved. > + * > + * SPDX-License-Identifier: GPL-2.0-or-later > + */ > + > +#include "tests.h" > +#include "scno.h" > + > +/* > + * This test is designed to be executed with the following strace options: > + * --secontext[=full] > + */ > + > +#if defined __NR_access && defined HAVE_SELINUX_RUNTIME > + > +# include > +# include > +# include > +# include > + > +# include "selinux.c" > + > +int > +main(void) > +{ > + static const char sample[] = "access_sample"; > + > + unlink(sample); > + if (open(sample, O_CREAT|O_RDONLY, 0400) == -1) > + perror_msg_and_fail("open"); > + > + long rc = syscall(__NR_access, sample, F_OK); > + printf("%saccess(\"%s\"%s, F_OK) = %s\n", > + SELINUX_MYCONTEXT(), > + sample, SELINUX_FILECONTEXT(sample), > + sprintrc(rc)); > + > + if (unlink(sample) == -1) > + perror_msg_and_fail("unlink"); > + > + rc = syscall(__NR_access, sample, F_OK); > + printf("%saccess(\"%s\", F_OK) = %ld %s (%m)\n", > + SELINUX_MYCONTEXT(), > + sample, > + rc, errno2name()); Since you used sprintrc(rc) in the previous printf, you can use it here as well. errno2name() was introduced before sprintrc(), in most cases where you can see errno2name() it's just an old test that hasn't been converted to sprintrc(). This applies to other tests, too. > diff --git a/tests/selinux.c b/tests/selinux.c > new file mode 100644 > index 000000000..9335f0534 > --- /dev/null > +++ b/tests/selinux.c > @@ -0,0 +1,192 @@ > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include Since xmalloc.h is not a system header, please use "xmalloc.h". [...] > +char * > +context_format(char *context, const char *fmt) > +{ > + char *res; > + int saved_errno = errno; > + > + if (context == NULL) { > + res = strdup(""); In this and other places, please use xstrdup. > + errno = saved_errno; > + return res; > + } > + > + res = xasprintf(fmt, context); > + free(context); > + > + errno = saved_errno; > + return res; This code could be simplified, e.g.: int saved_errno = errno; char *res = context ? xasprintf(fmt, context) : xstrdup(""); free(context); errno = saved_errno; return res; > +} > + > +char * > +get_file_context_full(const char *filename) > +{ > + int res; > + char *secontext; > + int saved_errno = errno; > + > + res = getfilecon(filename, &secontext); > + if (res == -1) > + goto fail; > + > + char *full_context = strdup(secontext); > + freecon(secontext); > + > + errno = saved_errno; > + return full_context; > + > +fail: > + errno = saved_errno; > + return NULL; It seems to me that this code could be simplified, e.g.: int saved_errno = errno; char *full_context = NULL; char *secontext; if (getfilecon(filename, &secontext) == 0) { full_context = xstrdup(secontext); freecon(secontext); } errno = saved_errno; return full_context; This also applies to get_pid_context_full. -- ldv From rmetrich at redhat.com Wed Mar 17 15:04:11 2021 From: rmetrich at redhat.com (=?UTF-8?Q?Renaud_M=c3=a9trich?=) Date: Wed, 17 Mar 2021 16:04:11 +0100 Subject: Proposing SELinux support in strace In-Reply-To: <20210317011559.GA4853@altlinux.org> References: <8553b7c6-a0fa-e202-4f0d-edb8a878a697@redhat.com> <20210305141819.GB14087@altlinux.org> <20210315011000.GA3123@altlinux.org> <2a0ba13b-620c-0bf6-11c7-c123947f0050@redhat.com> <20210315203328.GA17962@altlinux.org> <007c7593-deb3-e39f-e63a-b2f541c308f7@redhat.com> <20210316105309.GA28115@altlinux.org> <20210317011559.GA4853@altlinux.org> Message-ID: Hi Dmitry, thanks again. All fixed now. Code coverage improved. Regarding adding libselinux-dev, this didn't make a difference, so I finally removed it. Patch attached. On 3/17/21 2:15 AM, Dmitry V. Levin wrote: > On Tue, Mar 16, 2021 at 02:43:29PM +0100, Renaud M?trich wrote: >> OK, done. Final (?) patch in attachment. > Not the final yet, but very close. > > Unless you want to keep the feature buried in the source code, please > document it in doc/strace.1.in and mention --secontext in NEWS. > > There are also a few minor issues that have to be addressed, > see below. > > With regards to CI, have you tried to add libselinux-dev > to ci/install-dependencies.sh, does it make any difference? > >> diff --git a/m4/mpers.m4 b/m4/mpers.m4 >> index 510aabe84..6fb40926d 100644 >> --- a/m4/mpers.m4 >> +++ b/m4/mpers.m4 >> @@ -63,9 +63,11 @@ pushdef([mpers_name], [$1]) >> pushdef([MPERS_NAME], translit([$1], [a-z], [A-Z])) >> pushdef([HAVE_MPERS], [HAVE_]MPERS_NAME[_MPERS]) >> pushdef([HAVE_RUNTIME], [HAVE_]MPERS_NAME[_RUNTIME]) >> +pushdef([HAVE_SELINUX_RUNTIME], [HAVE_]MPERS_NAME[_SELINUX_RUNTIME]) >> pushdef([MPERS_CFLAGS], [$cc_flags_$1]) >> pushdef([st_cv_cc], [st_cv_$1_cc]) >> pushdef([st_cv_runtime], [st_cv_$1_runtime]) >> +pushdef([st_cv_selinux_runtime], [st_cv_$1_selinux_runtime]) >> pushdef([st_cv_mpers], [st_cv_$1_mpers]) >> >> pushdef([EXEEXT], MPERS_NAME[_EXEEXT])dnl >> @@ -126,6 +128,26 @@ case "$arch" in >> else >> st_cv_mpers=no >> fi]) >> + AS_IF([test "x$with_secontexts$st_cv_mpers$st_cv_runtime" = xyesyesyes], >> + AC_CACHE_CHECK([whether selinux runtime works with mpers_name personality], >> + [st_cv_selinux_runtime], >> + [saved_CPPFLAGS="$CPPFLAGS" >> + saved_LDFLAGS="$LDFLAGS" >> + saved_LIBS="$LIBS" >> + CPPFLAGS="$CPPFLAGS $libselinux_CPPFLAGS" >> + LDFLAGS="$LDFLAGS $libselinux_LDFLAGS" >> + LIBS="$LIBS $libselinux_LIBS" >> + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], >> + [[return 0]])], >> + [st_cv_selinux_runtime=yes], >> + [st_cv_selinux_runtime=no], >> + [st_cv_selinux_runtime=no]) >> + LIBS="$saved_LIBS" >> + LDFLAGS="$saved_LDFLAGS" >> + CPPFLAGS="$saved_CPPFLAGS" >> + ], >> + [st_cv_selinux_runtime=no]) >> + ) > The last [st_cv_selinux_runtime=no] should be the "else" branch of AS_IF. > >> diff --git a/src/access.c b/src/access.c >> index 2936242f7..214a32f6d 100644 >> --- a/src/access.c >> +++ b/src/access.c >> @@ -35,7 +35,6 @@ decode_faccessat(struct tcb *tcp) >> /* dirfd */ >> print_dirfd(tcp, tcp->u_arg[0]); >> tprint_arg_next(); >> - >> decode_access(tcp, 1); >> } >> > Please drop this. > >> diff --git a/src/dirent.c b/src/dirent.c >> index 3c2c09e9b..ca56f15cd 100644 >> --- a/src/dirent.c >> +++ b/src/dirent.c >> @@ -106,6 +106,9 @@ SYS_FUNC(readdir) >> if (entering(tcp)) { >> /* fd */ >> printfd(tcp, tcp->u_arg[0]); >> +#ifdef USE_SELINUX >> + tcp->last_dirfd = (int)(tcp->u_arg[0]); >> +#endif >> tprint_arg_next(); >> } else { >> /* dirp */ > OK > >> diff --git a/src/fanotify.c b/src/fanotify.c >> index 9e8071009..f60dcf09c 100644 >> --- a/src/fanotify.c >> +++ b/src/fanotify.c >> @@ -57,8 +57,9 @@ SYS_FUNC(fanotify_mark) >> tprints(", "); >> if ((int) tcp->u_arg[argn] == FAN_NOFD) >> print_xlat_d(FAN_NOFD); >> - else >> + else { >> print_dirfd(tcp, tcp->u_arg[argn]); >> + } >> tprints(", "); >> printpath(tcp, tcp->u_arg[argn + 1]); >> > Please drop this. > >> diff --git a/src/open.c b/src/open.c >> index b48fc087a..a364c56a5 100644 >> --- a/src/open.c >> +++ b/src/open.c >> @@ -33,6 +33,9 @@ print_dirfd(struct tcb *tcp, int fd) >> print_xlat_d(AT_FDCWD); >> else >> printfd(tcp, fd); >> +#ifdef USE_SELINUX >> + tcp->last_dirfd = fd; >> +#endif >> } >> >> /* > OK > >> diff --git a/src/selinux.c b/src/selinux.c >> new file mode 100644 >> index 000000000..5e9fc9126 >> --- /dev/null >> +++ b/src/selinux.c >> @@ -0,0 +1,128 @@ >> +/* >> + * Copyright (c) 2020-2021 The strace developers. >> + * All rights reserved. >> + * >> + * SPDX-License-Identifier: LGPL-2.1-or-later >> + */ >> + >> +#include "defs.h" >> + >> +#include >> +#include >> +#include >> +#include >> + >> +#include "selinux.h" >> +#include "xstring.h" >> + >> +bool selinux_context = false; >> +bool selinux_context_full = false; >> + >> +static int >> +getcontext(int rc, char **secontext, char **result) >> +{ >> + if (rc < 0) >> + return rc; >> + >> + *result = NULL; >> + if (!selinux_context_full) { >> + char *saveptr = NULL; >> + char *secontext_copy = xstrdup(*secontext); >> + const char *token; >> + unsigned int i; >> + >> + /* >> + * We only want to keep the type (3rd field, ':' separator). >> + */ >> + for (token = strtok_r(secontext_copy, ":", &saveptr), i = 0; >> + token; token = strtok_r(NULL, ":", &saveptr), i++) { >> + if (i == 2) { >> + *result = xstrdup(token); >> + break; >> + } >> + } >> + free(secontext_copy); >> + } >> + >> + if (*result == NULL) >> + *result = xstrdup(*secontext); >> + freecon(*secontext); >> + return 0; >> +} >> +/* >> + * Retrieves the SELinux context of the given PID (extracted from the tcb). >> + * Memory must be freed. >> + * Returns 0 on success, -1 on failure. >> + */ >> +int >> +selinux_getpidcon(struct tcb *tcp, char **result) >> +{ >> + if (!selinux_context) >> + return -1; >> + >> + int proc_pid = 0; >> + translate_pid(NULL, tcp->pid, PT_TID, &proc_pid); >> + if (!proc_pid) >> + return -1; >> + >> + char *secontext; >> + return getcontext(getpidcon(proc_pid, &secontext), &secontext, result); >> +} >> + >> +/* >> + * Retrieves the SELinux context of the given path. >> + * Memory must be freed. >> + * Returns 0 on success, -1 on failure. >> + */ >> +int >> +selinux_getfilecon(struct tcb *tcp, const char *path, char **result) >> +{ >> + if (!selinux_context) >> + return -1; >> + >> + /* >> + * Current limitation: we cannot query the path if we are in different >> + * mount namespaces. >> + */ >> + if (get_mnt_ns(tcp) != get_our_mnt_ns()) >> + return -1; >> + >> + char *secontext; >> + >> + if (path[0] == '/') >> + return getcontext(getfilecon(path, &secontext), &secontext, result); >> + >> + char resolved[PATH_MAX + 1]; >> + >> + /* >> + * If we have a relative pathname and 'last_dirfd' == AT_FDCWD, we need >> + * to prepend by the CWD. >> + */ >> + if (tcp->last_dirfd == AT_FDCWD) { >> + int proc_pid = 0; >> + translate_pid(NULL, tcp->pid, PT_TID, &proc_pid); >> + if (!proc_pid) >> + return -1; >> + >> + char linkpath[sizeof("/proc/%u/cwd") + sizeof(int)*3]; >> + xsprintf(linkpath, "/proc/%u/cwd", proc_pid); >> + >> + ssize_t n = readlink(linkpath, resolved, sizeof(resolved) - 1); >> + /* >> + * NB: if buffer is too small, readlink doesn't fail, >> + * it returns truncated result. >> + */ >> + if (n == sizeof(resolved) - 1) >> + return -1; >> + resolved[n] = '\0'; >> + } else { >> + if (getfdpath_pid(tcp->pid, tcp->last_dirfd, >> + resolved, sizeof(resolved)) < 0) >> + return -1; >> + } > Since readlink can return a path that doesn't start with '/', let's be on > the safe side and check against that: > > if (resolved[0] != '/') > return -1; > >> + >> + char pathtoresolve[2 * PATH_MAX + 2]; >> + xsprintf(pathtoresolve, "%s/%s", resolved, path); >> + >> + return getcontext(getfilecon(pathtoresolve, &secontext), &secontext, result); >> +} > [...] >> @@ -2321,6 +2356,17 @@ init(int argc, char *argv[]) >> case GETOPT_SECCOMP: >> seccomp_filtering = true; >> break; >> +#ifdef USE_SELINUX >> + case GETOPT_SELINUX_CONTEXT: >> + selinux_context = true; >> + if (optarg) { >> + if (!strcmp(optarg, "full")) >> + selinux_context_full = true; >> + else >> + error_opt_arg(c, lopt, optarg); >> + } >> + break; >> +#endif > The "else" branch is not covered by the test suite. > >> case GETOPT_QUAL_TRACE: >> qualify_trace(optarg); >> break; >> @@ -2503,6 +2549,11 @@ init(int argc, char *argv[]) >> if (!number_set_array_is_empty(decode_fd_set, 0)) >> error_msg("-y/--decode-fds has no effect " >> "with -c/--summary-only"); >> +#ifdef USE_SELINUX >> + if (selinux_context) >> + error_msg("--secontext has no effect with " >> + "-c/--summary-only"); >> +#endif > This is not covered by the test suite. > >> diff --git a/src/syscall.c b/src/syscall.c >> index d143f257b..245cc7419 100644 >> --- a/src/syscall.c >> +++ b/src/syscall.c >> @@ -24,6 +24,7 @@ >> #include "poke.h" >> #include "retval.h" >> #include >> +#include >> >> /* for struct iovec */ >> #include >> @@ -1019,6 +1020,10 @@ syscall_exiting_finish(struct tcb *tcp) >> tcp->sys_func_rval = 0; >> free_tcb_priv_data(tcp); >> >> +#ifdef USE_SELINUX >> + tcp->last_dirfd = AT_FDCWD; >> +#endif >> + >> if (cflag) >> tcp->ltime = tcp->stime; >> } > OK > >> diff --git a/src/xgetdents.c b/src/xgetdents.c >> index 4de5fbc10..6a0144bbf 100644 >> --- a/src/xgetdents.c >> +++ b/src/xgetdents.c >> @@ -122,6 +122,9 @@ xgetdents(struct tcb *const tcp, const unsigned int header_size, >> { >> if (entering(tcp)) { >> printfd(tcp, tcp->u_arg[0]); >> +#ifdef USE_SELINUX >> + tcp->last_dirfd = (int)(tcp->u_arg[0]); >> +#endif >> tprints(", "); >> return 0; >> } > OK > >> diff --git a/tests/Makefile.am b/tests/Makefile.am >> index b8efce824..8076719da 100644 >> --- a/tests/Makefile.am >> +++ b/tests/Makefile.am >> @@ -292,6 +292,63 @@ check_PROGRAMS = $(PURE_EXECUTABLES) \ >> zeroargc \ >> # end of check_PROGRAMS >> >> +check_PROGRAMS += \ >> + access--secontext \ >> + access--secontext_full \ >> + chmod--secontext \ >> + chmod--secontext_full \ >> + execve--secontext \ >> + execve--secontext_full \ >> + execveat--secontext \ >> + execveat--secontext_full \ >> + faccessat--secontext \ >> + faccessat--secontext_full \ >> + fanotify_mark--secontext \ >> + fanotify_mark--secontext_full \ >> + fchmod--secontext \ >> + fchmod--secontext_full \ >> + fchmodat--secontext \ >> + fchmodat--secontext_full \ >> + fchownat--secontext \ >> + fchownat--secontext_full \ >> + file_handle--secontext \ >> + file_handle--secontext_full \ >> + linkat--secontext \ >> + linkat--secontext_full \ >> + openat--secontext \ >> + openat--secontext_full > Could you put this list to secontext_PROGRAMS and add > $(secontext_PROGRAMS) to check_PROGRAMS instead, please? > >> diff --git a/tests/access--secontext.c b/tests/access--secontext.c >> new file mode 100644 >> index 000000000..8ba2c02df >> --- /dev/null >> +++ b/tests/access--secontext.c >> @@ -0,0 +1,57 @@ >> +/* >> + * Copyright (c) 2021 The strace developers. >> + * All rights reserved. >> + * >> + * SPDX-License-Identifier: GPL-2.0-or-later >> + */ >> + >> +#include "tests.h" >> +#include "scno.h" >> + >> +/* >> + * This test is designed to be executed with the following strace options: >> + * --secontext[=full] >> + */ >> + >> +#if defined __NR_access && defined HAVE_SELINUX_RUNTIME >> + >> +# include >> +# include >> +# include >> +# include >> + >> +# include "selinux.c" >> + >> +int >> +main(void) >> +{ >> + static const char sample[] = "access_sample"; >> + >> + unlink(sample); >> + if (open(sample, O_CREAT|O_RDONLY, 0400) == -1) >> + perror_msg_and_fail("open"); >> + >> + long rc = syscall(__NR_access, sample, F_OK); >> + printf("%saccess(\"%s\"%s, F_OK) = %s\n", >> + SELINUX_MYCONTEXT(), >> + sample, SELINUX_FILECONTEXT(sample), >> + sprintrc(rc)); >> + >> + if (unlink(sample) == -1) >> + perror_msg_and_fail("unlink"); >> + >> + rc = syscall(__NR_access, sample, F_OK); >> + printf("%saccess(\"%s\", F_OK) = %ld %s (%m)\n", >> + SELINUX_MYCONTEXT(), >> + sample, >> + rc, errno2name()); > Since you used sprintrc(rc) in the previous printf, you can use it here as well. > > errno2name() was introduced before sprintrc(), in most cases where you > can see errno2name() it's just an old test that hasn't been converted > to sprintrc(). > > This applies to other tests, too. > >> diff --git a/tests/selinux.c b/tests/selinux.c >> new file mode 100644 >> index 000000000..9335f0534 >> --- /dev/null >> +++ b/tests/selinux.c >> @@ -0,0 +1,192 @@ >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include > Since xmalloc.h is not a system header, please use "xmalloc.h". > > [...] >> +char * >> +context_format(char *context, const char *fmt) >> +{ >> + char *res; >> + int saved_errno = errno; >> + >> + if (context == NULL) { >> + res = strdup(""); > In this and other places, please use xstrdup. > >> + errno = saved_errno; >> + return res; >> + } >> + >> + res = xasprintf(fmt, context); >> + free(context); >> + >> + errno = saved_errno; >> + return res; > This code could be simplified, e.g.: > > int saved_errno = errno; > char *res = context ? xasprintf(fmt, context) : xstrdup(""); > free(context); > errno = saved_errno; > return res; > >> +} >> + >> +char * >> +get_file_context_full(const char *filename) >> +{ >> + int res; >> + char *secontext; >> + int saved_errno = errno; >> + >> + res = getfilecon(filename, &secontext); >> + if (res == -1) >> + goto fail; >> + >> + char *full_context = strdup(secontext); >> + freecon(secontext); >> + >> + errno = saved_errno; >> + return full_context; >> + >> +fail: >> + errno = saved_errno; >> + return NULL; > It seems to me that this code could be simplified, e.g.: > > int saved_errno = errno; > char *full_context = NULL; > char *secontext; > if (getfilecon(filename, &secontext) == 0) { > full_context = xstrdup(secontext); > freecon(secontext); > } > errno = saved_errno; > return full_context; > > This also applies to get_pid_context_full. > > -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-Print-SELinux-contexts-when-enabling-secontext-full-.patch Type: text/x-patch Size: 79593 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: OpenPGP_signature Type: application/pgp-signature Size: 840 bytes Desc: OpenPGP digital signature URL: From ldv at altlinux.org Thu Mar 18 02:49:35 2021 From: ldv at altlinux.org (Dmitry V. Levin) Date: Thu, 18 Mar 2021 05:49:35 +0300 Subject: Proposing SELinux support in strace In-Reply-To: References: <20210315011000.GA3123@altlinux.org> <2a0ba13b-620c-0bf6-11c7-c123947f0050@redhat.com> <20210315203328.GA17962@altlinux.org> <007c7593-deb3-e39f-e63a-b2f541c308f7@redhat.com> <20210316105309.GA28115@altlinux.org> <20210317011559.GA4853@altlinux.org> Message-ID: <20210318024935.GA23192@altlinux.org> On Wed, Mar 17, 2021 at 04:04:11PM +0100, Renaud M?trich wrote: > Hi Dmitry, thanks again. All fixed now. Code coverage improved. > > Regarding adding libselinux-dev, this didn't make a difference, so I > finally removed it. > > Patch attached. Great. Let's clear remaining few documentation and formatting bits. > Subject: [PATCH] Print SELinux contexts when enabling "--secontext[=full]" > (not compatible with "-c"). I'm not sure whether this level of detail in the summary is really needed. I suggest a bit more concise wording: Implement --secontext[=full] option to display SELinux contexts > This is very useful when debugging SELinux issues, in particular when a > process runs in an unexpected context or didn't transition properly, or > typically when a file being opened has not the proper context. A comma is needed after "in particular". > Parameter "full" may be used to print the full context, as shown in the > example below: I suggest a slightly different wording: When --secontext=full is specified, strace will print the complete context (user, role, type and category) instead of just the type which is printed for --secontext option, as shown in the examples below: [...] > To implement this, a new "--with-libselinux" automake option has been > introduced. It defaults to "check", which means automatic support on > SELinux aware systems. It's a configure option rather than an automake or autoconf. > diff --git a/doc/strace.1.in b/doc/strace.1.in > index 05c32d902..e310e0877 100644 > --- a/doc/strace.1.in > +++ b/doc/strace.1.in > @@ -53,6 +53,7 @@ strace \- trace system calls and signals > .OM \-P path > .OM \-p pid > .OP \-\-seccomp\-bpf > +.if '@USE_SELINUX_FALSE@'#' .OP \-\-secontext[=full] [=full] should not be bold, consider changing the line to .if '@USE_SELINUX_FALSE@'#' .OP \-\-secontext\fR[=\fIfull\fR] > @@ -1440,6 +1441,13 @@ In cases when seccomp-bpf filter setup failed, > .B strace > proceeds as usual and stops traced processes on every system call. > .TP > +.B \-\-secontext[=full] Likewise, [=full] should not be bold, consider changing the line to .BR \-\-secontext "[=" \fIfull\fR "]" > +Print SELinux contexts of processes and files in square brackets when SELinux is available and not disabled. The line is too long, please wrap. > +When > +.BR full This should rather be .I full > +is specified, print the complete context (user, role, type and category) instead of just the type. The line is too long, please wrap. > +The current implementation has limitations, in particular it does not support Mount namespaces. In this case, no context will be printed. I suggest a slightly different wording: The current implementation has limitations, in particular, SELinux contexts cannot be printed when .B strace and the tracee belong to different mount namespaces. > @@ -1164,6 +1182,11 @@ extern void print_ax25_addr(const void /* ax25_address */ *addr); > extern void print_x25_addr(const void /* struct x25_address */ *addr); > extern const char *get_sockaddr_by_inode(struct tcb *, int fd, unsigned long inode); > extern bool print_sockaddr_by_inode(struct tcb *, int fd, unsigned long inode); > + > +/** > + * Prints dirfd file descriptor and saves it in tcp->last_dirfd (used when > + * printing SELinux contexts). > + */ I suggest a slightly different wording: Prints dirfd file descriptor and saves it in tcp->last_dirfd, the latter is used when printing SELinux contexts. > diff --git a/src/dirent.c b/src/dirent.c > index 3c2c09e9b..ca56f15cd 100644 > --- a/src/dirent.c > +++ b/src/dirent.c > @@ -106,6 +106,9 @@ SYS_FUNC(readdir) > if (entering(tcp)) { > /* fd */ > printfd(tcp, tcp->u_arg[0]); > +#ifdef USE_SELINUX > + tcp->last_dirfd = (int)(tcp->u_arg[0]); We usually format casts this way: tcp->last_dirfd = (int) tcp->u_arg[0]; > diff --git a/src/xgetdents.c b/src/xgetdents.c > index 4de5fbc10..6a0144bbf 100644 > --- a/src/xgetdents.c > +++ b/src/xgetdents.c > @@ -122,6 +122,9 @@ xgetdents(struct tcb *const tcp, const unsigned int header_size, > { > if (entering(tcp)) { > printfd(tcp, tcp->u_arg[0]); > +#ifdef USE_SELINUX > + tcp->last_dirfd = (int)(tcp->u_arg[0]); Likewise. > @@ -445,6 +455,14 @@ Miscellaneous:\n\ > -d, --debug enable debug output to stderr\n\ > -h, --help print help message\n\ > --seccomp-bpf enable seccomp-bpf filtering\n\ > +" > +#ifdef USE_SELINUX > +"\ > + --secontext[=full]\n\ > + print SELinux contexts (type only unless 'full' is specified)\n\ > +" > +#endif > +"\ > -V, --version print version\n\ > " > /* ancient, no one should use it I think this should go to the end of "Output format:" section rather "Miscellaneous:". > @@ -46,6 +48,7 @@ check_e '-t and --absolute-timestamps cannot be provided simultaneously' -t --ti > check_e '-t and --absolute-timestamps cannot be provided simultaneously' --absolute-timestamps -ttt -p $$ > check_e '-t and --absolute-timestamps cannot be provided simultaneously' -t --timestamps=ns -t -p $$ > check_e '-t and --absolute-timestamps cannot be provided simultaneously' --timestamps=ns -t --absolute-timestamps=unix -p $$ > +[ -n "$compiled_with_secontext" ] && check_h "invalid --secontext argument: 'ss'" --secontext=ss We prefer writing it this way: [ -z "$compiled_with_secontext" ] || check_h "invalid --secontext argument: 'ss'" --secontext=ss > +#define CONTEXT_FORMAT_SPACE_BEFORE(string) context_format(string, " [%s]") > +#define CONTEXT_FORMAT_SPACE_AFTER(string) context_format(string, "[%s] ") > +#define CONTEXT_FORMAT_SPACE_BEFORE_QUOTED(string) context_format(string, " \\[%s\\]") > +#define CONTEXT_FORMAT_SPACE_AFTER_QUOTED(string) context_format(string, "\\[%s\\] ") > + > +#ifdef PRINT_SECONTEXT_FULL > + > +#define SELINUX_FILECONTEXT(filename) CONTEXT_FORMAT_SPACE_BEFORE(get_file_context_full(filename)) > +#define SELINUX_PIDCONTEXT(pid) CONTEXT_FORMAT_SPACE_AFTER(get_pid_context_full(pid)) > +#define SELINUX_FILECONTEXT_QUOTED(filename) CONTEXT_FORMAT_SPACE_BEFORE_QUOTED(get_file_context_full(filename)) > +#define SELINUX_PIDCONTEXT_QUOTED(pid) CONTEXT_FORMAT_SPACE_AFTER_QUOTED(get_pid_context_full(pid)) > + > +#else > + > +#define SELINUX_FILECONTEXT(filename) CONTEXT_FORMAT_SPACE_BEFORE(get_file_context_short(filename)) > +#define SELINUX_PIDCONTEXT(pid) CONTEXT_FORMAT_SPACE_AFTER(get_pid_context_short(pid)) > +#define SELINUX_FILECONTEXT_QUOTED(filename) CONTEXT_FORMAT_SPACE_BEFORE_QUOTED(get_file_context_short(filename)) > +#define SELINUX_PIDCONTEXT_QUOTED(pid) CONTEXT_FORMAT_SPACE_AFTER_QUOTED(get_pid_context_short(pid)) Some of these lines are too long, please wrap. > + char *newcontext = xasprintf("%s:%s:%s:%s", split[0], split[1], newtype, split[3]); Likewise. -- ldv From rmetrich at redhat.com Thu Mar 18 11:31:18 2021 From: rmetrich at redhat.com (=?UTF-8?Q?Renaud_M=c3=a9trich?=) Date: Thu, 18 Mar 2021 12:31:18 +0100 Subject: Proposing SELinux support in strace In-Reply-To: <20210318024935.GA23192@altlinux.org> References: <20210315011000.GA3123@altlinux.org> <2a0ba13b-620c-0bf6-11c7-c123947f0050@redhat.com> <20210315203328.GA17962@altlinux.org> <007c7593-deb3-e39f-e63a-b2f541c308f7@redhat.com> <20210316105309.GA28115@altlinux.org> <20210317011559.GA4853@altlinux.org> <20210318024935.GA23192@altlinux.org> Message-ID: See line. Updated patch attached. On 3/18/21 3:49 AM, Dmitry V. Levin wrote: > diff --git a/doc/strace.1.in b/doc/strace.1.in >> index 05c32d902..e310e0877 100644 >> --- a/doc/strace.1.in >> +++ b/doc/strace.1.in >> @@ -53,6 +53,7 @@ strace \- trace system calls and signals >> .OM \-P path >> .OM \-p pid >> .OP \-\-seccomp\-bpf >> +.if '@USE_SELINUX_FALSE@'#' .OP \-\-secontext[=full] > [=full] should not be bold, consider changing the line to > .if '@USE_SELINUX_FALSE@'#' .OP \-\-secontext\fR[=\fIfull\fR] Actually "full" is a keyword here and not a variable, hence I think it's better to have it not underlined at all. [--secontext[=full]] > > I think this should go to the end of "Output format:" section rather > "Miscellaneous:". OK, moved the option in the man page also. >> @@ -46,6 +48,7 @@ check_e '-t and --absolute-timestamps cannot be provided simultaneously' -t --ti >> check_e '-t and --absolute-timestamps cannot be provided simultaneously' --absolute-timestamps -ttt -p $$ >> check_e '-t and --absolute-timestamps cannot be provided simultaneously' -t --timestamps=ns -t -p $$ >> check_e '-t and --absolute-timestamps cannot be provided simultaneously' --timestamps=ns -t --absolute-timestamps=unix -p $$ >> +[ -n "$compiled_with_secontext" ] && check_h "invalid --secontext argument: 'ss'" --secontext=ss > We prefer writing it this way: > > [ -z "$compiled_with_secontext" ] || > check_h "invalid --secontext argument: 'ss'" --secontext=ss OK, that's what I had written intially, then thought some people don't like that. -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-Implement-secontext-full-option-to-display-SELinux-c.patch Type: text/x-patch Size: 79838 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: OpenPGP_signature Type: application/pgp-signature Size: 840 bytes Desc: OpenPGP digital signature URL: From rmetrich at redhat.com Thu Mar 18 15:55:13 2021 From: rmetrich at redhat.com (=?UTF-8?Q?Renaud_M=c3=a9trich?=) Date: Thu, 18 Mar 2021 16:55:13 +0100 Subject: Proposing SELinux support in strace In-Reply-To: References: <20210315011000.GA3123@altlinux.org> <2a0ba13b-620c-0bf6-11c7-c123947f0050@redhat.com> <20210315203328.GA17962@altlinux.org> <007c7593-deb3-e39f-e63a-b2f541c308f7@redhat.com> <20210316105309.GA28115@altlinux.org> <20210317011559.GA4853@altlinux.org> <20210318024935.GA23192@altlinux.org> Message-ID: <3c311a75-f5ec-a8a6-5c0a-738f2f4ef724@redhat.com> Hello, I've just realized that the limitation on the mount namespace is a real blocker in real world: it appears that on systemd systems, all systemd services making use of PrivateTmp get their own namespace (due to having their own /var/tmp), which prevents the --secontext option from working for all files. I just experienced this with a customer strace ... I would hence like to add a new option (similar to "full", e.g. "nocheck") that would ignore the mount namespace check and resolve paths in the strace mount namespace. This will potentially return invalid context information, but is definitely better than returning nothing at all. This will at least enable to strace normal services just having PrivateTmp set: most paths, except stuff in /var/tmp will be correct. Would you agree with this or would you prefer a new PR to come with this? Sorry for the late heads up... Renaud. On 3/18/21 12:31 PM, Renaud M?trich wrote: > See line. Updated patch attached. > > On 3/18/21 3:49 AM, Dmitry V. Levin wrote: >> diff --git a/doc/strace.1.in b/doc/strace.1.in >>> index 05c32d902..e310e0877 100644 >>> --- a/doc/strace.1.in >>> +++ b/doc/strace.1.in >>> @@ -53,6 +53,7 @@ strace \- trace system calls and signals >>> ? .OM \-P path >>> ? .OM \-p pid >>> ? .OP \-\-seccomp\-bpf >>> +.if '@USE_SELINUX_FALSE@'#' .OP \-\-secontext[=full] >> [=full] should not be bold, consider changing the line to >> .if '@USE_SELINUX_FALSE@'#' .OP \-\-secontext\fR[=\fIfull\fR] > > Actually "full" is a keyword here and not a variable, hence I think > it's better to have it not underlined at all. > > [--secontext[=full]] > >> >> I think this should go to the end of "Output format:" section rather >> "Miscellaneous:". > OK, moved the option in the man page also. >>> @@ -46,6 +48,7 @@ check_e '-t and --absolute-timestamps cannot be >>> provided simultaneously' -t --ti >>> ? check_e '-t and --absolute-timestamps cannot be provided >>> simultaneously' --absolute-timestamps -ttt -p $$ >>> ? check_e '-t and --absolute-timestamps cannot be provided >>> simultaneously' -t --timestamps=ns -t -p $$ >>> ? check_e '-t and --absolute-timestamps cannot be provided >>> simultaneously' --timestamps=ns -t --absolute-timestamps=unix -p $$ >>> +[ -n "$compiled_with_secontext" ] && check_h "invalid --secontext >>> argument: 'ss'" --secontext=ss >> We prefer writing it this way: >> >> [ -z "$compiled_with_secontext" ] || >> ????check_h "invalid --secontext argument: 'ss'" --secontext=ss > OK, that's what I had written intially, then thought some people don't > like that. -------------- next part -------------- A non-text attachment was scrubbed... Name: OpenPGP_signature Type: application/pgp-signature Size: 840 bytes Desc: OpenPGP digital signature URL: From rmetrich at redhat.com Thu Mar 18 21:36:49 2021 From: rmetrich at redhat.com (=?UTF-8?Q?Renaud_M=c3=a9trich?=) Date: Thu, 18 Mar 2021 22:36:49 +0100 Subject: Proposing SELinux support in strace In-Reply-To: References: <20210315011000.GA3123@altlinux.org> <2a0ba13b-620c-0bf6-11c7-c123947f0050@redhat.com> <20210315203328.GA17962@altlinux.org> <007c7593-deb3-e39f-e63a-b2f541c308f7@redhat.com> <20210316105309.GA28115@altlinux.org> <20210317011559.GA4853@altlinux.org> <20210318024935.GA23192@altlinux.org> Message-ID: Attached is a small fix in the doc, I had forgotten to prefix the details for --secontext using "if USE_SELINUX_FALSE" statements. Sorry for that. On 3/18/21 12:31 PM, Renaud M?trich wrote: > See line. Updated patch attached. > > On 3/18/21 3:49 AM, Dmitry V. Levin wrote: >> diff --git a/doc/strace.1.in b/doc/strace.1.in >>> index 05c32d902..e310e0877 100644 >>> --- a/doc/strace.1.in >>> +++ b/doc/strace.1.in >>> @@ -53,6 +53,7 @@ strace \- trace system calls and signals >>> ? .OM \-P path >>> ? .OM \-p pid >>> ? .OP \-\-seccomp\-bpf >>> +.if '@USE_SELINUX_FALSE@'#' .OP \-\-secontext[=full] >> [=full] should not be bold, consider changing the line to >> .if '@USE_SELINUX_FALSE@'#' .OP \-\-secontext\fR[=\fIfull\fR] > > Actually "full" is a keyword here and not a variable, hence I think > it's better to have it not underlined at all. > > [--secontext[=full]] > >> >> I think this should go to the end of "Output format:" section rather >> "Miscellaneous:". > OK, moved the option in the man page also. >>> @@ -46,6 +48,7 @@ check_e '-t and --absolute-timestamps cannot be >>> provided simultaneously' -t --ti >>> ? check_e '-t and --absolute-timestamps cannot be provided >>> simultaneously' --absolute-timestamps -ttt -p $$ >>> ? check_e '-t and --absolute-timestamps cannot be provided >>> simultaneously' -t --timestamps=ns -t -p $$ >>> ? check_e '-t and --absolute-timestamps cannot be provided >>> simultaneously' --timestamps=ns -t --absolute-timestamps=unix -p $$ >>> +[ -n "$compiled_with_secontext" ] && check_h "invalid --secontext >>> argument: 'ss'" --secontext=ss >> We prefer writing it this way: >> >> [ -z "$compiled_with_secontext" ] || >> ????check_h "invalid --secontext argument: 'ss'" --secontext=ss > OK, that's what I had written intially, then thought some people don't > like that. -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-Fixed-missing-if-USE_SELINUX-in-manpage-for-detailed.patch Type: text/x-patch Size: 1911 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: OpenPGP_signature Type: application/pgp-signature Size: 840 bytes Desc: OpenPGP digital signature URL: From rmetrich at redhat.com Thu Mar 18 22:41:29 2021 From: rmetrich at redhat.com (=?UTF-8?Q?Renaud_M=c3=a9trich?=) Date: Thu, 18 Mar 2021 23:41:29 +0100 Subject: Proposing SELinux support in strace In-Reply-To: <3c311a75-f5ec-a8a6-5c0a-738f2f4ef724@redhat.com> References: <20210315011000.GA3123@altlinux.org> <2a0ba13b-620c-0bf6-11c7-c123947f0050@redhat.com> <20210315203328.GA17962@altlinux.org> <007c7593-deb3-e39f-e63a-b2f541c308f7@redhat.com> <20210316105309.GA28115@altlinux.org> <20210317011559.GA4853@altlinux.org> <20210318024935.GA23192@altlinux.org> <3c311a75-f5ec-a8a6-5c0a-738f2f4ef724@redhat.com> Message-ID: If you agree with merging this with the existing PR, attached is the proposed patch. It introduces a "nocheck" modifier to --secontext option (--secontext=nocheck or --secontext=full,nocheck). On 3/18/21 4:55 PM, Renaud M?trich wrote: > Hello, I've just realized that the limitation on the mount namespace > is a real blocker in real world: > > it appears that on systemd systems, all systemd services making use of > PrivateTmp get their own namespace (due to having their own /var/tmp), > which prevents the --secontext option from working for all files. > > I just experienced this with a customer strace ... > > I would hence like to add a new option (similar to "full", e.g. > "nocheck") that would ignore the mount namespace check and resolve > paths in the strace mount namespace. > > This will potentially return invalid context information, but is > definitely better than returning nothing at all. > > This will at least enable to strace normal services just having > PrivateTmp set: most paths, except stuff in /var/tmp will be correct. > > Would you agree with this or would you prefer a new PR to come with this? > > Sorry for the late heads up... > > Renaud. > > On 3/18/21 12:31 PM, Renaud M?trich wrote: >> See line. Updated patch attached. >> >> On 3/18/21 3:49 AM, Dmitry V. Levin wrote: >>> diff --git a/doc/strace.1.in b/doc/strace.1.in >>>> index 05c32d902..e310e0877 100644 >>>> --- a/doc/strace.1.in >>>> +++ b/doc/strace.1.in >>>> @@ -53,6 +53,7 @@ strace \- trace system calls and signals >>>> ? .OM \-P path >>>> ? .OM \-p pid >>>> ? .OP \-\-seccomp\-bpf >>>> +.if '@USE_SELINUX_FALSE@'#' .OP \-\-secontext[=full] >>> [=full] should not be bold, consider changing the line to >>> .if '@USE_SELINUX_FALSE@'#' .OP \-\-secontext\fR[=\fIfull\fR] >> >> Actually "full" is a keyword here and not a variable, hence I think >> it's better to have it not underlined at all. >> >> [--secontext[=full]] >> >>> >>> I think this should go to the end of "Output format:" section rather >>> "Miscellaneous:". >> OK, moved the option in the man page also. >>>> @@ -46,6 +48,7 @@ check_e '-t and --absolute-timestamps cannot be >>>> provided simultaneously' -t --ti >>>> ? check_e '-t and --absolute-timestamps cannot be provided >>>> simultaneously' --absolute-timestamps -ttt -p $$ >>>> ? check_e '-t and --absolute-timestamps cannot be provided >>>> simultaneously' -t --timestamps=ns -t -p $$ >>>> ? check_e '-t and --absolute-timestamps cannot be provided >>>> simultaneously' --timestamps=ns -t --absolute-timestamps=unix -p $$ >>>> +[ -n "$compiled_with_secontext" ] && check_h "invalid --secontext >>>> argument: 'ss'" --secontext=ss >>> We prefer writing it this way: >>> >>> [ -z "$compiled_with_secontext" ] || >>> ????check_h "invalid --secontext argument: 'ss'" --secontext=ss >> OK, that's what I had written intially, then thought some people >> don't like that. > -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-Implement-secontext-nocheck-modifier.patch Type: text/x-patch Size: 21326 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: OpenPGP_signature Type: application/pgp-signature Size: 840 bytes Desc: OpenPGP digital signature URL: From ldv at altlinux.org Thu Mar 18 23:18:35 2021 From: ldv at altlinux.org (Dmitry V. Levin) Date: Fri, 19 Mar 2021 02:18:35 +0300 Subject: Proposing SELinux support in strace In-Reply-To: <3c311a75-f5ec-a8a6-5c0a-738f2f4ef724@redhat.com> References: <2a0ba13b-620c-0bf6-11c7-c123947f0050@redhat.com> <20210315203328.GA17962@altlinux.org> <007c7593-deb3-e39f-e63a-b2f541c308f7@redhat.com> <20210316105309.GA28115@altlinux.org> <20210317011559.GA4853@altlinux.org> <20210318024935.GA23192@altlinux.org> <3c311a75-f5ec-a8a6-5c0a-738f2f4ef724@redhat.com> Message-ID: <20210318231835.GA4569@altlinux.org> On Thu, Mar 18, 2021 at 04:55:13PM +0100, Renaud M?trich wrote: > Hello, I've just realized that the limitation on the mount namespace is > a real blocker in real world: > > it appears that on systemd systems, all systemd services making use of > PrivateTmp get their own namespace (due to having their own /var/tmp), > which prevents the --secontext option from working for all files. The very minimal fix that's readily available is for printing selinux context associated with descriptors. Since it can be obtained right from procfs without falling back to path names, it should not be affected by any differences in mountns or rootfs between strace and its tracee. Could you try the following fix, please: diff --git a/doc/strace.1.in b/doc/strace.1.in index f63032b0f..e6ad7a9c0 100644 --- a/doc/strace.1.in +++ b/doc/strace.1.in @@ -1094,7 +1094,8 @@ strace's namespace, too. .if '@USE_SELINUX_FALSE@'#' is specified, print the complete context (user, .if '@USE_SELINUX_FALSE@'#' role, type and category) instead of just the type. .if '@USE_SELINUX_FALSE@'#' The current implementation has limitations, in -.if '@USE_SELINUX_FALSE@'#' particular, SELinux contexts cannot be printed when +.if '@USE_SELINUX_FALSE@'#' particular, SELinux contexts cannot be printed for +.if '@USE_SELINUX_FALSE@'#' file names when .if '@USE_SELINUX_FALSE@'#' .B strace .if '@USE_SELINUX_FALSE@'#' and the tracee belong to different mount namespaces. .SS Statistics diff --git a/src/selinux.c b/src/selinux.c index 62e8e89e3..0f1edfe28 100644 --- a/src/selinux.c +++ b/src/selinux.c @@ -69,6 +69,29 @@ selinux_getpidcon(struct tcb *tcp, char **result) return getcontext(getpidcon(proc_pid, &secontext), &secontext, result); } +/* + * Retrieves the SELinux context of the given pid and descriptor. + * Memory must be freed. + * Returns 0 on success, -1 on failure. + */ +int +selinux_getfdcon(pid_t pid, int fd, char **result) +{ + if (!selinux_context || pid <= 0 || fd < 0) + return -1; + + int proc_pid = 0; + translate_pid(NULL, pid, PT_TID, &proc_pid); + if (!proc_pid) + return -1; + + char linkpath[sizeof("/proc/%u/fd/%u") + 2 * sizeof(int)*3]; + xsprintf(linkpath, "/proc/%u/fd/%u", proc_pid, fd); + + char *secontext; + return getcontext(getfilecon(linkpath, &secontext), &secontext, result); +} + /* * Retrieves the SELinux context of the given path. * Memory must be freed. diff --git a/src/selinux.h b/src/selinux.h index ab39ea52e..68958f0cb 100644 --- a/src/selinux.h +++ b/src/selinux.h @@ -14,6 +14,7 @@ extern bool selinux_context; extern bool selinux_context_full; +int selinux_getfdcon(pid_t pid, int fd, char **context); int selinux_getpidcon(struct tcb *tcp, char **context); int selinux_getfilecon(struct tcb *tcp, const char *path, char **context); diff --git a/src/util.c b/src/util.c index 509b12f7f..b68129703 100644 --- a/src/util.c +++ b/src/util.c @@ -665,16 +665,16 @@ printfd_pid(struct tcb *tcp, pid_t pid, int fd) printed: tprints(">"); -#ifdef USE_SELINUX - char *context; - if (!selinux_getfilecon(tcp, path, &context)) { - tprintf(" [%s]", context); - free(context); - } -#endif } else { tprintf("%d", fd); } +#ifdef USE_SELINUX + char *context; + if (!selinux_getfdcon(pid, fd, &context)) { + tprintf(" [%s]", context); + free(context); + } +#endif } void -- ldv From ldv at altlinux.org Fri Mar 19 01:41:24 2021 From: ldv at altlinux.org (Dmitry V. Levin) Date: Fri, 19 Mar 2021 04:41:24 +0300 Subject: Proposing SELinux support in strace In-Reply-To: <20210318231835.GA4569@altlinux.org> References: <20210315203328.GA17962@altlinux.org> <007c7593-deb3-e39f-e63a-b2f541c308f7@redhat.com> <20210316105309.GA28115@altlinux.org> <20210317011559.GA4853@altlinux.org> <20210318024935.GA23192@altlinux.org> <3c311a75-f5ec-a8a6-5c0a-738f2f4ef724@redhat.com> <20210318231835.GA4569@altlinux.org> Message-ID: <20210319014124.GA5767@altlinux.org> On Fri, Mar 19, 2021 at 02:18:35AM +0300, Dmitry V. Levin wrote: > On Thu, Mar 18, 2021 at 04:55:13PM +0100, Renaud M?trich wrote: > > Hello, I've just realized that the limitation on the mount namespace is > > a real blocker in real world: > > > > it appears that on systemd systems, all systemd services making use of > > PrivateTmp get their own namespace (due to having their own /var/tmp), > > which prevents the --secontext option from working for all files. > > The very minimal fix that's readily available is for printing selinux > context associated with descriptors. Since it can be obtained right from > procfs without falling back to path names, it should not be affected by > any differences in mountns or rootfs between strace and its tracee. Assuming this works, let's see what could be done with file names: - if the filename starts with "/", we can construct a new name as /proc/pid/root/filename and getfilecon it; - otherwise, if last_dirfd == AT_FDCWD, we can construct a new name as /proc/pid/cwd/filename and getfilecon it; - otherwise, we can construct a new name as /proc/pid/fd/last_dirfd/filename and getfilecon it. Could you check whether this approach would work good enough, please? diff --git a/doc/strace.1.in b/doc/strace.1.in index e6ad7a9c0..15d8e2531 100644 --- a/doc/strace.1.in +++ b/doc/strace.1.in @@ -1093,11 +1093,6 @@ strace's namespace, too. .if '@USE_SELINUX_FALSE@'#' .B full .if '@USE_SELINUX_FALSE@'#' is specified, print the complete context (user, .if '@USE_SELINUX_FALSE@'#' role, type and category) instead of just the type. -.if '@USE_SELINUX_FALSE@'#' The current implementation has limitations, in -.if '@USE_SELINUX_FALSE@'#' particular, SELinux contexts cannot be printed for -.if '@USE_SELINUX_FALSE@'#' file names when -.if '@USE_SELINUX_FALSE@'#' .B strace -.if '@USE_SELINUX_FALSE@'#' and the tracee belong to different mount namespaces. .SS Statistics .TP 12 .B \-c diff --git a/src/selinux.c b/src/selinux.c index 0f1edfe28..b62d40324 100644 --- a/src/selinux.c +++ b/src/selinux.c @@ -103,52 +103,27 @@ selinux_getfilecon(struct tcb *tcp, const char *path, char **result) if (!selinux_context) return -1; - /* - * Current limitation: we cannot query the path if we are in different - * mount namespaces. - */ - if (get_mnt_ns(tcp) != get_our_mnt_ns()) + int proc_pid = 0; + translate_pid(NULL, tcp->pid, PT_TID, &proc_pid); + if (!proc_pid) return -1; - char *secontext; + int ret = -1; + char fname[PATH_MAX]; if (path[0] == '/') - return getcontext(getfilecon(path, &secontext), &secontext, result); - - char resolved[PATH_MAX + 1]; - - /* - * If we have a relative pathname and 'last_dirfd' == AT_FDCWD, we need - * to prepend by the CWD. - */ - if (tcp->last_dirfd == AT_FDCWD) { - int proc_pid = 0; - translate_pid(NULL, tcp->pid, PT_TID, &proc_pid); - if (!proc_pid) - return -1; - - char linkpath[sizeof("/proc/%u/cwd") + sizeof(int)*3]; - xsprintf(linkpath, "/proc/%u/cwd", proc_pid); - - ssize_t n = readlink(linkpath, resolved, sizeof(resolved) - 1); - /* - * NB: if buffer is too small, readlink doesn't fail, - * it returns truncated result. - */ - if (n == sizeof(resolved) - 1) - return -1; - resolved[n] = '\0'; - } else { - if (getfdpath_pid(tcp->pid, tcp->last_dirfd, - resolved, sizeof(resolved)) < 0) - return -1; - } - - if (resolved[0] != '/') + ret = snprintf(fname, sizeof(fname), "/proc/%u/root%s", + proc_pid, path); + else if (tcp->last_dirfd == AT_FDCWD) + ret = snprintf(fname, sizeof(fname), "/proc/%u/cwd/%s", + proc_pid, path); + else if (tcp->last_dirfd >= 0 ) + ret = snprintf(fname, sizeof(fname), "/proc/%u/fd/%u/%s", + proc_pid, tcp->last_dirfd, path); + + if ((unsigned int) ret >= sizeof(fname)) return -1; - char pathtoresolve[2 * PATH_MAX + 2]; - xsprintf(pathtoresolve, "%s/%s", resolved, path); - - return getcontext(getfilecon(pathtoresolve, &secontext), &secontext, result); + char *secontext; + return getcontext(getfilecon(fname, &secontext), &secontext, result); } diff --git a/tests/fchmod--secontext.c b/tests/fchmod--secontext.c index 13434544c..3b6681153 100644 --- a/tests/fchmod--secontext.c +++ b/tests/fchmod--secontext.c @@ -37,19 +37,20 @@ main(void) if (fname_realpath == NULL) perror_msg_and_fail("realpath"); + const char *fname_context = SELINUX_FILECONTEXT(fname); long rc = syscall(__NR_fchmod, fd, 0600); printf("%sfchmod(%d<%s>%s, 0600) = %s\n", SELINUX_MYCONTEXT(), - fd, fname_realpath, SELINUX_FILECONTEXT(fname), + fd, fname_realpath, fname_context, sprintrc(rc)); if (unlink(fname)) perror_msg_and_fail("unlink"); rc = syscall(__NR_fchmod, fd, 0600); - printf("%sfchmod(%d<%s (deleted)>, 0600) = %s\n", + printf("%sfchmod(%d<%s (deleted)>%s, 0600) = %s\n", SELINUX_MYCONTEXT(), - fd, fname_realpath, + fd, fname_realpath, fname_context, sprintrc(rc)); puts("+++ exited with 0 +++"); -- ldv From rmetrich at redhat.com Fri Mar 19 08:29:12 2021 From: rmetrich at redhat.com (=?UTF-8?Q?Renaud_M=c3=a9trich?=) Date: Fri, 19 Mar 2021 09:29:12 +0100 Subject: Proposing SELinux support in strace In-Reply-To: <20210319014124.GA5767@altlinux.org> References: <20210315203328.GA17962@altlinux.org> <007c7593-deb3-e39f-e63a-b2f541c308f7@redhat.com> <20210316105309.GA28115@altlinux.org> <20210317011559.GA4853@altlinux.org> <20210318024935.GA23192@altlinux.org> <3c311a75-f5ec-a8a6-5c0a-738f2f4ef724@redhat.com> <20210318231835.GA4569@altlinux.org> <20210319014124.GA5767@altlinux.org> Message-ID: <35ff989a-4a8e-429e-5e53-05ef52773b12@redhat.com> Shame on me, definitely, your idea just works fine and is robust! Tested on chroots, bind mounts and systemd-nspawns. We get even more contexts since Unix sockets are now displayed as well. I was concentrating on how I could rebuild the fs tree from mountinfo instead of just following symlinks in /proc as you proposed ... So what's next now? Since contexts always display now, there is no real need for dedicated *--secontext test suite, all this can be integrated into the standard test suite (we just need to add "%s" almost everywhere for tests that we want to re-run with "strace --secontext"). Shall I do this or just stick to the updated test suite? Renaud. On 3/19/21 2:41 AM, Dmitry V. Levin wrote: > On Fri, Mar 19, 2021 at 02:18:35AM +0300, Dmitry V. Levin wrote: >> On Thu, Mar 18, 2021 at 04:55:13PM +0100, Renaud M?trich wrote: >>> Hello, I've just realized that the limitation on the mount namespace is >>> a real blocker in real world: >>> >>> it appears that on systemd systems, all systemd services making use of >>> PrivateTmp get their own namespace (due to having their own /var/tmp), >>> which prevents the --secontext option from working for all files. >> The very minimal fix that's readily available is for printing selinux >> context associated with descriptors. Since it can be obtained right from >> procfs without falling back to path names, it should not be affected by >> any differences in mountns or rootfs between strace and its tracee. > Assuming this works, let's see what could be done with file names: > - if the filename starts with "/", we can construct a new name as > /proc/pid/root/filename and getfilecon it; > - otherwise, if last_dirfd == AT_FDCWD, we can construct a new name as > /proc/pid/cwd/filename and getfilecon it; > - otherwise, we can construct a new name as > /proc/pid/fd/last_dirfd/filename and getfilecon it. > > Could you check whether this approach would work good enough, please? > > diff --git a/doc/strace.1.in b/doc/strace.1.in > index e6ad7a9c0..15d8e2531 100644 > --- a/doc/strace.1.in > +++ b/doc/strace.1.in > @@ -1093,11 +1093,6 @@ strace's namespace, too. > .if '@USE_SELINUX_FALSE@'#' .B full > .if '@USE_SELINUX_FALSE@'#' is specified, print the complete context (user, > .if '@USE_SELINUX_FALSE@'#' role, type and category) instead of just the type. > -.if '@USE_SELINUX_FALSE@'#' The current implementation has limitations, in > -.if '@USE_SELINUX_FALSE@'#' particular, SELinux contexts cannot be printed for > -.if '@USE_SELINUX_FALSE@'#' file names when > -.if '@USE_SELINUX_FALSE@'#' .B strace > -.if '@USE_SELINUX_FALSE@'#' and the tracee belong to different mount namespaces. > .SS Statistics > .TP 12 > .B \-c > diff --git a/src/selinux.c b/src/selinux.c > index 0f1edfe28..b62d40324 100644 > --- a/src/selinux.c > +++ b/src/selinux.c > @@ -103,52 +103,27 @@ selinux_getfilecon(struct tcb *tcp, const char *path, char **result) > if (!selinux_context) > return -1; > > - /* > - * Current limitation: we cannot query the path if we are in different > - * mount namespaces. > - */ > - if (get_mnt_ns(tcp) != get_our_mnt_ns()) > + int proc_pid = 0; > + translate_pid(NULL, tcp->pid, PT_TID, &proc_pid); > + if (!proc_pid) > return -1; > > - char *secontext; > + int ret = -1; > + char fname[PATH_MAX]; > > if (path[0] == '/') > - return getcontext(getfilecon(path, &secontext), &secontext, result); > - > - char resolved[PATH_MAX + 1]; > - > - /* > - * If we have a relative pathname and 'last_dirfd' == AT_FDCWD, we need > - * to prepend by the CWD. > - */ > - if (tcp->last_dirfd == AT_FDCWD) { > - int proc_pid = 0; > - translate_pid(NULL, tcp->pid, PT_TID, &proc_pid); > - if (!proc_pid) > - return -1; > - > - char linkpath[sizeof("/proc/%u/cwd") + sizeof(int)*3]; > - xsprintf(linkpath, "/proc/%u/cwd", proc_pid); > - > - ssize_t n = readlink(linkpath, resolved, sizeof(resolved) - 1); > - /* > - * NB: if buffer is too small, readlink doesn't fail, > - * it returns truncated result. > - */ > - if (n == sizeof(resolved) - 1) > - return -1; > - resolved[n] = '\0'; > - } else { > - if (getfdpath_pid(tcp->pid, tcp->last_dirfd, > - resolved, sizeof(resolved)) < 0) > - return -1; > - } > - > - if (resolved[0] != '/') > + ret = snprintf(fname, sizeof(fname), "/proc/%u/root%s", > + proc_pid, path); > + else if (tcp->last_dirfd == AT_FDCWD) > + ret = snprintf(fname, sizeof(fname), "/proc/%u/cwd/%s", > + proc_pid, path); > + else if (tcp->last_dirfd >= 0 ) > + ret = snprintf(fname, sizeof(fname), "/proc/%u/fd/%u/%s", > + proc_pid, tcp->last_dirfd, path); > + > + if ((unsigned int) ret >= sizeof(fname)) > return -1; > > - char pathtoresolve[2 * PATH_MAX + 2]; > - xsprintf(pathtoresolve, "%s/%s", resolved, path); > - > - return getcontext(getfilecon(pathtoresolve, &secontext), &secontext, result); > + char *secontext; > + return getcontext(getfilecon(fname, &secontext), &secontext, result); > } > diff --git a/tests/fchmod--secontext.c b/tests/fchmod--secontext.c > index 13434544c..3b6681153 100644 > --- a/tests/fchmod--secontext.c > +++ b/tests/fchmod--secontext.c > @@ -37,19 +37,20 @@ main(void) > if (fname_realpath == NULL) > perror_msg_and_fail("realpath"); > > + const char *fname_context = SELINUX_FILECONTEXT(fname); > long rc = syscall(__NR_fchmod, fd, 0600); > printf("%sfchmod(%d<%s>%s, 0600) = %s\n", > SELINUX_MYCONTEXT(), > - fd, fname_realpath, SELINUX_FILECONTEXT(fname), > + fd, fname_realpath, fname_context, > sprintrc(rc)); > > if (unlink(fname)) > perror_msg_and_fail("unlink"); > > rc = syscall(__NR_fchmod, fd, 0600); > - printf("%sfchmod(%d<%s (deleted)>, 0600) = %s\n", > + printf("%sfchmod(%d<%s (deleted)>%s, 0600) = %s\n", > SELINUX_MYCONTEXT(), > - fd, fname_realpath, > + fd, fname_realpath, fname_context, > sprintrc(rc)); > > puts("+++ exited with 0 +++"); > -------------- next part -------------- A non-text attachment was scrubbed... Name: OpenPGP_signature Type: application/pgp-signature Size: 840 bytes Desc: OpenPGP digital signature URL: From ldv at altlinux.org Fri Mar 19 11:51:25 2021 From: ldv at altlinux.org (Dmitry V. Levin) Date: Fri, 19 Mar 2021 14:51:25 +0300 Subject: Proposing SELinux support in strace In-Reply-To: <35ff989a-4a8e-429e-5e53-05ef52773b12@redhat.com> References: <20210316105309.GA28115@altlinux.org> <20210317011559.GA4853@altlinux.org> <20210318024935.GA23192@altlinux.org> <3c311a75-f5ec-a8a6-5c0a-738f2f4ef724@redhat.com> <20210318231835.GA4569@altlinux.org> <20210319014124.GA5767@altlinux.org> <35ff989a-4a8e-429e-5e53-05ef52773b12@redhat.com> Message-ID: <20210319115125.GA12901@altlinux.org> On Fri, Mar 19, 2021 at 09:29:12AM +0100, Renaud M?trich wrote: [...] > So what's next now? Since contexts always display now, there is no real > need for dedicated *--secontext test suite, all this can be integrated > into the standard test suite (we just need to add "%s" almost everywhere > for tests that we want to re-run with "strace --secontext"). > > Shall I do this or just stick to the updated test suite? The standard test suite is often quite limited, for example, it doesn't test for the case when the cwd of strace differs from the cwd of its tracee, which is especially relevant when relative paths are processed with --secontext. If you could extend some of traditional tests to cover this case and make --secontext tests just use them, it would be indeed a good addition to the test suite. -- ldv From rmetrich at redhat.com Fri Mar 19 14:58:01 2021 From: rmetrich at redhat.com (=?UTF-8?Q?Renaud_M=c3=a9trich?=) Date: Fri, 19 Mar 2021 15:58:01 +0100 Subject: Proposing SELinux support in strace In-Reply-To: <20210319115125.GA12901@altlinux.org> References: <20210316105309.GA28115@altlinux.org> <20210317011559.GA4853@altlinux.org> <20210318024935.GA23192@altlinux.org> <3c311a75-f5ec-a8a6-5c0a-738f2f4ef724@redhat.com> <20210318231835.GA4569@altlinux.org> <20210319014124.GA5767@altlinux.org> <35ff989a-4a8e-429e-5e53-05ef52773b12@redhat.com> <20210319115125.GA12901@altlinux.org> Message-ID: Sure I will enhance the regular unit tests and get rid off the --secontext ones. On 3/19/21 12:51 PM, Dmitry V. Levin wrote: > On Fri, Mar 19, 2021 at 09:29:12AM +0100, Renaud M?trich wrote: > [...] >> So what's next now? Since contexts always display now, there is no real >> need for dedicated *--secontext test suite, all this can be integrated >> into the standard test suite (we just need to add "%s" almost everywhere >> for tests that we want to re-run with "strace --secontext"). >> >> Shall I do this or just stick to the updated test suite? > The standard test suite is often quite limited, for example, it doesn't > test for the case when the cwd of strace differs from the cwd of its > tracee, which is especially relevant when relative paths are processed > with --secontext. If you could extend some of traditional tests to cover > this case and make --secontext tests just use them, it would be indeed > a good addition to the test suite. > > -------------- next part -------------- A non-text attachment was scrubbed... Name: OpenPGP_signature Type: application/pgp-signature Size: 840 bytes Desc: OpenPGP digital signature URL: From 3563deb6753 at gmail.com Sun Mar 21 05:11:44 2021 From: 3563deb6753 at gmail.com (deborah brouwer) Date: Sat, 20 Mar 2021 22:11:44 -0700 Subject: [GSOC] Building strace mpers 32 Message-ID: <20210321051143.GA11550@djbComp> Hi! My name is Deborah and I'm studying computer science at Thompson Rivers University in British Columbia, Canada. I'm interested in GSOC. Can you please help me build strace with mpers enabled? After cloning the repository and running ./bootstrap and ./configure, make gives the error: make echo 5.11.0.172.97bbe > .version-t && mv .version-t .version make all-recursive make[1]: Entering directory '~/strace' Making all in bundled make[2]: Entering directory '~/strace/bundled' make[2]: Nothing to be done for 'all'. make[2]: Leaving directory '~/strace/bundled' Making all in src make[2]: Entering directory '~/strace/src' ... for f in block.c ...; do \ D="" \ READELF="readelf" \ CC="gcc" \ CFLAGS="-DHAVE_CONFIG_H -I./linux/x86_64 -I./linux/x86_64 -I./linux/generic -I./linux/generic -I. -I. -I../bundled/linux/arch/x86/include/uapi -I../bundled/linux/include/uapi -DIN_STRACE=1 -I./bundled/linux/arch/x86/include/uapi -I./bundled/linux/include/uapi -DMPERS_IS_m32" \ CPP="gcc -E" \ CPPFLAGS="-DHAVE_CONFIG_H -I./linux/x86_64 -I./linux/x86_64 -I./linux/generic -I./linux/generic -I. -I. -I../bundled/linux/arch/x86/include/uapi -I../bundled/linux/include/uapi -DIN_STRACE=1 -I./bundled/linux/arch/x86/include/uapi -I./bundled/linux/include/uapi -DIN_MPERS -DMPERS_IS_m32" \ ./mpers.sh m32 "-m32" $f || exit; \ done In file included from /usr/include/bits/errno.h:26:0, from /usr/include/errno.h:28, from ./defs.h:32, from mpers-m32/struct_blk_user_trace_setup.c:10: /usr/include/linux/errno.h:1:10: fatal error: asm/errno.h: No such file or directory #include ^~~~~~~~~~~~~ compilation terminated. Makefile:8785: recipe for target 'mpers-m32.stamp' failed Unsuccessfully I tried to fix the error by manually creating a new directory "~/strace/src/linux/x86_64/asm" and adding errno.h from my own "/usr/include/asm-generic". But this led to a chain reaction of additional make errors and I had to add additional headers to the newly created directory. Finally, make complained that I was missing stat.h, but when I added this header I got an additional errors about the redefinition of 'struct stat'. In strace/scr/linux/x86-64/asm_stat.h there is a comment that /* * This is a replacement for x32 which * appears to be wrong in older kernel headers. */ So, I think I have taken the wrong approach. Backing up, if I configure without mpers using ./configure --enable-mpers=no then I am able to build and install strace without any problems. However, I assume since enabling mpers is the default, this is something I need to fix. I have looked at the archives of the mailing list and haven't been able to find the solution. Can you please point me in the right direction to build strace with mpers enabled? From ldv at altlinux.org Sun Mar 21 10:43:32 2021 From: ldv at altlinux.org (Dmitry V. Levin) Date: Sun, 21 Mar 2021 13:43:32 +0300 Subject: [GSOC] Building strace mpers 32 In-Reply-To: <20210321051143.GA11550@djbComp> References: <20210321051143.GA11550@djbComp> Message-ID: <20210321104332.GA12051@altlinux.org> Hi, On Sat, Mar 20, 2021 at 10:11:44PM -0700, deborah brouwer wrote: > Hi! > My name is Deborah and I'm studying computer science at Thompson Rivers University in British Columbia, Canada. I'm interested in GSOC. > > Can you please help me build strace with mpers enabled? After cloning the repository and running ./bootstrap and ./configure, make gives the error: > > make > echo 5.11.0.172.97bbe > .version-t && mv .version-t .version > make all-recursive > make[1]: Entering directory '~/strace' > Making all in bundled > make[2]: Entering directory '~/strace/bundled' > make[2]: Nothing to be done for 'all'. > make[2]: Leaving directory '~/strace/bundled' > Making all in src > make[2]: Entering directory '~/strace/src' > ... > for f in block.c ...; do \ > D="" \ > READELF="readelf" \ > CC="gcc" \ > CFLAGS="-DHAVE_CONFIG_H -I./linux/x86_64 -I./linux/x86_64 -I./linux/generic -I./linux/generic -I. -I. -I../bundled/linux/arch/x86/include/uapi -I../bundled/linux/include/uapi -DIN_STRACE=1 -I./bundled/linux/arch/x86/include/uapi -I./bundled/linux/include/uapi -DMPERS_IS_m32" \ > CPP="gcc -E" \ > CPPFLAGS="-DHAVE_CONFIG_H -I./linux/x86_64 -I./linux/x86_64 -I./linux/generic -I./linux/generic -I. -I. -I../bundled/linux/arch/x86/include/uapi -I../bundled/linux/include/uapi -DIN_STRACE=1 -I./bundled/linux/arch/x86/include/uapi -I./bundled/linux/include/uapi -DIN_MPERS -DMPERS_IS_m32" \ > ./mpers.sh m32 "-m32" $f || exit; \ > done > In file included from /usr/include/bits/errno.h:26:0, > from /usr/include/errno.h:28, > from ./defs.h:32, > from mpers-m32/struct_blk_user_trace_setup.c:10: > /usr/include/linux/errno.h:1:10: fatal error: asm/errno.h: No such file or directory > #include > ^~~~~~~~~~~~~ > compilation terminated. This is odd. Does /usr/include/asm/errno.h exist in your system? -- ldv From 3563deb6753 at gmail.com Sun Mar 21 16:29:54 2021 From: 3563deb6753 at gmail.com (deborah brouwer) Date: Sun, 21 Mar 2021 09:29:54 -0700 Subject: [GSOC] Building strace mpers 32 In-Reply-To: <20210321104332.GA12051@altlinux.org> References: <20210321051143.GA11550@djbComp> <20210321104332.GA12051@altlinux.org> Message-ID: <20210321162953.GA3559@djbComp> On Sun, Mar 21, 2021 at 01:43:32PM +0300, Dmitry V. Levin wrote: > Hi, > > On Sat, Mar 20, 2021 at 10:11:44PM -0700, deborah brouwer wrote: > > Hi! > > My name is Deborah and I'm studying computer science at Thompson Rivers University in British Columbia, Canada. I'm interested in GSOC. > > > > Can you please help me build strace with mpers enabled? After cloning the repository and running ./bootstrap and ./configure, make gives the error: > > > > make > > echo 5.11.0.172.97bbe > .version-t && mv .version-t .version > > make all-recursive > > make[1]: Entering directory '~/strace' > > Making all in bundled > > make[2]: Entering directory '~/strace/bundled' > > make[2]: Nothing to be done for 'all'. > > make[2]: Leaving directory '~/strace/bundled' > > Making all in src > > make[2]: Entering directory '~/strace/src' > > ... > > for f in block.c ...; do \ > > D="" \ > > READELF="readelf" \ > > CC="gcc" \ > > CFLAGS="-DHAVE_CONFIG_H -I./linux/x86_64 -I./linux/x86_64 -I./linux/generic -I./linux/generic -I. -I. -I../bundled/linux/arch/x86/include/uapi -I../bundled/linux/include/uapi -DIN_STRACE=1 -I./bundled/linux/arch/x86/include/uapi -I./bundled/linux/include/uapi -DMPERS_IS_m32" \ > > CPP="gcc -E" \ > > CPPFLAGS="-DHAVE_CONFIG_H -I./linux/x86_64 -I./linux/x86_64 -I./linux/generic -I./linux/generic -I. -I. -I../bundled/linux/arch/x86/include/uapi -I../bundled/linux/include/uapi -DIN_STRACE=1 -I./bundled/linux/arch/x86/include/uapi -I./bundled/linux/include/uapi -DIN_MPERS -DMPERS_IS_m32" \ > > ./mpers.sh m32 "-m32" $f || exit; \ > > done > > In file included from /usr/include/bits/errno.h:26:0, > > from /usr/include/errno.h:28, > > from ./defs.h:32, > > from mpers-m32/struct_blk_user_trace_setup.c:10: > > /usr/include/linux/errno.h:1:10: fatal error: asm/errno.h: No such file or directory > > #include > > ^~~~~~~~~~~~~ > > compilation terminated. > > This is odd. Does /usr/include/asm/errno.h exist in your system? > No, my system does not have a /usr/include/asm/ directory, but I did try to create one and put errno.h in it from my /usr/include/asm-generic directory. It led to the same problem. > -- > ldv > -- > Strace-devel mailing list > Strace-devel at lists.strace.io > https://lists.strace.io/mailman/listinfo/strace-devel From ldv at altlinux.org Sun Mar 21 23:51:50 2021 From: ldv at altlinux.org (Dmitry V. Levin) Date: Mon, 22 Mar 2021 02:51:50 +0300 Subject: [GSOC] Building strace mpers 32 In-Reply-To: <20210321162953.GA3559@djbComp> References: <20210321051143.GA11550@djbComp> <20210321104332.GA12051@altlinux.org> <20210321162953.GA3559@djbComp> Message-ID: <20210321235149.GA19941@altlinux.org> On Sun, Mar 21, 2021 at 09:29:54AM -0700, deborah brouwer wrote: > On Sun, Mar 21, 2021 at 01:43:32PM +0300, Dmitry V. Levin wrote: > > Hi, > > > > On Sat, Mar 20, 2021 at 10:11:44PM -0700, deborah brouwer wrote: > > > Hi! > > > My name is Deborah and I'm studying computer science at Thompson Rivers University in British Columbia, Canada. I'm interested in GSOC. > > > > > > Can you please help me build strace with mpers enabled? After cloning the repository and running ./bootstrap and ./configure, make gives the error: > > > > > > make > > > echo 5.11.0.172.97bbe > .version-t && mv .version-t .version > > > make all-recursive > > > make[1]: Entering directory '~/strace' > > > Making all in bundled > > > make[2]: Entering directory '~/strace/bundled' > > > make[2]: Nothing to be done for 'all'. > > > make[2]: Leaving directory '~/strace/bundled' > > > Making all in src > > > make[2]: Entering directory '~/strace/src' > > > ... > > > for f in block.c ...; do \ > > > D="" \ > > > READELF="readelf" \ > > > CC="gcc" \ > > > CFLAGS="-DHAVE_CONFIG_H -I./linux/x86_64 -I./linux/x86_64 -I./linux/generic -I./linux/generic -I. -I. -I../bundled/linux/arch/x86/include/uapi -I../bundled/linux/include/uapi -DIN_STRACE=1 -I./bundled/linux/arch/x86/include/uapi -I./bundled/linux/include/uapi -DMPERS_IS_m32" \ > > > CPP="gcc -E" \ > > > CPPFLAGS="-DHAVE_CONFIG_H -I./linux/x86_64 -I./linux/x86_64 -I./linux/generic -I./linux/generic -I. -I. -I../bundled/linux/arch/x86/include/uapi -I../bundled/linux/include/uapi -DIN_STRACE=1 -I./bundled/linux/arch/x86/include/uapi -I./bundled/linux/include/uapi -DIN_MPERS -DMPERS_IS_m32" \ > > > ./mpers.sh m32 "-m32" $f || exit; \ > > > done > > > In file included from /usr/include/bits/errno.h:26:0, > > > from /usr/include/errno.h:28, > > > from ./defs.h:32, > > > from mpers-m32/struct_blk_user_trace_setup.c:10: > > > /usr/include/linux/errno.h:1:10: fatal error: asm/errno.h: No such file or directory > > > #include > > > ^~~~~~~~~~~~~ > > > compilation terminated. > > > > This is odd. Does /usr/include/asm/errno.h exist in your system? > > > No, my system does not have a /usr/include/asm/ directory, but I did try > to create one and put errno.h in it from my /usr/include/asm-generic > directory. It led to the same problem. It's very unusual for an operating system to provide system header /usr/include/linux/errno.h that doesn't compile because it uses /usr/include/asm/errno.h that doesn't exist. Since your operating system is glibc-based, it most likely consists of packages, and some package that makes /usr/include/linux/errno.h usable seems to be missing. Anyway, I wonder how did you manage to build strace without a usable . Could it be that your system's is not /usr/include/linux/errno.h? -- ldv From 3563deb6753 at gmail.com Mon Mar 22 03:46:10 2021 From: 3563deb6753 at gmail.com (deborah brouwer) Date: Sun, 21 Mar 2021 20:46:10 -0700 Subject: [GSOC] Building strace mpers 32 In-Reply-To: <20210321235149.GA19941@altlinux.org> References: <20210321051143.GA11550@djbComp> <20210321104332.GA12051@altlinux.org> <20210321162953.GA3559@djbComp> <20210321235149.GA19941@altlinux.org> Message-ID: <20210322034609.GA14825@djbComp> On Mon, Mar 22, 2021 at 02:51:50AM +0300, Dmitry V. Levin wrote: > On Sun, Mar 21, 2021 at 09:29:54AM -0700, deborah brouwer wrote: > > On Sun, Mar 21, 2021 at 01:43:32PM +0300, Dmitry V. Levin wrote: > > > Hi, > > > > > > On Sat, Mar 20, 2021 at 10:11:44PM -0700, deborah brouwer wrote: > > > > Hi! > > > > My name is Deborah and I'm studying computer science at Thompson Rivers University in British Columbia, Canada. I'm interested in GSOC. > > > > > > > > Can you please help me build strace with mpers enabled? After cloning the repository and running ./bootstrap and ./configure, make gives the error: > > > > > > > > make > > > > echo 5.11.0.172.97bbe > .version-t && mv .version-t .version > > > > make all-recursive > > > > make[1]: Entering directory '~/strace' > > > > Making all in bundled > > > > make[2]: Entering directory '~/strace/bundled' > > > > make[2]: Nothing to be done for 'all'. > > > > make[2]: Leaving directory '~/strace/bundled' > > > > Making all in src > > > > make[2]: Entering directory '~/strace/src' > > > > ... > > > > for f in block.c ...; do \ > > > > D="" \ > > > > READELF="readelf" \ > > > > CC="gcc" \ > > > > CFLAGS="-DHAVE_CONFIG_H -I./linux/x86_64 -I./linux/x86_64 -I./linux/generic -I./linux/generic -I. -I. -I../bundled/linux/arch/x86/include/uapi -I../bundled/linux/include/uapi -DIN_STRACE=1 -I./bundled/linux/arch/x86/include/uapi -I./bundled/linux/include/uapi -DMPERS_IS_m32" \ > > > > CPP="gcc -E" \ > > > > CPPFLAGS="-DHAVE_CONFIG_H -I./linux/x86_64 -I./linux/x86_64 -I./linux/generic -I./linux/generic -I. -I. -I../bundled/linux/arch/x86/include/uapi -I../bundled/linux/include/uapi -DIN_STRACE=1 -I./bundled/linux/arch/x86/include/uapi -I./bundled/linux/include/uapi -DIN_MPERS -DMPERS_IS_m32" \ > > > > ./mpers.sh m32 "-m32" $f || exit; \ > > > > done > > > > In file included from /usr/include/bits/errno.h:26:0, > > > > from /usr/include/errno.h:28, > > > > from ./defs.h:32, > > > > from mpers-m32/struct_blk_user_trace_setup.c:10: > > > > /usr/include/linux/errno.h:1:10: fatal error: asm/errno.h: No such file or directory > > > > #include > > > > ^~~~~~~~~~~~~ > > > > compilation terminated. > > > > > > This is odd. Does /usr/include/asm/errno.h exist in your system? > > > > > No, my system does not have a /usr/include/asm/ directory, but I did try > > to create one and put errno.h in it from my /usr/include/asm-generic > > directory. It led to the same problem. > > It's very unusual for an operating system to provide system header > /usr/include/linux/errno.h that doesn't compile because it uses > /usr/include/asm/errno.h that doesn't exist. > > Since your operating system is glibc-based, it most likely consists of > packages, and some package that makes /usr/include/linux/errno.h usable > seems to be missing. Thank you, this was the problem. I am using Ubuntu bionic (18.04LTS) and I was missing the package gcc-multilib. > > Anyway, I wonder how did you manage to build strace without a usable > . Could it be that your system's is not > /usr/include/linux/errno.h? > I did check the include path with gcc -v and it seemed to be as expected. I am not sure how that was working beforehand. But the problem is solved now. > > -- > ldv > -- > Strace-devel mailing list > Strace-devel at lists.strace.io > https://lists.strace.io/mailman/listinfo/strace-devel From srikavinramkumar at gmail.com Tue Mar 23 23:39:45 2021 From: srikavinramkumar at gmail.com (Srikavin Ramkumar) Date: Tue, 23 Mar 2021 19:39:45 -0400 Subject: [PATCH] tests: improve test coverage of prctl syscall decoder Message-ID: <20210323233940.23073-1-srikavinramkumar@gmail.com> * tests/.gitignore: Add new test binaries. * tests/Makefile.am: Add new tests. * tests/pure_executables.list: Likewise. * tests/prctl-cap-ambient.c: New file. * tests/prctl-cap-ambient.test: Likewise. * tests/prctl-capbset.c: Likewise. * tests/prctl-capbset.test: Likewise. * tests/prctl-fp-mode.c: Likewise. * tests/prctl-fp-mode.test: Likewise. * tests/prctl-mce-kill.c: Likewise. * tests/prctl-mce-kill.test: Likewise. * tests/prctl-sve.c: Likewise. * tests/prctl-sve.test: Likewise. * tests/prctl-unalign.c: Likewise. * tests/prctl-unalign.test: Likewise. --- This is part of my GSoC microproject. I plan to add a few more tests, but I wanted to make sure that I'm on the right track with these tests. These tests pass the CI, and the coverage results can be found here [1]. [1]: https://codecov.io/gh/srikavin/strace/src/prctl-tests/src/prctl.c tests/.gitignore | 6 +++ tests/Makefile.am | 7 +++ tests/prctl-cap-ambient.c | 78 +++++++++++++++++++++++++++++ tests/prctl-cap-ambient.test | 16 ++++++ tests/prctl-capbset.c | 48 ++++++++++++++++++ tests/prctl-capbset.test | 16 ++++++ tests/prctl-fp-mode.c | 96 ++++++++++++++++++++++++++++++++++++ tests/prctl-fp-mode.test | 33 +++++++++++++ tests/prctl-mce-kill.c | 59 ++++++++++++++++++++++ tests/prctl-mce-kill.test | 16 ++++++ tests/prctl-sve.c | 53 ++++++++++++++++++++ tests/prctl-sve.test | 16 ++++++ tests/prctl-unalign.c | 48 ++++++++++++++++++ tests/prctl-unalign.test | 16 ++++++ tests/pure_executables.list | 5 ++ 15 files changed, 513 insertions(+) create mode 100644 tests/prctl-cap-ambient.c create mode 100755 tests/prctl-cap-ambient.test create mode 100644 tests/prctl-capbset.c create mode 100755 tests/prctl-capbset.test create mode 100644 tests/prctl-fp-mode.c create mode 100755 tests/prctl-fp-mode.test create mode 100644 tests/prctl-mce-kill.c create mode 100755 tests/prctl-mce-kill.test create mode 100644 tests/prctl-sve.c create mode 100755 tests/prctl-sve.test create mode 100644 tests/prctl-unalign.c create mode 100755 tests/prctl-unalign.test diff --git a/tests/.gitignore b/tests/.gitignore index a2f3419b..74eca446 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -594,7 +594,11 @@ ppoll ppoll-P ppoll-v prctl-arg2-intptr +prctl-cap-ambient +prctl-capbset prctl-dumpable +prctl-fp-mode +prctl-mce-kill prctl-name prctl-no-args prctl-pdeathsig @@ -602,8 +606,10 @@ prctl-seccomp-filter-v prctl-seccomp-strict prctl-securebits prctl-spec-inject +prctl-sve prctl-tid_address prctl-tsc +prctl-unalign pread64-pwrite64 preadv preadv-pwritev diff --git a/tests/Makefile.am b/tests/Makefile.am index b8efce82..27961a39 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -226,6 +226,7 @@ check_PROGRAMS = $(PURE_EXECUTABLES) \ ppoll-P \ ppoll-v \ prlimit64--pidns-translation \ + prctl-fp-mode \ prctl-seccomp-filter-v \ prctl-seccomp-strict \ prctl-spec-inject \ @@ -409,7 +410,11 @@ DECODER_TESTS = \ poll-P.test \ poll.test \ prctl-arg2-intptr.test \ + prctl-capbset.test \ + prctl-cap-ambient.test \ prctl-dumpable.test \ + prctl-fp-mode.test \ + prctl-mce-kill.test \ prctl-name.test \ prctl-no-args.test \ prctl-pdeathsig.test \ @@ -417,8 +422,10 @@ DECODER_TESTS = \ prctl-seccomp-strict.test \ prctl-securebits.test \ prctl-spec-inject.test \ + prctl-sve.test \ prctl-tid_address.test \ prctl-tsc.test \ + prctl-unalign.test \ qual_fault-exit_group.test \ quotactl-success-v.test \ quotactl-success.test \ diff --git a/tests/prctl-cap-ambient.c b/tests/prctl-cap-ambient.c new file mode 100644 index 00000000..4c2b15f3 --- /dev/null +++ b/tests/prctl-cap-ambient.c @@ -0,0 +1,78 @@ +/* + * Check decoding of prctl PR_CAP_AMBIENT operations. + * + * Copyright (c) 2021 The strace developers. + * All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "tests.h" +#include "scno.h" +#include +#include +#include +#include + +int +main(void) +{ + long rc; + + rc = syscall(__NR_prctl, PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, + CAP_NET_RAW, 0, 0); + printf("prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, CAP_NET_RAW, 0, 0) = %s\n", + sprintrc(rc)); + + rc = syscall(__NR_prctl, PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, + CAP_AUDIT_CONTROL, 0, 0); + printf("prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, CAP_AUDIT_CONTROL, 0, 0) = %s\n", + sprintrc(rc)); + + rc = syscall(__NR_prctl, PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, 0xff, 0, 0); + printf("prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, 0xff /* CAP_??? */, 0, 0) = %s\n", + sprintrc(rc)); + + rc = syscall(__NR_prctl, PR_CAP_AMBIENT, PR_CAP_AMBIENT_LOWER, + CAP_NET_RAW, 0, 0); + printf("prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_LOWER, CAP_NET_RAW, 0, 0) = %s\n", + sprintrc(rc)); + + rc = syscall(__NR_prctl, PR_CAP_AMBIENT, PR_CAP_AMBIENT_LOWER, + CAP_KILL, 0, 0); + printf("prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_LOWER, CAP_KILL, 0, 0) = %s\n", + sprintrc(rc)); + + rc = syscall(__NR_prctl, PR_CAP_AMBIENT, PR_CAP_AMBIENT_LOWER, 0xff, 0, 0); + printf("prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_LOWER, 0xff /* CAP_??? */, 0, 0) = %s\n", + sprintrc(rc)); + + rc = syscall(__NR_prctl, PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, + CAP_NET_RAW, 0, 0); + printf("prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_NET_RAW, 0, 0) = %s\n", + sprintrc(rc)); + + rc = syscall(__NR_prctl, PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, + CAP_AUDIT_CONTROL, 0, 0); + printf("prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_AUDIT_CONTROL, 0, 0) = %s\n", + sprintrc(rc)); + + rc = syscall(__NR_prctl, PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, 0xff, 0, 0); + printf("prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, 0xff /* CAP_??? */, 0, 0) = %s\n", + sprintrc(rc)); + + rc = syscall(__NR_prctl, PR_CAP_AMBIENT, PR_CAP_AMBIENT_CLEAR_ALL, 0, 0, 0); + printf("prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_CLEAR_ALL, 0, 0, 0) = %s\n", + sprintrc(rc)); + + rc = syscall(__NR_prctl, PR_CAP_AMBIENT, 0xff, 0xaaaa, 0, 0); + printf("prctl(PR_CAP_AMBIENT, 0xff /* PR_CAP_AMBIENT_??? */, 0xaaaa, 0, 0) = %s\n", + sprintrc(rc)); + + rc = syscall(__NR_prctl, PR_CAP_AMBIENT, 0xff, 0xaaaa, 0xbbbb, 0xcccc); + printf("prctl(PR_CAP_AMBIENT, 0xff /* PR_CAP_AMBIENT_??? */, 0xaaaa, 0xbbbb, 0xcccc) = %s\n", + sprintrc(rc)); + + puts("+++ exited with 0 +++"); + return 0; +} diff --git a/tests/prctl-cap-ambient.test b/tests/prctl-cap-ambient.test new file mode 100755 index 00000000..c2955de6 --- /dev/null +++ b/tests/prctl-cap-ambient.test @@ -0,0 +1,16 @@ +#!/bin/sh +# +# Check decoding of prctl PR_CAP_AMBIENT operations. +# +# Copyright (c) 2021 The strace developers. +# All rights reserved. +# +# SPDX-License-Identifier: GPL-2.0-or-later + +. "${srcdir=.}/init.sh" + +check_prog grep +run_prog > /dev/null +run_strace -a21 -eprctl $args > "$EXP" +grep -v '^prctl(PR_[^C][^A][^P]_[^A][^M]' < "$LOG" > "$OUT" +match_diff "$OUT" "$EXP" diff --git a/tests/prctl-capbset.c b/tests/prctl-capbset.c new file mode 100644 index 00000000..8ca62c8b --- /dev/null +++ b/tests/prctl-capbset.c @@ -0,0 +1,48 @@ +/* + * Check decoding of prctl PR_CAPBSET_READ/PR_CAPBSET_DROP operations. + * + * Copyright (c) 2021 The strace developers. + * All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "tests.h" +#include "scno.h" +#include +#include +#include +#include + +int +main(void) +{ + long rc; + + rc = syscall(__NR_prctl, PR_CAPBSET_READ, CAP_AUDIT_CONTROL); + printf("prctl(PR_CAPBSET_READ, CAP_AUDIT_CONTROL) = %s\n", + sprintrc(rc)); + + rc = syscall(__NR_prctl, PR_CAPBSET_READ, CAP_NET_RAW); + printf("prctl(PR_CAPBSET_READ, CAP_NET_RAW) = %s\n", + sprintrc(rc)); + + rc = syscall(__NR_prctl, PR_CAPBSET_READ, 0xff); + printf("prctl(PR_CAPBSET_READ, 0xff /* CAP_??? */) = %s\n", + sprintrc(rc)); + + rc = syscall(__NR_prctl, PR_CAPBSET_DROP, CAP_AUDIT_CONTROL); + printf("prctl(PR_CAPBSET_DROP, CAP_AUDIT_CONTROL) = %s\n", + sprintrc(rc)); + + rc = syscall(__NR_prctl, PR_CAPBSET_DROP, CAP_NET_RAW); + printf("prctl(PR_CAPBSET_DROP, CAP_NET_RAW) = %s\n", + sprintrc(rc)); + + rc = syscall(__NR_prctl, PR_CAPBSET_DROP, 0xff); + printf("prctl(PR_CAPBSET_DROP, 0xff /* CAP_??? */) = %s\n", + sprintrc(rc)); + + puts("+++ exited with 0 +++"); + return 0; +} diff --git a/tests/prctl-capbset.test b/tests/prctl-capbset.test new file mode 100755 index 00000000..2002bcdd --- /dev/null +++ b/tests/prctl-capbset.test @@ -0,0 +1,16 @@ +#!/bin/sh +# +# Check decoding of prctl PR_CAPBSET_READ/PR_CAPBSET_DROP operations. +# +# Copyright (c) 2021 The strace developers. +# All rights reserved. +# +# SPDX-License-Identifier: GPL-2.0-or-later + +. "${srcdir=.}/init.sh" + +check_prog grep +run_prog > /dev/null +run_strace -a21 -eprctl $args > "$EXP" +grep -Ev '^prctl\(PR_[^C][^A][^P][^B][^S][^E][^T]_(DROP|READ)' < "$LOG" > "$OUT" +match_diff "$OUT" "$EXP" diff --git a/tests/prctl-fp-mode.c b/tests/prctl-fp-mode.c new file mode 100644 index 00000000..62c0b070 --- /dev/null +++ b/tests/prctl-fp-mode.c @@ -0,0 +1,96 @@ +/* + * Check decoding of prctl PR_GET_FP_MODE/PR_SET_FP_MODE operations. + * + * Copyright (c) 2021 The strace developers. + * All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "tests.h" +#include "scno.h" +#include +#include +#include +#include + +static long injected_val; + +long +do_prctl(kernel_ulong_t cmd, kernel_ulong_t arg2, kernel_ulong_t arg3) +{ + long rc = syscall(__NR_prctl, cmd, arg2, arg3); + + if (rc != injected_val) + error_msg_and_fail("Return value (%ld) differs from expected " + "injected value (%ld)", + rc, injected_val); + + return rc; +} + +int +main(int argc, char **argv) +{ + static const kernel_ulong_t bogus_arg2 = + (kernel_ulong_t) 0xdecafeedbeefda7eULL; + static const kernel_ulong_t bogus_arg3 = + (kernel_ulong_t) 0xdecafeedbeefda7eULL; + + static const struct { + long arg; + const char *str; + } get_strs[] = { + {-1, ""}, + {0, ""}, + {1, " (PR_FP_MODE_FR)"}, + {2, " (PR_FP_MODE_FRE)"}, + {3, " (PR_FP_MODE_FR|PR_FP_MODE_FRE)"}, + {0x20, " (0x20)"}, + {0x20 | 3, " (PR_FP_MODE_FR|PR_FP_MODE_FRE|0x20)"} + }; + static const struct { + kernel_ulong_t arg; + const char *str; + } set_strs[] = { + {0, "0"}, + {1, "PR_FP_MODE_FR"}, + {2, "PR_FP_MODE_FRE"}, + {3, "PR_FP_MODE_FR|PR_FP_MODE_FRE"}, + {0x20, "0x20 /* PR_FP_MODE_??? */"}, + {0x20 | 3, "PR_FP_MODE_FR|PR_FP_MODE_FRE|0x20"} + }; + + long rc; + const char *str = NULL; + + if (argc < 2) + error_msg_and_fail("Usage: %s INJECTED_VAL", argv[0]); + + injected_val = strtol(argv[1], NULL, 0); + + /* PR_GET_FP_MODE */ + rc = do_prctl(PR_GET_FP_MODE, bogus_arg2, bogus_arg3); + + for (size_t i = 0; i < ARRAY_SIZE(get_strs); i++) { + if (get_strs[i].arg == rc) { + str = get_strs[i].str; + break; + } + } + if (!str) + error_msg_and_fail("Unknown return value: %ld", rc); + + printf("prctl(PR_GET_FP_MODE) = %s%s (INJECTED)\n", sprintrc(rc), str); + + /* PR_SET_FP_MODE */ + for (size_t i = 0; i < ARRAY_SIZE(set_strs); i++) { + rc = do_prctl(PR_SET_FP_MODE, set_strs[i].arg, bogus_arg3); + + printf("prctl(PR_SET_FP_MODE, %s) = %s (INJECTED)\n", set_strs[i].str, + sprintrc(rc)); + } + + puts("+++ exited with 0 +++"); + return 0; +} diff --git a/tests/prctl-fp-mode.test b/tests/prctl-fp-mode.test new file mode 100755 index 00000000..bcd99675 --- /dev/null +++ b/tests/prctl-fp-mode.test @@ -0,0 +1,33 @@ +#!/bin/sh -efu +# +# Check decoding of prctl PR_GET_FP_MODE/PR_SET_FP_MODE operations. +# +# Copyright (c) 2021 The strace developers. +# All rights reserved. +# +# SPDX-License-Identifier: GPL-2.0-or-later + +. "${srcdir=.}/scno_tampering.sh" + +fault_args='-a21 -e trace=prctl -e inject=prctl:' +prog="../$NAME" + +test_run_rval() +{ + local rval injexpr + rval="$1"; shift + injexpr="$1"; shift + + run_strace $fault_args$injexpr $prog $rval > "$EXP" + LC_ALL=C grep -v '^prctl(PR_[GS]ET_[^F][^P][^_][^M][^O][^D][^E]' \ + < "$LOG" > "$OUT" + match_diff "$OUT" "$EXP" +} + +test_run_rval -1 "error=ENOTTY" +test_run_rval 0 "retval=0" +test_run_rval 1 "retval=1" +test_run_rval 2 "retval=2" +test_run_rval 3 "retval=3" +test_run_rval 32 "retval=32" +test_run_rval 35 "retval=35" diff --git a/tests/prctl-mce-kill.c b/tests/prctl-mce-kill.c new file mode 100644 index 00000000..3ff05f24 --- /dev/null +++ b/tests/prctl-mce-kill.c @@ -0,0 +1,59 @@ +/* + * Check decoding of prctl PR_MCE_KILL/PR_MCE_KILL_GET operations. + * + * Copyright (c) 2021 The strace developers. + * All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "tests.h" +#include "scno.h" +#include +#include +#include + +int +main(void) +{ + long rc; + + rc = syscall(__NR_prctl, PR_MCE_KILL, PR_MCE_KILL_CLEAR, 0, 0, 0); + printf("prctl(PR_MCE_KILL, PR_MCE_KILL_CLEAR, 0, 0, 0) = %s\n", + sprintrc(rc)); + + rc = syscall(__NR_prctl, PR_MCE_KILL, PR_MCE_KILL_SET, PR_MCE_KILL_EARLY, 0, 0); + printf("prctl(PR_MCE_KILL, PR_MCE_KILL_SET, PR_MCE_KILL_EARLY, 0, 0) = %s\n", + sprintrc(rc)); + + rc = syscall(__NR_prctl, PR_MCE_KILL, PR_MCE_KILL_SET, PR_MCE_KILL_LATE, 0, 0); + printf("prctl(PR_MCE_KILL, PR_MCE_KILL_SET, PR_MCE_KILL_LATE, 0, 0) = %s\n", + sprintrc(rc)); + + rc = syscall(__NR_prctl, PR_MCE_KILL, PR_MCE_KILL_SET, 0xff, 0, 0); + printf("prctl(PR_MCE_KILL, PR_MCE_KILL_SET, 0xff /* PR_MCE_KILL_??? */, 0, 0) = %s\n", + sprintrc(rc)); + + rc = syscall(__NR_prctl, PR_MCE_KILL, 0xaaaa, 0xbbbb, 0xcccc, 0xdddd); + printf("prctl(PR_MCE_KILL, 0xaaaa /* PR_MCE_KILL_??? */, 0xbbbb, 0xcccc, 0xdddd) = %s\n", + sprintrc(rc)); + + rc = syscall(__NR_prctl, PR_MCE_KILL, PR_MCE_KILL_SET, PR_MCE_KILL_DEFAULT, 0, 0); + printf("prctl(PR_MCE_KILL, PR_MCE_KILL_SET, PR_MCE_KILL_DEFAULT, 0, 0) = %s\n", + sprintrc(rc)); + + rc = syscall(__NR_prctl, PR_MCE_KILL_GET, 0, 0, 0, 0); + if (rc) + printf("prctl(PR_MCE_KILL_GET, 0, 0, 0, 0) = %s (PR_MCE_KILL_DEFAULT)\n", + sprintrc(rc)); + else + printf("prctl(PR_MCE_KILL_GET, 0, 0, 0, 0) = %s\n", + sprintrc(rc)); + + rc = syscall(__NR_prctl, PR_MCE_KILL_GET, 0xaaaa, 0xbbbb, 0xcccc, 0xdddd); + printf("prctl(PR_MCE_KILL_GET, 0xaaaa, 0xbbbb, 0xcccc, 0xdddd) = %s\n", + sprintrc(rc)); + + puts("+++ exited with 0 +++"); + return 0; +} diff --git a/tests/prctl-mce-kill.test b/tests/prctl-mce-kill.test new file mode 100755 index 00000000..d22a9a52 --- /dev/null +++ b/tests/prctl-mce-kill.test @@ -0,0 +1,16 @@ +#!/bin/sh +# +# Check decoding of prctl PR_MCE_KILL/PR_MCE_KILL_GET operations. +# +# Copyright (c) 2021 The strace developers. +# All rights reserved. +# +# SPDX-License-Identifier: GPL-2.0-or-later + +. "${srcdir=.}/init.sh" + +check_prog grep +run_prog > /dev/null +run_strace -a21 -eprctl $args > "$EXP" +grep -v '^prctl(PR_[^M][^C][^E]_[^K][^I][^L][^L]' < "$LOG" > "$OUT" +match_diff "$OUT" "$EXP" diff --git a/tests/prctl-sve.c b/tests/prctl-sve.c new file mode 100644 index 00000000..ea212935 --- /dev/null +++ b/tests/prctl-sve.c @@ -0,0 +1,53 @@ +/* + * Check decoding of prctl PR_SVE_SET_VL/PR_SVE_GET_VL operations. + * + * Copyright (c) 2021 The strace developers. + * All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "tests.h" +#include "scno.h" +#include +#include +#include + +int +main(void) +{ + long rc; + + rc = syscall(__NR_prctl, PR_SVE_SET_VL, 0xf); + printf("prctl(PR_SVE_SET_VL, %#lx) = %s\n", (unsigned long) 0xf, + sprintrc(rc)); + + rc = syscall(__NR_prctl, PR_SVE_SET_VL, 0xff); + printf("prctl(PR_SVE_SET_VL, %#lx) = %s\n", (unsigned long) 0xff, + sprintrc(rc)); + + rc = syscall(__NR_prctl, PR_SVE_SET_VL, PR_SVE_SET_VL_ONEXEC | 0xff); + printf("prctl(PR_SVE_SET_VL, PR_SVE_SET_VL_ONEXEC|%#lx) = %s\n", + (unsigned long) 0xff, sprintrc(rc)); + + rc = syscall(__NR_prctl, PR_SVE_SET_VL, PR_SVE_VL_INHERIT | 0xff); + printf("prctl(PR_SVE_SET_VL, PR_SVE_VL_INHERIT|%#lx) = %s\n", + (unsigned long) 0xff, sprintrc(rc)); + + rc = syscall(__NR_prctl, PR_SVE_SET_VL, + PR_SVE_SET_VL_ONEXEC | PR_SVE_VL_INHERIT | 0xff); + printf("prctl(PR_SVE_SET_VL, " + "PR_SVE_SET_VL_ONEXEC|PR_SVE_VL_INHERIT|%#lx) = %s\n", + (unsigned long) 0xff, sprintrc(rc)); + + rc = syscall(__NR_prctl, PR_SVE_GET_VL); + printf("prctl(PR_SVE_GET_VL) = %s", sprintrc(rc)); + if (rc >= 0) { + printf(" (PR_SVE_SET_VL_ONEXEC|PR_SVE_VL_INHERIT|%#lx)", + (unsigned long) 0xff); + } + puts(""); + + puts("+++ exited with 0 +++"); + return 0; +} diff --git a/tests/prctl-sve.test b/tests/prctl-sve.test new file mode 100755 index 00000000..14c2805f --- /dev/null +++ b/tests/prctl-sve.test @@ -0,0 +1,16 @@ +#!/bin/sh +# +# Check decoding of prctl PR_SVE_SET_VL/PR_SVE_GET_VL operations. +# +# Copyright (c) 2021 The strace developers. +# All rights reserved. +# +# SPDX-License-Identifier: GPL-2.0-or-later + +. "${srcdir=.}/init.sh" + +check_prog grep +run_prog > /dev/null +run_strace -a21 -eprctl $args > "$EXP" +grep -v '^prctl(PR_[^S][^V][^E]_[GS]ET_[^V][^L]' < "$LOG" > "$OUT" +match_diff "$OUT" "$EXP" diff --git a/tests/prctl-unalign.c b/tests/prctl-unalign.c new file mode 100644 index 00000000..8d919b6f --- /dev/null +++ b/tests/prctl-unalign.c @@ -0,0 +1,48 @@ +/* + * Check decoding of prctl PR_GET_UNALIGN/PR_SET_UNALIGN operations. + * + * Copyright (c) 2021 The strace developers. + * All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "tests.h" +#include "scno.h" +#include +#include +#include + +int +main(void) +{ + TAIL_ALLOC_OBJECT_CONST_PTR(unsigned int, unalign); + long rc; + + rc = syscall(__NR_prctl, PR_SET_UNALIGN, PR_UNALIGN_NOPRINT | PR_UNALIGN_SIGBUS); + printf("prctl(PR_SET_UNALIGN, PR_UNALIGN_NOPRINT|PR_UNALIGN_SIGBUS) = %s\n", + sprintrc(rc)); + + rc = syscall(__NR_prctl, PR_SET_UNALIGN, 0xff00); + printf("prctl(PR_SET_UNALIGN, %#llx /* PR_UNALIGN_??? */) = %s\n", + (unsigned long long) 0xff00, sprintrc(rc)); + + rc = syscall(__NR_prctl, PR_SET_UNALIGN, PR_UNALIGN_SIGBUS); + printf("prctl(PR_SET_UNALIGN, PR_UNALIGN_SIGBUS) = %s\n", sprintrc(rc)); + + rc = syscall(__NR_prctl, PR_GET_UNALIGN, unalign + 1); + printf("prctl(PR_GET_UNALIGN, %p) = %s\n", unalign + 1, sprintrc(rc)); + + rc = syscall(__NR_prctl, PR_GET_UNALIGN, NULL); + printf("prctl(PR_GET_UNALIGN, NULL) = %s\n", sprintrc(rc)); + + rc = syscall(__NR_prctl, PR_GET_UNALIGN, unalign); + if (rc) + printf("prctl(PR_GET_UNALIGN, %p) = %s\n", unalign, sprintrc(rc)); + else + printf("prctl(PR_GET_UNALIGN, [PR_UNALIGN_SIGBUS]) = %s\n", + sprintrc(rc)); + + puts("+++ exited with 0 +++"); + return 0; +} diff --git a/tests/prctl-unalign.test b/tests/prctl-unalign.test new file mode 100755 index 00000000..b03540e5 --- /dev/null +++ b/tests/prctl-unalign.test @@ -0,0 +1,16 @@ +#!/bin/sh -efu +# +# Check decoding of prctl PR_GET_UNALIGN/PR_SET_UNALIGN operations. +# +# Copyright (c) 2021 The strace developers. +# All rights reserved. +# +# SPDX-License-Identifier: GPL-2.0-or-later + +. "${srcdir=.}/init.sh" + +check_prog grep +run_prog > /dev/null +run_strace -a28 -eprctl $args > "$EXP" +grep -v '^prctl(PR_[GS]ET_[^U][^N][^A][^L][^I][^G][^N]' < "$LOG" > "$OUT" +match_diff "$OUT" "$EXP" diff --git a/tests/pure_executables.list b/tests/pure_executables.list index 9c329c4e..52c849ce 100755 --- a/tests/pure_executables.list +++ b/tests/pure_executables.list @@ -449,13 +449,18 @@ poke-sendfile poll ppoll prctl-arg2-intptr +prctl-cap-ambient +prctl-capbset prctl-dumpable +prctl-mce-kill prctl-name prctl-no-args prctl-pdeathsig prctl-securebits +prctl-sve prctl-tid_address prctl-tsc +prctl-unalign pread64-pwrite64 preadv preadv-pwritev -- 2.25.1 From 3563deb6753 at gmail.com Wed Mar 24 06:24:26 2021 From: 3563deb6753 at gmail.com (deborah brouwer) Date: Tue, 23 Mar 2021 23:24:26 -0700 Subject: [GSOC] Microproject - statfs constant ST_NOSYMFOLLOW Message-ID: <20210324062425.GA25161@djbComp> Hi, Would it be a good microproject to add the ST_NOSYMFOLLOW constant for statfs that was introduced in Linux 5.10? Deb From rmetrich at redhat.com Wed Mar 24 14:52:21 2021 From: rmetrich at redhat.com (=?UTF-8?Q?Renaud_M=c3=a9trich?=) Date: Wed, 24 Mar 2021 15:52:21 +0100 Subject: Proposing SELinux support in strace In-Reply-To: <20210316013026.GA21789@altlinux.org> References: <20210119231326.GA15157@altlinux.org> <20210217001009.GA8097@altlinux.org> <2b816386-321d-5db6-6b84-19f987404863@redhat.com> <8553b7c6-a0fa-e202-4f0d-edb8a878a697@redhat.com> <20210305141819.GB14087@altlinux.org> <20210315011000.GA3123@altlinux.org> <2a0ba13b-620c-0bf6-11c7-c123947f0050@redhat.com> <20210316013026.GA21789@altlinux.org> Message-ID: <42e45004-46c6-01cd-9df1-77a42799ffe9@redhat.com> Hi Dmitry, Sorry for the delay, I was busy this week. I pushed the new code with updated test suite. Still I have an issue regarding 1 test: test_personality_64 I don't understand what is supposed to be checked here, the strace runs on "getcwd" but fails because now some tests (including "execveat") use getcwd() internally. Renaud. On 3/16/21 2:30 AM, Dmitry V. Levin wrote: > On Mon, Mar 15, 2021 at 06:09:34PM +0100, Renaud M?trich wrote: > [...] >> diff --git a/tests/linkat--secontext.c b/tests/linkat--secontext.c >> index f2fd003d7..4818d676b 100644 >> --- a/tests/linkat--secontext.c >> +++ b/tests/linkat--secontext.c >> @@ -20,6 +20,7 @@ >> # include >> # include >> # include >> +# include >> >> /* for getcwd()/opendir() */ >> # include >> @@ -97,9 +98,7 @@ main(void) >> perror_msg_and_fail("dirfd"); >> >> static const char sample_2_dir[] = "new"; >> - char *new_sample_2 = malloc(strlen(sample_2_dir) + 1 + strlen(sample_2) + 1); >> - if (new_sample_2 == NULL) >> - perror_msg_and_fail("malloc"); >> + char *new_sample_2 = xmalloc(strlen(sample_2_dir) + 1 + strlen(sample_2) + 1); >> sprintf(new_sample_2, "%s/%s", sample_2_dir, sample_2); > I've added xasprintf to xmalloc, now you can write this as simple as > > char *new_sample_2 = xasprintf("%s/%s", sample_2_dir, sample_2); > -------------- next part -------------- A non-text attachment was scrubbed... Name: OpenPGP_signature Type: application/pgp-signature Size: 840 bytes Desc: OpenPGP digital signature URL: From rmetrich at redhat.com Wed Mar 24 18:49:10 2021 From: rmetrich at redhat.com (=?UTF-8?Q?Renaud_M=c3=a9trich?=) Date: Wed, 24 Mar 2021 19:49:10 +0100 Subject: Proposing SELinux support in strace In-Reply-To: <42e45004-46c6-01cd-9df1-77a42799ffe9@redhat.com> References: <20210119231326.GA15157@altlinux.org> <20210217001009.GA8097@altlinux.org> <2b816386-321d-5db6-6b84-19f987404863@redhat.com> <8553b7c6-a0fa-e202-4f0d-edb8a878a697@redhat.com> <20210305141819.GB14087@altlinux.org> <20210315011000.GA3123@altlinux.org> <2a0ba13b-620c-0bf6-11c7-c123947f0050@redhat.com> <20210316013026.GA21789@altlinux.org> <42e45004-46c6-01cd-9df1-77a42799ffe9@redhat.com> Message-ID: <53b5f8ac-77a2-9831-9f7e-2b928d797810@redhat.com> OK I fixed the issue with the personality tests. PR is currently being in CI. On 3/24/21 3:52 PM, Renaud M?trich wrote: > Hi Dmitry, > > Sorry for the delay, I was busy this week. > > I pushed the new code with updated test suite. > > Still I have an issue regarding 1 test: test_personality_64 > > I don't understand what is supposed to be checked here, the strace > runs on "getcwd" but fails because now some tests (including > "execveat") use getcwd() internally. > > Renaud. > > On 3/16/21 2:30 AM, Dmitry V. Levin wrote: >> On Mon, Mar 15, 2021 at 06:09:34PM +0100, Renaud M?trich wrote: >> [...] >>> diff --git a/tests/linkat--secontext.c b/tests/linkat--secontext.c >>> index f2fd003d7..4818d676b 100644 >>> --- a/tests/linkat--secontext.c >>> +++ b/tests/linkat--secontext.c >>> @@ -20,6 +20,7 @@ >>> ? # include >>> ? # include >>> ? # include >>> +# include >>> ? ? /* for getcwd()/opendir() */ >>> ? # include >>> @@ -97,9 +98,7 @@ main(void) >>> ????????? perror_msg_and_fail("dirfd"); >>> ? ????? static const char sample_2_dir[] = "new"; >>> -??? char *new_sample_2 = malloc(strlen(sample_2_dir) + 1 + >>> strlen(sample_2) + 1); >>> -??? if (new_sample_2 == NULL) >>> -??????? perror_msg_and_fail("malloc"); >>> +??? char *new_sample_2 = xmalloc(strlen(sample_2_dir) + 1 + >>> strlen(sample_2) + 1); >>> ????? sprintf(new_sample_2, "%s/%s", sample_2_dir, sample_2); >> I've added xasprintf to xmalloc, now you can write this as simple as >> >> ????char *new_sample_2 = xasprintf("%s/%s", sample_2_dir, sample_2); >> > -------------- next part -------------- A non-text attachment was scrubbed... Name: OpenPGP_signature Type: application/pgp-signature Size: 840 bytes Desc: OpenPGP digital signature URL: From ldv at altlinux.org Thu Mar 25 02:00:53 2021 From: ldv at altlinux.org (Dmitry V. Levin) Date: Thu, 25 Mar 2021 05:00:53 +0300 Subject: [PATCH] tests: improve test coverage of prctl syscall decoder In-Reply-To: <20210323233940.23073-1-srikavinramkumar@gmail.com> References: <20210323233940.23073-1-srikavinramkumar@gmail.com> Message-ID: <20210325020053.GB6714@altlinux.org> On Tue, Mar 23, 2021 at 07:39:45PM -0400, Srikavin Ramkumar wrote: > * tests/.gitignore: Add new test binaries. > * tests/Makefile.am: Add new tests. > * tests/pure_executables.list: Likewise. > * tests/prctl-cap-ambient.c: New file. > * tests/prctl-cap-ambient.test: Likewise. > * tests/prctl-capbset.c: Likewise. > * tests/prctl-capbset.test: Likewise. > * tests/prctl-fp-mode.c: Likewise. > * tests/prctl-fp-mode.test: Likewise. > * tests/prctl-mce-kill.c: Likewise. > * tests/prctl-mce-kill.test: Likewise. > * tests/prctl-sve.c: Likewise. > * tests/prctl-sve.test: Likewise. > * tests/prctl-unalign.c: Likewise. > * tests/prctl-unalign.test: Likewise. > --- > > This is part of my GSoC microproject. I plan to add a few more tests, but I > wanted to make sure that I'm on the right track with these tests. These tests > pass the CI, and the coverage results can be found here [1]. > > [1]: https://codecov.io/gh/srikavin/strace/src/prctl-tests/src/prctl.c I haven't looked into details yet, but overall these tests look good. -- ldv From ldv at altlinux.org Thu Mar 25 02:17:12 2021 From: ldv at altlinux.org (Dmitry V. Levin) Date: Thu, 25 Mar 2021 05:17:12 +0300 Subject: [GSOC] Microproject - statfs constant ST_NOSYMFOLLOW In-Reply-To: <20210324062425.GA25161@djbComp> References: <20210324062425.GA25161@djbComp> Message-ID: <20210325021712.GC6714@altlinux.org> Hi, On Tue, Mar 23, 2021 at 11:24:26PM -0700, deborah brouwer wrote: > Hi, > Would it be a good microproject to add the ST_NOSYMFOLLOW constant for statfs that was introduced in Linux 5.10? Good catch, we somehow missed ST_NOSYMFOLLOW, most likely because it isn't defined in UAPI. -- ldv From ldv at altlinux.org Thu Mar 25 02:45:02 2021 From: ldv at altlinux.org (Dmitry V. Levin) Date: Thu, 25 Mar 2021 05:45:02 +0300 Subject: Proposing SELinux support in strace In-Reply-To: <42e45004-46c6-01cd-9df1-77a42799ffe9@redhat.com> References: <20210217001009.GA8097@altlinux.org> <2b816386-321d-5db6-6b84-19f987404863@redhat.com> <8553b7c6-a0fa-e202-4f0d-edb8a878a697@redhat.com> <20210305141819.GB14087@altlinux.org> <20210315011000.GA3123@altlinux.org> <2a0ba13b-620c-0bf6-11c7-c123947f0050@redhat.com> <20210316013026.GA21789@altlinux.org> <42e45004-46c6-01cd-9df1-77a42799ffe9@redhat.com> Message-ID: <20210325024501.GA7333@altlinux.org> Hi Renaud, On Wed, Mar 24, 2021 at 03:52:21PM +0100, Renaud M?trich wrote: > Hi Dmitry, > > Sorry for the delay, I was busy this week. > > I pushed the new code with updated test suite. > > Still I have an issue regarding 1 test: test_personality_64 > > I don't understand what is supposed to be checked here, the strace runs > on "getcwd" but fails because now some tests (including "execveat") use > getcwd() internally. I haven't looked into details yet, but your guess about the reason why test_personality_* started to fail is correct. I'm not sure why do you need getcwd in the first place, though. If you need a descriptor referring to the current directory, you can open "." instead of the result of getcwd. If you need to chdir back, you can fchdir using that descriptor. You probably can replace SELINUX_FILECONTEXT(cwd) with SELINUX_FILECONTEXT(".") and save the result for later use if the current workdir is changed in the test. It doesn't mean that you cannot use getcwd, but this would exclude the test from test_personality_* which is not very nice, so we should try to avoid unnecessary use of getcwd. -- ldv From 3563deb6753 at gmail.com Thu Mar 25 04:26:33 2021 From: 3563deb6753 at gmail.com (Deborah Brouwer) Date: Wed, 24 Mar 2021 21:26:33 -0700 Subject: [PATCH] xlat: update ST_NOSYMFOLLOW constant Message-ID: <20210325042629.GA4418@djbComp> Linux 5.10 introduced new constant ST_NOSYMFOLLOW. Signed-off-by: Deborah Brouwer <3563deb6753 at gmail.com> --- src/xlat/statfs_flags.in | 1 + 1 file changed, 1 insertion(+) diff --git a/src/xlat/statfs_flags.in b/src/xlat/statfs_flags.in index f791a60e..90a06138 100644 --- a/src/xlat/statfs_flags.in +++ b/src/xlat/statfs_flags.in @@ -8,3 +8,4 @@ ST_MANDLOCK 0x0040 ST_NOATIME 0x0400 ST_NODIRATIME 0x0800 ST_RELATIME 0x1000 +ST_NOSYMFOLLOW 0x2000 -- 2.17.1 From rmetrich at redhat.com Thu Mar 25 12:51:09 2021 From: rmetrich at redhat.com (=?UTF-8?Q?Renaud_M=c3=a9trich?=) Date: Thu, 25 Mar 2021 13:51:09 +0100 Subject: Proposing SELinux support in strace In-Reply-To: <20210325024501.GA7333@altlinux.org> References: <20210217001009.GA8097@altlinux.org> <2b816386-321d-5db6-6b84-19f987404863@redhat.com> <8553b7c6-a0fa-e202-4f0d-edb8a878a697@redhat.com> <20210305141819.GB14087@altlinux.org> <20210315011000.GA3123@altlinux.org> <2a0ba13b-620c-0bf6-11c7-c123947f0050@redhat.com> <20210316013026.GA21789@altlinux.org> <42e45004-46c6-01cd-9df1-77a42799ffe9@redhat.com> <20210325024501.GA7333@altlinux.org> Message-ID: Hi Dmitry, I reworked all the tests to stop having getcwd() calls. This means realpath() cannot be used. Please check the PR, tests/ only, rest was already reviewed (since it's basically *your* code ...) On 3/25/21 3:45 AM, Dmitry V. Levin wrote: > Hi Renaud, > > On Wed, Mar 24, 2021 at 03:52:21PM +0100, Renaud M?trich wrote: >> Hi Dmitry, >> >> Sorry for the delay, I was busy this week. >> >> I pushed the new code with updated test suite. >> >> Still I have an issue regarding 1 test: test_personality_64 >> >> I don't understand what is supposed to be checked here, the strace runs >> on "getcwd" but fails because now some tests (including "execveat") use >> getcwd() internally. > I haven't looked into details yet, but your guess about the reason why > test_personality_* started to fail is correct. I'm not sure why do you > need getcwd in the first place, though. If you need a descriptor > referring to the current directory, you can open "." instead of the result > of getcwd. If you need to chdir back, you can fchdir using that > descriptor. You probably can replace SELINUX_FILECONTEXT(cwd) with > SELINUX_FILECONTEXT(".") and save the result for later use if the current > workdir is changed in the test. It doesn't mean that you cannot use > getcwd, but this would exclude the test from test_personality_* which > is not very nice, so we should try to avoid unnecessary use of getcwd. > > -------------- next part -------------- A non-text attachment was scrubbed... Name: OpenPGP_signature Type: application/pgp-signature Size: 840 bytes Desc: OpenPGP digital signature URL: From hi at alyssa.is Thu Mar 25 03:55:54 2021 From: hi at alyssa.is (Alyssa Ross) Date: Thu, 25 Mar 2021 03:55:54 +0000 Subject: [PATCH] close_range: fd and max_fd are unsigned Message-ID: <20210325035554.25656-1-hi@alyssa.is> The distinction is important, because close_range(2) says that having max_fd < fd is an error, but if you give the kernel 1U + INT_MAX as max_fd, it'll interpret it as unsigned. Since we're working with ranges of file descriptors here, the particular properties of only the start and end file descriptors aren't really relevant, so it doesn't matter that we're losing fancy file descriptor printing in making this change. Signed-off-by: Alyssa Ross --- src/close_range.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/close_range.c b/src/close_range.c index 3b11c170..4c267bdc 100644 --- a/src/close_range.c +++ b/src/close_range.c @@ -12,11 +12,11 @@ SYS_FUNC(close_range) { /* fd */ - printfd(tcp, tcp->u_arg[0]); + tprintf("%u", (unsigned int)tcp->u_arg[0]); tprint_arg_next(); /* max_fd */ - printfd(tcp, tcp->u_arg[1]); + tprintf("%u", (unsigned int)tcp->u_arg[1]); tprint_arg_next(); /* flags */ -- 2.30.0 From ldv at altlinux.org Fri Mar 26 00:32:22 2021 From: ldv at altlinux.org (Dmitry V. Levin) Date: Fri, 26 Mar 2021 03:32:22 +0300 Subject: [PATCH] close_range: fd and max_fd are unsigned In-Reply-To: <20210325035554.25656-1-hi@alyssa.is> References: <20210325035554.25656-1-hi@alyssa.is> Message-ID: <20210326003222.GA22197@altlinux.org> Hi, On Thu, Mar 25, 2021 at 03:55:54AM +0000, Alyssa Ross wrote: > The distinction is important, because close_range(2) says that having > max_fd < fd is an error, but if you give the kernel 1U + INT_MAX as > max_fd, it'll interpret it as unsigned. > > Since we're working with ranges of file descriptors here, the > particular properties of only the start and end file descriptors > aren't really relevant, so it doesn't matter that we're losing fancy > file descriptor printing in making this change. > > Signed-off-by: Alyssa Ross I'm inclined to agree with your interpretation, fd and max_fd are indeed unsigned integers rather than file descriptors, and there seems to be no easy way to identify all file descriptors in the specified interval. The proposed patch just changes the printer of close_range syscall, but there are at least two more places that need more attention. First is -P option: pathtrace_match_set tries to match fd and max_fd assuming they are file descriptors. Second is tests: tests/close_range* are checking the current behaviour, they will fail if the printer of close_range syscall is changed this way. > --- > src/close_range.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/src/close_range.c b/src/close_range.c > index 3b11c170..4c267bdc 100644 > --- a/src/close_range.c > +++ b/src/close_range.c > @@ -12,11 +12,11 @@ > SYS_FUNC(close_range) > { > /* fd */ > - printfd(tcp, tcp->u_arg[0]); > + tprintf("%u", (unsigned int)tcp->u_arg[0]); > tprint_arg_next(); > > /* max_fd */ > - printfd(tcp, tcp->u_arg[1]); > + tprintf("%u", (unsigned int)tcp->u_arg[1]); > tprint_arg_next(); Please note that we are (slowly but surely) getting rid of raw tprintf calls, the recommended way of printing these integers would be PRINT_VAL_U((unsigned int) tcp->u_arg[0]); ... PRINT_VAL_U((unsigned int) tcp->u_arg[1]); -- ldv From ldv at altlinux.org Fri Mar 26 00:52:23 2021 From: ldv at altlinux.org (Dmitry V. Levin) Date: Fri, 26 Mar 2021 03:52:23 +0300 Subject: [PATCH] xlat: update ST_NOSYMFOLLOW constant In-Reply-To: <20210325042629.GA4418@djbComp> References: <20210325042629.GA4418@djbComp> Message-ID: <20210326005223.GB22197@altlinux.org> Hi, Since the change itself is trivial, I'll be extra picky about details so you could get a taste of patch review process. On Wed, Mar 24, 2021 at 09:26:33PM -0700, Deborah Brouwer wrote: > Linux 5.10 introduced new constant ST_NOSYMFOLLOW. > > Signed-off-by: Deborah Brouwer <3563deb6753 at gmail.com> As we try to be more specific nowadays, we usually mention the Linux kernel commit introduced the new constant, see e.g. strace commit v5.11~31. We also try to list user visible changes in the NEWS file, see e.g. the same commit. Sometimes we also update tests to check printing of new constants, but that is not mandatory. The first line of the commit message says "xlat: update ST_NOSYMFOLLOW constant" which is a bit misleading because the change doesn't update ST_NOSYMFOLLOW constant. > --- > src/xlat/statfs_flags.in | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/src/xlat/statfs_flags.in b/src/xlat/statfs_flags.in > index f791a60e..90a06138 100644 > --- a/src/xlat/statfs_flags.in > +++ b/src/xlat/statfs_flags.in > @@ -8,3 +8,4 @@ ST_MANDLOCK 0x0040 > ST_NOATIME 0x0400 > ST_NODIRATIME 0x0800 > ST_RELATIME 0x1000 > +ST_NOSYMFOLLOW 0x2000 This part is fine. -- ldv From ldv at altlinux.org Fri Mar 26 01:07:42 2021 From: ldv at altlinux.org (Dmitry V. Levin) Date: Fri, 26 Mar 2021 04:07:42 +0300 Subject: Proposing SELinux support in strace In-Reply-To: References: <8553b7c6-a0fa-e202-4f0d-edb8a878a697@redhat.com> <20210305141819.GB14087@altlinux.org> <20210315011000.GA3123@altlinux.org> <2a0ba13b-620c-0bf6-11c7-c123947f0050@redhat.com> <20210316013026.GA21789@altlinux.org> <42e45004-46c6-01cd-9df1-77a42799ffe9@redhat.com> <20210325024501.GA7333@altlinux.org> Message-ID: <20210326010742.GC22197@altlinux.org> Hi Dmitry, On Thu, Mar 25, 2021 at 01:51:09PM +0100, Renaud M?trich wrote: > Hi Dmitry, > > I reworked all the tests to stop having getcwd() calls. > > This means realpath() cannot be used. > > Please check the PR, tests/ only, rest was already reviewed (since it's > basically *your* code ...) I've just got two comments about get_curdir_fd: - when using readlink, please make sure the returned string is NUL-terminated, see e.g. getfdpath_pid; - the most likely reason why readlink of /proc/self/cwd could fail is that /proc is not mounted, let's use perror_msg_and_skip instead of perror_msg_and_fail in that case. -- ldv From rmetrich at redhat.com Fri Mar 26 09:16:27 2021 From: rmetrich at redhat.com (=?UTF-8?Q?Renaud_M=c3=a9trich?=) Date: Fri, 26 Mar 2021 10:16:27 +0100 Subject: Proposing SELinux support in strace In-Reply-To: <20210326010742.GC22197@altlinux.org> References: <8553b7c6-a0fa-e202-4f0d-edb8a878a697@redhat.com> <20210305141819.GB14087@altlinux.org> <20210315011000.GA3123@altlinux.org> <2a0ba13b-620c-0bf6-11c7-c123947f0050@redhat.com> <20210316013026.GA21789@altlinux.org> <42e45004-46c6-01cd-9df1-77a42799ffe9@redhat.com> <20210325024501.GA7333@altlinux.org> <20210326010742.GC22197@altlinux.org> Message-ID: <814989de-7ebc-4e56-524f-399991663591@redhat.com> Thanks, fixed. I additionally handled the buffer too small case, just in case ... I didn't merge de commits yet, to keep track of changes, will do once ready to merge. On 3/26/21 2:07 AM, Dmitry V. Levin wrote: > Hi Dmitry, > > On Thu, Mar 25, 2021 at 01:51:09PM +0100, Renaud M?trich wrote: >> Hi Dmitry, >> >> I reworked all the tests to stop having getcwd() calls. >> >> This means realpath() cannot be used. >> >> Please check the PR, tests/ only, rest was already reviewed (since it's >> basically *your* code ...) > I've just got two comments about get_curdir_fd: > - when using readlink, please make sure the returned string is > NUL-terminated, see e.g. getfdpath_pid; > - the most likely reason why readlink of /proc/self/cwd could fail is that > /proc is not mounted, let's use perror_msg_and_skip instead of > perror_msg_and_fail in that case. > > -------------- next part -------------- A non-text attachment was scrubbed... Name: OpenPGP_signature Type: application/pgp-signature Size: 840 bytes Desc: OpenPGP digital signature URL: From srikavinramkumar at gmail.com Fri Mar 26 16:14:34 2021 From: srikavinramkumar at gmail.com (Srikavin Ramkumar) Date: Fri, 26 Mar 2021 12:14:34 -0400 Subject: [GSOC] Introduction and Microproject In-Reply-To: <20210315014045.GB3123@altlinux.org> Message-ID: Hi, I'm currently drafting a GSoC proposal and had a few questions about the implementation of the parser/code generator: 1. Is using Python 3 to parse and generate decoders/tests from syzkaller descriptions at build time OK? Alternatively, the script could be run when the underlying syzkaller descriptions change and the generated code could be committed so Python wouldn't be needed to build strace. 2. The syzkaller description language (syzlang) doesn't differentiate between (enum-like) mutually exclusive flags and OR-able bit flags [1]. Consider the prctl option PR_FP_MODE. It has two flags PR_FP_MODE_FR=1, PR_FP_MODE_FRE=2. If we decode the value 3 assuming it is enum-like we would decode it as PR_FP_MODE_???, while if we (correctly) treated it as bit flags, we would decode it as PR_FP_MODE_FR|PR_FP_MODE_FRE. I'd prefer to stick with syzlang since a large number of syscalls/ioctls are already defined. Would it be a good idea to extend the syslang language with a new type to differentiate between these cases? Or should we keep the original syslang description files, but maintain a separate categorization of which flags should be treated as bit-wise vs mutually exclusive? [1]: https://github.com/google/syzkaller/blob/master/docs/syscall_descriptions.md#flagsenums Thanks, Srikavin Ramkumar From ldv at altlinux.org Sat Mar 27 00:45:09 2021 From: ldv at altlinux.org (Dmitry V. Levin) Date: Sat, 27 Mar 2021 03:45:09 +0300 Subject: [GSOC] Introduction and Microproject In-Reply-To: References: <20210315014045.GB3123@altlinux.org> Message-ID: <20210327004505.GA5392@altlinux.org> Hi, On Fri, Mar 26, 2021 at 12:14:34PM -0400, Srikavin Ramkumar wrote: > Hi, > > I'm currently drafting a GSoC proposal and had a few questions about the > implementation of the parser/code generator: > > 1. Is using Python 3 to parse and generate decoders/tests from syzkaller > descriptions at build time OK? Alternatively, the script could be run when the > underlying syzkaller descriptions change and the generated code could be > committed so Python wouldn't be needed to build strace. I think such generators do not have to be run at build time. We have a few scripts in maint directory that are run manually as a part of maintenance, and the new script would fit into that pattern. > 2. The syzkaller description language (syzlang) doesn't differentiate between > (enum-like) mutually exclusive flags and OR-able bit flags [1]. Consider the > prctl option PR_FP_MODE. It has two flags PR_FP_MODE_FR=1, PR_FP_MODE_FRE=2. If > we decode the value 3 assuming it is enum-like we would decode it as > PR_FP_MODE_???, while if we (correctly) treated it as bit flags, we would decode > it as PR_FP_MODE_FR|PR_FP_MODE_FRE. > > I'd prefer to stick with syzlang since a large number of syscalls/ioctls are > already defined. Would it be a good idea to extend the syslang language with a > new type to differentiate between these cases? Or should we keep the original > syslang description files, but maintain a separate categorization of which flags > should be treated as bit-wise vs mutually exclusive? > > [1]: https://github.com/google/syzkaller/blob/master/docs/syscall_descriptions.md#flagsenums This documentation also says that "The fuzzer has logic to distinguish enums and bit flags". I don't know how do they do it, but strace certainly doesn't have anything like that, we have dedicated functions for printing enums and flags instead. The idea to extend syzlang to describe enums, flags, and their hybrids sounds good to me. -- ldv From 3563deb6753 at gmail.com Sat Mar 27 04:16:11 2021 From: 3563deb6753 at gmail.com (deborah brouwer) Date: Fri, 26 Mar 2021 21:16:11 -0700 Subject: [PATCH] xlat: update ST_NOSYMFOLLOW constant In-Reply-To: <20210326005223.GB22197@altlinux.org> References: <20210325042629.GA4418@djbComp> <20210326005223.GB22197@altlinux.org> Message-ID: <20210327041610.GA31634@djbComp> On Fri, Mar 26, 2021 at 03:52:23AM +0300, Dmitry V. Levin wrote: > Hi, > > Since the change itself is trivial, I'll be extra picky about details > so you could get a taste of patch review process. > > On Wed, Mar 24, 2021 at 09:26:33PM -0700, Deborah Brouwer wrote: > > Linux 5.10 introduced new constant ST_NOSYMFOLLOW. > > > > Signed-off-by: Deborah Brouwer <3563deb6753 at gmail.com> > > As we try to be more specific nowadays, we usually mention the Linux > kernel commit introduced the new constant, see e.g. strace commit > v5.11~31. > > We also try to list user visible changes in the NEWS file, see e.g. > the same commit. > > Sometimes we also update tests to check printing of new constants, but > that is not mandatory. > > The first line of the commit message says "xlat: update ST_NOSYMFOLLOW > constant" which is a bit misleading because the change doesn't update > ST_NOSYMFOLLOW constant. > > > --- > > src/xlat/statfs_flags.in | 1 + > > 1 file changed, 1 insertion(+) > > > > diff --git a/src/xlat/statfs_flags.in b/src/xlat/statfs_flags.in > > index f791a60e..90a06138 100644 > > --- a/src/xlat/statfs_flags.in > > +++ b/src/xlat/statfs_flags.in > > @@ -8,3 +8,4 @@ ST_MANDLOCK 0x0040 > > ST_NOATIME 0x0400 > > ST_NODIRATIME 0x0800 > > ST_RELATIME 0x1000 > > +ST_NOSYMFOLLOW 0x2000 > > This part is fine. > > > -- > ldv Thank you I will submit v2 of the patch to address all the issues that you mention. I would like to also write a test, but I am not quite sure how to approach it. Am I correct that the statfs tests are in tests/xstatfsx.c but that the mount flags are not explicitly tested? Could the flags be tested by making some additional calls to print_statfs with bogus filesystems mounted in different ways as in tests/mount.c? Finally, would you prefer that I send the patch with the new constant separately from any test patch? Deb From ldv at altlinux.org Sun Mar 28 00:41:35 2021 From: ldv at altlinux.org (Dmitry V. Levin) Date: Sun, 28 Mar 2021 03:41:35 +0300 Subject: [PATCH] xlat: update ST_NOSYMFOLLOW constant In-Reply-To: <20210327041610.GA31634@djbComp> References: <20210325042629.GA4418@djbComp> <20210326005223.GB22197@altlinux.org> <20210327041610.GA31634@djbComp> Message-ID: <20210328004135.GA20963@altlinux.org> On Fri, Mar 26, 2021 at 09:16:11PM -0700, deborah brouwer wrote: [...] > Thank you I will submit v2 of the patch to address all the issues that you mention. > I would like to also write a test, but I am not quite sure how to approach it. > Am I correct that the statfs tests are in tests/xstatfsx.c but that the mount flags > are not explicitly tested? Yes, all tests of statfs family syscalls use tests/xstatfsx.c, they do not try to test printing of any specific ST_* flag. > Could the flags be tested by making some additional calls > to print_statfs with bogus filesystems mounted in different ways as in tests/mount.c? To test src/print_statfs.c with arbitrary statfs data, one has to tamper with a syscall from statfs family. We have tests that use syscall tampering, they are usually called tests/*success.* because they use a form of syscall tampering that's called success injection. > Finally, would you prefer that I send the patch with the new constant separately > from any test patch? Since the new constant doesn't break any existing tests, it's up to you. In this particular case I'd go for a separate patch because it's rather simple and almost ready. -- ldv From 3563deb6753 at gmail.com Sun Mar 28 03:38:47 2021 From: 3563deb6753 at gmail.com (Deborah Brouwer) Date: Sat, 27 Mar 2021 20:38:47 -0700 Subject: [PATCH v2] xlat: update ST_* constants Message-ID: <20210328033842.GA27249@djbComp> * scr/xlat/statfs_flags.in (ST_NOSYMFOLLOW): New constant introduced by Linux kernel commit v5.10-rc1~19^2~9. * NEWS: Mention this change. Signed-off-by: Deborah Brouwer <3563deb6753 at gmail.com> --- Changes since v1: Revised commit message for accuracy. Put change in NEWS file. NEWS | 1 + src/xlat/statfs_flags.in | 1 + 2 files changed, 2 insertions(+) diff --git a/NEWS b/NEWS index 84fd944d..567dab85 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,7 @@ Noteworthy changes in release ?.?? (????-??-??) =============================================== * Improvements + * Updated list of ST_* constants. * Bug fixes * Fixed build using bionic libc. diff --git a/src/xlat/statfs_flags.in b/src/xlat/statfs_flags.in index f791a60e..90a06138 100644 --- a/src/xlat/statfs_flags.in +++ b/src/xlat/statfs_flags.in @@ -8,3 +8,4 @@ ST_MANDLOCK 0x0040 ST_NOATIME 0x0400 ST_NODIRATIME 0x0800 ST_RELATIME 0x1000 +ST_NOSYMFOLLOW 0x2000 -- 2.17.1 From ldv at altlinux.org Mon Mar 29 00:50:16 2021 From: ldv at altlinux.org (Dmitry V. Levin) Date: Mon, 29 Mar 2021 03:50:16 +0300 Subject: Proposing SELinux support in strace In-Reply-To: <814989de-7ebc-4e56-524f-399991663591@redhat.com> References: <20210315011000.GA3123@altlinux.org> <2a0ba13b-620c-0bf6-11c7-c123947f0050@redhat.com> <20210316013026.GA21789@altlinux.org> <42e45004-46c6-01cd-9df1-77a42799ffe9@redhat.com> <20210325024501.GA7333@altlinux.org> <20210326010742.GC22197@altlinux.org> <814989de-7ebc-4e56-524f-399991663591@redhat.com> Message-ID: <20210329005013.GB3621@altlinux.org> On Fri, Mar 26, 2021 at 10:16:27AM +0100, Renaud M?trich wrote: > Thanks, fixed. I additionally handled the buffer too small case, just in > case ... > > I didn't merge de commits yet, to keep track of changes, will do once > ready to merge. Thanks. There are several style issues, see below. [...] diff --git a/tests/access--secontext.c b/tests/access--secontext.c new file mode 100644 index 000000000..01fd12e35 --- /dev/null +++ b/tests/access--secontext.c @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2021 The strace developers. + * All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "tests.h" + +#define TEST_SECONTEXT + +#ifndef HAVE_SELINUX_RUNTIME + +SKIP_MAIN_UNDEFINED("HAVE_SELINUX_RUNTIME") + +#else + +#include "access.c" + +#endif There are several minor style issues here (and in other similar files), I'd prefer if it was written this way: #include "tests.h" #ifdef HAVE_SELINUX_RUNTIME # define TEST_SECONTEXT # include "access.c" #else SKIP_MAIN_UNDEFINED("HAVE_SELINUX_RUNTIME") #endif [...] diff --git a/tests/dirfd.c b/tests/dirfd.c new file mode 100644 index 000000000..517ddea0c --- /dev/null +++ b/tests/dirfd.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2021 The strace developers. + * All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "tests.h" + +#include +#include +#include I don't think we need to include explicitly here. Note that in man-pages-5.11 a lot of redundant were removed. +#include + +#include "xmalloc.h" + +int +get_dir_fd(const char *dir_path) +{ + DIR *dir = NULL; + dir = opendir(dir_path); Let's merge the last two lines. + if (dir == NULL) + perror_msg_and_fail("opendir"); Let's mention dir_path in the diagnostics. + int dfd = dirfd(dir); + if (dfd == -1) + perror_msg_and_fail("dirfd"); + return dfd; +} + +int +get_curdir_fd(char **curdir) +{ + int res = get_dir_fd("."); + + if (curdir != NULL) { + char *buf = xmalloc(PATH_MAX); + ssize_t n = readlink("/proc/self/cwd", buf, PATH_MAX); + if (n == -1) + perror_msg_and_skip("/proc is not available"); Let's change the last line to perror_msg_and_skip("readlink: %s", "/proc/self/cwd"); + if (n >= PATH_MAX) + perror_msg_and_fail("buffer is too small"); There is no errno defined in this case so perror_* is not suitable, let's change the last line to error_msg_and_fail("readlink: %s: %s", "/proc/self/cwd", "symlink value is too long"); [...] diff --git a/tests/execve--secontext.c.old b/tests/execve--secontext.c.old new file mode 100644 index 000000000..64c34c7b9 --- /dev/null +++ b/tests/execve--secontext.c.old @@ -0,0 +1,42 @@ This looks as a something unintended. diff --git a/tests/execve--secontext.test b/tests/execve--secontext.test new file mode 100755 index 000000000..14c9f33de --- /dev/null +++ b/tests/execve--secontext.test @@ -0,0 +1,18 @@ +#!/bin/sh +# +# Check execve syscall decoding. +# +# Copyright (c) 2021 The strace developers. +# All rights reserved. +# +# SPDX-License-Identifier: GPL-2.0-or-later + +. "${srcdir=.}/init.sh" + +check_prog grep +run_prog > /dev/null +run_strace --secontext -eexecve $args > "$EXP" + +# Filter out execve() call made by strace. +grep -F test.execve < "$LOG" > "$OUT" +match_diff "$OUT" "$EXP" This looks very similar to tests/execve.test, could you parametrize it instead, see e.g. tests/ioctl.test as an example. diff --git a/tests/execve--secontext_full.test b/tests/execve--secontext_full.test new file mode 100755 index 000000000..4f5ac8c54 --- /dev/null +++ b/tests/execve--secontext_full.test @@ -0,0 +1,18 @@ +#!/bin/sh +# +# Check execve syscall decoding. +# +# Copyright (c) 2021 The strace developers. +# All rights reserved. +# +# SPDX-License-Identifier: GPL-2.0-or-later + +. "${srcdir=.}/init.sh" + +check_prog grep +run_prog > /dev/null +run_strace --secontext=full -eexecve $args > "$EXP" + +# Filter out execve() call made by strace. +grep -F test.execve < "$LOG" > "$OUT" +match_diff "$OUT" "$EXP" Likewise. -- ldv From deepanshu1422 at gmail.com Sun Mar 28 11:00:53 2021 From: deepanshu1422 at gmail.com (Deepanshu Udhwani) Date: Sun, 28 Mar 2021 16:30:53 +0530 Subject: [GSOC] : Comprehensive test Suite Message-ID: Hello Community, I am *Deepanshu Udhwani* , a final year *Master's student *at Thapar Institute Of Engineering And technology , Patiala (INDIA) . Previously I have worked as a *Kernel Development Intern *with *Alibaba Cloud * where I worked on* adding support of io_uring *to handle buffers in *PostgreSQL I/O *system calls and successfully enhanced its I/O rate on kernel v5.5 on AliyunLinux by more than 5.2%. > https://www.linkedin.com/in/deepanshu-udhwani/ https://github.com/deepanshu1422 I have used *STRACE* extensively as an end user and would love to help the community to develop it even better. Dear Maintainers, I have started working on the micro project that participants need to submit as a prerequisite to join this program and will complete the task as soon as possible. There are *few doubts *that I have in my mind and would like to clear them up - Can I submit my proposal here first, before submitting on GSOC website in order to get a review and detail it better? - Can my proposal include hyper-links / images or does it need to be *plain text *? *Thanks and Regards* *Deepanshu Udhwani* -------------- next part -------------- An HTML attachment was scrubbed... URL: From ldv at altlinux.org Mon Mar 29 10:52:27 2021 From: ldv at altlinux.org (Dmitry V. Levin) Date: Mon, 29 Mar 2021 13:52:27 +0300 Subject: [PATCH v2] xlat: update ST_* constants In-Reply-To: <20210328033842.GA27249@djbComp> References: <20210328033842.GA27249@djbComp> Message-ID: <20210329105227.GB11628@altlinux.org> On Sat, Mar 27, 2021 at 08:38:47PM -0700, Deborah Brouwer wrote: > * scr/xlat/statfs_flags.in (ST_NOSYMFOLLOW): New constant introduced by > Linux kernel commit v5.10-rc1~19^2~9. > * NEWS: Mention this change. > > Signed-off-by: Deborah Brouwer <3563deb6753 at gmail.com> > --- > Changes since v1: > Revised commit message for accuracy. > Put change in NEWS file. > > NEWS | 1 + > src/xlat/statfs_flags.in | 1 + > 2 files changed, 2 insertions(+) > > diff --git a/NEWS b/NEWS > index 84fd944d..567dab85 100644 > --- a/NEWS > +++ b/NEWS > @@ -2,6 +2,7 @@ Noteworthy changes in release ?.?? (????-??-??) > =============================================== > > * Improvements > + * Updated list of ST_* constants. > > * Bug fixes > * Fixed build using bionic libc. > diff --git a/src/xlat/statfs_flags.in b/src/xlat/statfs_flags.in > index f791a60e..90a06138 100644 > --- a/src/xlat/statfs_flags.in > +++ b/src/xlat/statfs_flags.in > @@ -8,3 +8,4 @@ ST_MANDLOCK 0x0040 > ST_NOATIME 0x0400 > ST_NODIRATIME 0x0800 > ST_RELATIME 0x1000 > +ST_NOSYMFOLLOW 0x2000 Merged, thanks! -- ldv From rmetrich at redhat.com Mon Mar 29 15:36:42 2021 From: rmetrich at redhat.com (=?UTF-8?Q?Renaud_M=c3=a9trich?=) Date: Mon, 29 Mar 2021 17:36:42 +0200 Subject: Proposing SELinux support in strace In-Reply-To: <20210329005013.GB3621@altlinux.org> References: <20210315011000.GA3123@altlinux.org> <2a0ba13b-620c-0bf6-11c7-c123947f0050@redhat.com> <20210316013026.GA21789@altlinux.org> <42e45004-46c6-01cd-9df1-77a42799ffe9@redhat.com> <20210325024501.GA7333@altlinux.org> <20210326010742.GC22197@altlinux.org> <814989de-7ebc-4e56-524f-399991663591@redhat.com> <20210329005013.GB3621@altlinux.org> Message-ID: Thanks, all fixed, PR updated accordindly. I introduced stripping of trailing newlines in the context (see selinux.c), after digging into a CI issue for a few hours: for some reason, on the CI, the context for processes (there is no file contexts at all) have a trailing "\n" (actually it's "unconfined\n")! I think it's safe to keep this stripping in the normal code, just in case, that would avoid unintended newlines in strace output. Renaud. On 3/29/21 2:50 AM, Dmitry V. Levin wrote: > On Fri, Mar 26, 2021 at 10:16:27AM +0100, Renaud M?trich wrote: >> Thanks, fixed. I additionally handled the buffer too small case, just in >> case ... >> >> I didn't merge de commits yet, to keep track of changes, will do once >> ready to merge. > Thanks. There are several style issues, see below. > > [...] > diff --git a/tests/access--secontext.c b/tests/access--secontext.c > new file mode 100644 > index 000000000..01fd12e35 > --- /dev/null > +++ b/tests/access--secontext.c > @@ -0,0 +1,20 @@ > +/* > + * Copyright (c) 2021 The strace developers. > + * All rights reserved. > + * > + * SPDX-License-Identifier: GPL-2.0-or-later > + */ > + > +#include "tests.h" > + > +#define TEST_SECONTEXT > + > +#ifndef HAVE_SELINUX_RUNTIME > + > +SKIP_MAIN_UNDEFINED("HAVE_SELINUX_RUNTIME") > + > +#else > + > +#include "access.c" > + > +#endif > > There are several minor style issues here (and in other similar files), > I'd prefer if it was written this way: > > #include "tests.h" > > #ifdef HAVE_SELINUX_RUNTIME > > # define TEST_SECONTEXT > # include "access.c" > > #else > > SKIP_MAIN_UNDEFINED("HAVE_SELINUX_RUNTIME") > > #endif > > [...] > diff --git a/tests/dirfd.c b/tests/dirfd.c > new file mode 100644 > index 000000000..517ddea0c > --- /dev/null > +++ b/tests/dirfd.c > @@ -0,0 +1,47 @@ > +/* > + * Copyright (c) 2021 The strace developers. > + * All rights reserved. > + * > + * SPDX-License-Identifier: GPL-2.0-or-later > + */ > + > +#include "tests.h" > + > +#include > +#include > +#include > > I don't think we need to include explicitly here. > Note that in man-pages-5.11 a lot of redundant were removed. > > +#include > + > +#include "xmalloc.h" > + > +int > +get_dir_fd(const char *dir_path) > +{ > + DIR *dir = NULL; > + dir = opendir(dir_path); > > Let's merge the last two lines. > > + if (dir == NULL) > + perror_msg_and_fail("opendir"); > > Let's mention dir_path in the diagnostics. > > + int dfd = dirfd(dir); > + if (dfd == -1) > + perror_msg_and_fail("dirfd"); > + return dfd; > +} > + > +int > +get_curdir_fd(char **curdir) > +{ > + int res = get_dir_fd("."); > + > + if (curdir != NULL) { > + char *buf = xmalloc(PATH_MAX); > + ssize_t n = readlink("/proc/self/cwd", buf, PATH_MAX); > + if (n == -1) > + perror_msg_and_skip("/proc is not available"); > > Let's change the last line to > perror_msg_and_skip("readlink: %s", "/proc/self/cwd"); > > + if (n >= PATH_MAX) > + perror_msg_and_fail("buffer is too small"); > > There is no errno defined in this case so perror_* is not suitable, > let's change the last line to > error_msg_and_fail("readlink: %s: %s", > "/proc/self/cwd", > "symlink value is too long"); > > [...] > diff --git a/tests/execve--secontext.c.old b/tests/execve--secontext.c.old > new file mode 100644 > index 000000000..64c34c7b9 > --- /dev/null > +++ b/tests/execve--secontext.c.old > @@ -0,0 +1,42 @@ > > This looks as a something unintended. > > diff --git a/tests/execve--secontext.test b/tests/execve--secontext.test > new file mode 100755 > index 000000000..14c9f33de > --- /dev/null > +++ b/tests/execve--secontext.test > @@ -0,0 +1,18 @@ > +#!/bin/sh > +# > +# Check execve syscall decoding. > +# > +# Copyright (c) 2021 The strace developers. > +# All rights reserved. > +# > +# SPDX-License-Identifier: GPL-2.0-or-later > + > +. "${srcdir=.}/init.sh" > + > +check_prog grep > +run_prog > /dev/null > +run_strace --secontext -eexecve $args > "$EXP" > + > +# Filter out execve() call made by strace. > +grep -F test.execve < "$LOG" > "$OUT" > +match_diff "$OUT" "$EXP" > > This looks very similar to tests/execve.test, could you parametrize it > instead, see e.g. tests/ioctl.test as an example. > > diff --git a/tests/execve--secontext_full.test b/tests/execve--secontext_full.test > new file mode 100755 > index 000000000..4f5ac8c54 > --- /dev/null > +++ b/tests/execve--secontext_full.test > @@ -0,0 +1,18 @@ > +#!/bin/sh > +# > +# Check execve syscall decoding. > +# > +# Copyright (c) 2021 The strace developers. > +# All rights reserved. > +# > +# SPDX-License-Identifier: GPL-2.0-or-later > + > +. "${srcdir=.}/init.sh" > + > +check_prog grep > +run_prog > /dev/null > +run_strace --secontext=full -eexecve $args > "$EXP" > + > +# Filter out execve() call made by strace. > +grep -F test.execve < "$LOG" > "$OUT" > +match_diff "$OUT" "$EXP" > > Likewise. > > -------------- next part -------------- A non-text attachment was scrubbed... Name: OpenPGP_signature Type: application/pgp-signature Size: 840 bytes Desc: OpenPGP digital signature URL: From notifications at github.com Mon Mar 29 08:47:03 2021 From: notifications at github.com (Chris Packham) Date: Mon, 29 Mar 2021 01:47:03 -0700 Subject: [strace/strace] Error building against musl libc - error: "__UAPI_DEF_IN6_ADDR_ALT" redefined (#177) Message-ID: Hi, I'm trying to update crosstool-ng to include a newer strace version (current version supported is 5.8). When building against musl libc I strike this error ``` [ALL ] In file included from /home/x-tool/.build/arm-unknown-linux-musleabi/src/strace/bundled/linux/include/uapi/linux/in6.h:26, [ALL ] from /home/x-tool/.build/arm-unknown-linux-musleabi/src/strace/bundled/linux/include/uapi/linux/if_bridge.h:19, [ALL ] from /home/x-tool/.build/arm-unknown-linux-musleabi/src/strace/src/rtnl_mdb.c:16: [ERROR] /home/x-tool/.build/arm-unknown-linux-musleabi/src/strace/bundled/linux/include/uapi/linux/libc-compat.h:109: error: "__UAPI_DEF_IN6_ADDR_ALT" redefined [-Werror] [ALL ] 109 | #define __UAPI_DEF_IN6_ADDR_ALT 1 [ALL ] | [ALL ] In file included from /home/x-tool/.build/arm-unknown-linux-musleabi/src/strace/src/rtnl_mdb.c:15: [ALL ] /home/x-tool/x-tools/arm-unknown-linux-musleabi/arm-unknown-linux-musleabi/sysroot/usr/include/netinet/in.h:401: note: this is the location of the previous definition [ALL ] 401 | #define __UAPI_DEF_IN6_ADDR_ALT 0 [ALL ] | [ALL ] cc1: all warnings being treated as errors [ERROR] make[4]: *** [Makefile:6660: libstrace_a-rtnl_mdb.o] Error 1 [ALL ] make[4]: Leaving directory '/home/x-tool/.build/arm-unknown-linux-musleabi/build/build-strace/src' [ERROR] make[3]: *** [Makefile:2404: all] Error 2 [ALL ] rm ioctlsort0.o ioctls_all0.h ioctlsort0 [ALL ] make[3]: Leaving directory '/home/x-tool/.build/arm-unknown-linux-musleabi/build/build-strace/src' [ERROR] make[2]: *** [Makefile:601: all-recursive] Error 1 [ALL ] make[2]: Leaving directory '/home/x-tool/.build/arm-unknown-linux-musleabi/build/build-strace' [ERROR] make[1]: *** [Makefile:506: all] Error 2 [ALL ] make[1]: Leaving directory '/home/x-tool/.build/arm-unknown-linux-musleabi/build/build-strace' ``` any suggestions? -- You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub: https://github.com/strace/strace/issues/177 -------------- next part -------------- An HTML attachment was scrubbed... URL: From notifications at github.com Mon Mar 29 10:27:39 2021 From: notifications at github.com (Dmitry V. Levin) Date: Mon, 29 Mar 2021 03:27:39 -0700 Subject: [strace/strace] Error building against musl libc - error: "__UAPI_DEF_IN6_ADDR_ALT" redefined (#177) In-Reply-To: References: Message-ID: This seems to be something specific to musl. -- You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub: https://github.com/strace/strace/issues/177#issuecomment-809267575 -------------- next part -------------- An HTML attachment was scrubbed... URL: From notifications at github.com Mon Mar 29 21:53:51 2021 From: notifications at github.com (Chris Packham) Date: Mon, 29 Mar 2021 14:53:51 -0700 Subject: [strace/strace] Error building against musl libc - error: "__UAPI_DEF_IN6_ADDR_ALT" redefined (#177) In-Reply-To: References: Message-ID: Yes it is specific to musl. Musl defines some of the __UAPI flags in [in.h](https://git.musl-libc.org/cgit/musl/tree/include/netinet/in.h#n397) which causes problems with versions of strace that include the bundled uapi headers (basically v5.10-272-g5bd8364f4 onward). It looks like there's some attempt in the headers to coordinate with `_NETINET_IN_H`, `__USE_MISC` and `__USE_GNU` but I guess the order of includes might defeat this. -- You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub: https://github.com/strace/strace/issues/177#issuecomment-809738863 -------------- next part -------------- An HTML attachment was scrubbed... URL: From notifications at github.com Mon Mar 29 22:04:40 2021 From: notifications at github.com (Dmitry V. Levin) Date: Mon, 29 Mar 2021 15:04:40 -0700 Subject: [strace/strace] Error building against musl libc - error: "__UAPI_DEF_IN6_ADDR_ALT" redefined (#177) In-Reply-To: References: Message-ID: The order of includes is correct: ``` #include #include ``` The idea was to let `` define `__UAPI_DEF_`* macros and let `` define appropriate types depending on these `__UAPI_DEF_`* definitions. Unfortunately, it looks like the attempt to coordinate between glibc, musl, and linux has failed with ``. -- You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub: https://github.com/strace/strace/issues/177#issuecomment-809743768 -------------- next part -------------- An HTML attachment was scrubbed... URL: From notifications at github.com Mon Mar 29 16:45:07 2021 From: notifications at github.com (Igor Zhbanov) Date: Mon, 29 Mar 2021 09:45:07 -0700 Subject: [strace/strace] Feature request: Allow process detaching after N lines captured (#179) Message-ID: It could be useful in automatic tests scenarious to attach to some daemon process, make some action, and detach after e.g. 1000 syscalls gets captured. Also it could be useful to detach after 10 seconds. -- You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub: https://github.com/strace/strace/issues/179 -------------- next part -------------- An HTML attachment was scrubbed... URL: From notifications at github.com Mon Mar 29 16:45:55 2021 From: notifications at github.com (Igor Zhbanov) Date: Mon, 29 Mar 2021 09:45:55 -0700 Subject: [strace/strace] Feature request: Allow process detaching after N syscalls captured (#179) In-Reply-To: References: Message-ID: When atteching to several process the limit on the captured lines could be imposed on the total syscalls number for the simplicity. -- You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub: https://github.com/strace/strace/issues/179#issuecomment-809535709 -------------- next part -------------- An HTML attachment was scrubbed... URL: From notifications at github.com Mon Mar 29 22:06:42 2021 From: notifications at github.com (Chris Packham) Date: Mon, 29 Mar 2021 15:06:42 -0700 Subject: [strace/strace] Error building against musl libc - error: "__UAPI_DEF_IN6_ADDR_ALT" redefined (#177) In-Reply-To: References: Message-ID: I think it may be because musl doesn't define __USE_MISC or __USE_GNU so __UAPI_DEF_IN6_ADDR_ALT ends up 1 instead of 0. -- You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub: https://github.com/strace/strace/issues/177#issuecomment-809744652 -------------- next part -------------- An HTML attachment was scrubbed... URL: From notifications at github.com Mon Mar 29 22:14:32 2021 From: notifications at github.com (Chris Packham) Date: Mon, 29 Mar 2021 15:14:32 -0700 Subject: [strace/strace] Error building against musl libc - error: "__UAPI_DEF_IN6_ADDR_ALT" redefined (#177) In-Reply-To: References: Message-ID: We already have a bit of a trick for [strace+musl](https://github.com/crosstool-ng/crosstool-ng/blob/master/scripts/build/debug/500-strace.sh#L19) so perhaps updating that will suffice. -- You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub: https://github.com/strace/strace/issues/177#issuecomment-809748063 -------------- next part -------------- An HTML attachment was scrubbed... URL: From notifications at github.com Mon Mar 29 22:20:10 2021 From: notifications at github.com (Dmitry V. Levin) Date: Mon, 29 Mar 2021 15:20:10 -0700 Subject: [strace/strace] Error building against musl libc - error: "__UAPI_DEF_IN6_ADDR_ALT" redefined (#177) In-Reply-To: References: Message-ID: That's awful. Could you bring the issue to attention of linux uapi and musl developers, please? -- You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub: https://github.com/strace/strace/issues/177#issuecomment-809750632 -------------- next part -------------- An HTML attachment was scrubbed... URL: From notifications at github.com Mon Mar 29 15:59:17 2021 From: notifications at github.com (Igor Zhbanov) Date: Mon, 29 Mar 2021 08:59:17 -0700 Subject: [strace/strace] Strace should prevent a process under tracing to attach to the strace itself (#178) Message-ID: There is a problem when mutual debugging of 2 processes can stuck in unkillable stopped state. When one process, let's say "A", is tracing the another process "B", and the process "B" is trying to attach to the process "A", then both of them are getting stuck in the "t+" state. And they are ignoring all of the signals including the SIGKILL, so it is not possible to terminate them without a reboot. To reproduce: 1) Open two terminals. 2) Attach with `strace -p ...` from the first terminal to the shell (bash) of the second terminal. 3) In the second terminal run `exec strace -p ...` to attach to the PID of the first strace. Then you'll see that the second strace is hanging without any output. And the first strace will output following and hang too: ``` ptrace(PTRACE_SEIZE, 11795, NULL, PTRACE_O_TRACESYSGOOD|PTRACE_O_TRACEEXEC|PTRACE_O_TRACEEXIT ``` (The 11795 is the PID of the first strace itself.) And in the process list you will see following: ``` ps awux | grep strace user 11776 0.0 0.0 24752 2248 pts/3 t+ 13:53 0:00 strace -p 11795 user 11795 0.0 0.0 24752 3888 pts/1 t+ 13:54 0:00 strace -p 11776 ``` I've sent a letter to linux-trace-devel mailing list. But the strace itself is able to forbid to attaching to itself, at least when it sees such an attempt. -- You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub: https://github.com/strace/strace/issues/178 -------------- next part -------------- An HTML attachment was scrubbed... URL: From notifications at github.com Mon Mar 29 16:02:13 2021 From: notifications at github.com (Igor Zhbanov) Date: Mon, 29 Mar 2021 09:02:13 -0700 Subject: [strace/strace] Strace should prevent a process under tracing to attach to the strace itself (#178) In-Reply-To: References: Message-ID: Although, of course, the chain of the processes could be longer: `A`->`B`, `B`->`C`, `C`->`A`. -- You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub: https://github.com/strace/strace/issues/178#issuecomment-809504849 -------------- next part -------------- An HTML attachment was scrubbed... URL: From notifications at github.com Mon Mar 29 16:20:03 2021 From: notifications at github.com (Dmitry V. Levin) Date: Mon, 29 Mar 2021 09:20:03 -0700 Subject: [strace/strace] Strace should prevent a process under tracing to attach to the strace itself (#178) In-Reply-To: References: Message-ID: Looks like strace is not the right place to break this loop. Better workarounds are available, e.g. one can enable restricted ptrace by setting /proc/sys/kernel/yama to 1, or clear dumpable bit of the strace that shouldn't be ptraced. -- You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub: https://github.com/strace/strace/issues/178#issuecomment-809518103 -------------- next part -------------- An HTML attachment was scrubbed... URL: From notifications at github.com Mon Mar 29 16:42:39 2021 From: notifications at github.com (Igor Zhbanov) Date: Mon, 29 Mar 2021 09:42:39 -0700 Subject: [strace/strace] Strace should prevent a process under tracing to attach to the strace itself (#178) In-Reply-To: References: Message-ID: Let's see what kenel developers will say: https://lore.kernel.org/linux-trace-devel/f2f32ffa-52ad-ff67-19d8-95305a70a6f8 at omprussia.ru/T/#u -- You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub: https://github.com/strace/strace/issues/178#issuecomment-809533658 -------------- next part -------------- An HTML attachment was scrubbed... URL: From notifications at github.com Mon Mar 29 16:47:49 2021 From: notifications at github.com (Igor Zhbanov) Date: Mon, 29 Mar 2021 09:47:49 -0700 Subject: [strace/strace] Strace should prevent a process under tracing to attach to the strace itself (#178) In-Reply-To: References: Message-ID: But strace could at least break `A` -> `B` -> `A` cycle easily. -- You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub: https://github.com/strace/strace/issues/178#issuecomment-809536983 -------------- next part -------------- An HTML attachment was scrubbed... URL: From notifications at github.com Mon Mar 29 22:23:25 2021 From: notifications at github.com (Chris Packham) Date: Mon, 29 Mar 2021 15:23:25 -0700 Subject: [strace/strace] Error building against musl libc - error: "__UAPI_DEF_IN6_ADDR_ALT" redefined (#177) In-Reply-To: References: Message-ID: I'll try. -- You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub: https://github.com/strace/strace/issues/177#issuecomment-809752219 -------------- next part -------------- An HTML attachment was scrubbed... URL: From ldv at altlinux.org Tue Mar 30 00:27:02 2021 From: ldv at altlinux.org (Dmitry V. Levin) Date: Tue, 30 Mar 2021 03:27:02 +0300 Subject: [GSOC] : Comprehensive test Suite In-Reply-To: References: Message-ID: <20210330002702.GA20907@altlinux.org> Hi, On Sun, Mar 28, 2021 at 04:30:53PM +0530, Deepanshu Udhwani wrote: [...] > I have used *STRACE* extensively as an end user and would love to help the > community to develop it even better. Thank you for showing your interest in contributing to the strace project. > Dear Maintainers, > I have started working on the micro project that participants need to > submit as a prerequisite to join this program and will complete the task > as soon as possible. > > There are *few doubts *that I have in my mind and would like to clear them > up > > > - Can I submit my proposal here first, before submitting on GSOC website > in order to get a review and detail it better? It's preferable to submit your proposal here first, submitting it to the GSoC website would take us more time for review and make the actual review process slower. > - Can my proposal include hyper-links / images or does it need to be *plain > text *? The proposal has to be self-contained, but of course it may contain references to other projects. Plain text is preferable but not mandatory, the GSoC rules require the final edition to be in pdf anyway. -- ldv From ldv at altlinux.org Tue Mar 30 01:04:39 2021 From: ldv at altlinux.org (Dmitry V. Levin) Date: Tue, 30 Mar 2021 04:04:39 +0300 Subject: GSoC 2021: student application period begins Message-ID: <20210330010439.GB20907@altlinux.org> Hi, This is a friendly reminder that strace is taking part in the GSoC 2021 as a mentor organization, and the student application period has started. Students ======== As this period ends in two weeks which is not that far, students are encouraged to start discussing their application proposals early rather than late. Mentors ======= We need a few more volunteer mentors to coach and guide each of these few students as they contribute to strace. Would you volunteer? -- ldv From ldv at altlinux.org Tue Mar 30 01:47:59 2021 From: ldv at altlinux.org (Dmitry V. Levin) Date: Tue, 30 Mar 2021 04:47:59 +0300 Subject: Proposing SELinux support in strace In-Reply-To: References: <20210315011000.GA3123@altlinux.org> <2a0ba13b-620c-0bf6-11c7-c123947f0050@redhat.com> <20210316013026.GA21789@altlinux.org> <42e45004-46c6-01cd-9df1-77a42799ffe9@redhat.com> <20210325024501.GA7333@altlinux.org> <20210326010742.GC22197@altlinux.org> <814989de-7ebc-4e56-524f-399991663591@redhat.com> <20210329005013.GB3621@altlinux.org> Message-ID: <20210330014759.GA22109@altlinux.org> On Mon, Mar 29, 2021 at 05:36:42PM +0200, Renaud M?trich wrote: > Thanks, all fixed, PR updated accordindly. > > I introduced stripping of trailing newlines in the context (see > selinux.c), after digging into a CI issue for a few hours: > > for some reason, on the CI, the context for processes (there is no file > contexts at all) have a trailing "\n" (actually it's "unconfined\n")! > > I think it's safe to keep this stripping in the normal code, just in > case, that would avoid unintended newlines in strace output. I also think it's OK. Here is the next bunch of comments. [...] > + if (*result == NULL) { > + char *res = xstrdup(*secontext); > + /* > + * On the CI at least, the context may have a trailing \n, > + * let's remove it just in case > + */ > + int index; > + for (index = strlen(res) - 1; index >= 0; index--) { > + if (res[index] != '\n') > + break; > + res[index] = '\0'; > + } > + *result = res; I don't feel comfortable with assigning the result of strlen(arbitrary string) to a variable of type int. How about this: size_t len = strlen(*secontext); for (; len > 0; --len) { if ((*secontext)[len - 1] != '\n') break; } *result = xstrndup(*secontext, len); [...] > diff --git a/tests/access.c b/tests/access.c > index 8bdbb6265..b864993f5 100644 > --- a/tests/access.c > +++ b/tests/access.c > @@ -1,5 +1,5 @@ > /* > - * Copyright (c) 2016-2019 The strace developers. > + * Copyright (c) 2016-2021 The strace developers. > * All rights reserved. > * > * SPDX-License-Identifier: GPL-2.0-or-later > @@ -10,21 +10,36 @@ > > #ifdef __NR_access > > -# include > -# include > +#include > +#include > +#include > + > +#include "selinux.c" We don't just prefer to indent preprocessor directives, we actually fix preprocessor indentation before the release, see e.g. commit v5.11~2. Could you bring the indentation back, please? > diff --git a/tests/faccessat.test b/tests/faccessat.test > index 83f94ba40..2df711d3b 100755 > --- a/tests/faccessat.test > +++ b/tests/faccessat.test > @@ -14,6 +14,8 @@ check_prog sed > run_prog > /dev/null > run_strace -a23 --trace=faccessat "$@" $args > "$EXP" > > -# Filter out faccessat() calls made by ld.so and libc. > -sed -n '/^faccessat(-1, NULL,/,$p' < "$LOG" > "$OUT" > -match_diff "$OUT" "$EXP" > +# Removed this filtering since it breaks when enabling --secontext. > +# It looks like it's due to having square brackets in the lines ... > +## Filter out faccessat() calls made by ld.so and libc. > +#sed -n '/faccessat(-1, NULL,/,$p' < "$LOG" > "$OUT" > +match_diff "$LOG" "$EXP" Sorry but this doesn't work properly: there are architectures like aarch64 that don't have access() syscall so glibc uses faccessat() there instead. As result, all tests based on this faccessat.test fail on aarch64, e.g. FAIL: faccessat [...] --- exp 2021-03-30 01:08:37.645513400 +0000 +++ log 2021-03-30 01:08:37.645513400 +0000 @@ -1,3 +1,4 @@ +faccessat(AT_FDCWD, "/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) faccessat(-1, NULL, F_OK) = -1 EFAULT (Bad address) faccessat(-1, NULL, R_OK) = -1 EFAULT (Bad address) faccessat(-1, NULL, W_OK) = -1 EFAULT (Bad address) -- ldv From notifications at github.com Tue Mar 30 20:46:38 2021 From: notifications at github.com (Sergei Trofimovich) Date: Tue, 30 Mar 2021 13:46:38 -0700 Subject: [strace/strace] strace fails to build on binutils-2.36 (readelf output change) (#180) Message-ID: ``` # this works: $ READELF=/usr/x86_64-pc-linux-gnu/binutils-bin/2.35.2/readelf ./configure #this fails: $ READELF=/usr/x86_64-pc-linux-gnu/binutils-bin/2.36.1/readelf ./configure ... checking for m32 personality compile support (using x86_64-pc-linux-gnu-gcc -I./bundled/linux/arch/x86/include/uapi -I./bundled/linux/include/uapi -m32)... yes checking for m32 personality runtime support... yes checking whether mpers.sh m32 -m32 works... mpers-m32/sample_struct.d2: index [ ] without special no checking whether to enable m32 personality support... no configure: error: Cannot enable m32 personality support ``` Looking at the diff of `mpers-m32/sample_struct.d1` of lod and new readelf now provides a bit of extra info: ``` $ head -n 20 mpers-m32/sample_struct.d1_2.35.2 Contents of the .debug_info section: Compilation Unit @ offset 0x0: Length: 0x39c (32-bit) Version: 2 Abbrev Offset: 0x0 Pointer Size: 4 <0>: Abbrev Number: 1 (DW_TAG_compile_unit) DW_AT_producer : (indirect string, offset: 0x61): GNU C17 11.0.1 20210314 (experimental) -m32 -mtune=generic -march=x86-64 -gdwarf-2 <10> DW_AT_language : 12 (ANSI C99) <11> DW_AT_name : (indirect string, offset: 0x174): mpers-m32/sample_struct.c <15> DW_AT_comp_dir : (indirect string, offset: 0x3e): /home/slyfox/dev/git/strace <19> DW_AT_stmt_list : 0x0 <1><1d>: Abbrev Number: 2 (DW_TAG_base_type) <1e> DW_AT_byte_size : 1 <1f> DW_AT_encoding : 8 (unsigned char) <20> DW_AT_name : (indirect string, offset: 0xb4): unsigned char <1><24>: Abbrev Number: 2 (DW_TAG_base_type) <25> DW_AT_byte_size : 2 <26> DW_AT_encoding : 7 (unsigned) ``` ``` $ head -n 20 mpers-m32/sample_struct.d1_2.36.1 Contents of the .debug_info section: Compilation Unit @ offset 0x0: Length: 0x39c (32-bit) Version: 2 Abbrev Offset: 0x0 Pointer Size: 4 <0>: Abbrev Number: 1 (DW_TAG_compile_unit) DW_AT_producer : (strp) (offset: 0x61): GNU C17 11.0.1 20210314 (experimental) -m32 -mtune=generic -march=x86-64 -gdwarf-2 <10> DW_AT_language : (data1) 12 (ANSI C99) <11> DW_AT_name : (strp) (offset: 0x174): mpers-m32/sample_struct.c <15> DW_AT_comp_dir : (strp) (offset: 0x3e): /home/slyfox/dev/git/strace <19> DW_AT_stmt_list : (data4) 0x0 <1><1d>: Abbrev Number: 2 (DW_TAG_base_type) <1e> DW_AT_byte_size : (data1) 1 <1f> DW_AT_encoding : (data1) 8 (unsigned char) <20> DW_AT_name : (strp) (offset: 0xb4): unsigned char <1><24>: Abbrev Number: 2 (DW_TAG_base_type) <25> DW_AT_byte_size : (data1) 2 <26> DW_AT_encoding : (data1) 7 (unsigned) ``` Note the extra `data1`, `strp`, `indirect string` annotations. -- You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub: https://github.com/strace/strace/issues/180 -------------- next part -------------- An HTML attachment was scrubbed... URL: From notifications at github.com Tue Mar 30 21:31:51 2021 From: notifications at github.com (Dmitry V. Levin) Date: Tue, 30 Mar 2021 14:31:51 -0700 Subject: [strace/strace] strace fails to build on binutils-2.36 (readelf output change) (#180) In-Reply-To: References: Message-ID: This looks very similar to https://github.com/strace/strace/issues/171 -- You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub: https://github.com/strace/strace/issues/180#issuecomment-810591242 -------------- next part -------------- An HTML attachment was scrubbed... URL: