From 05ec9ee0f47d3b6ceb812475cce7c4f6972a04fc Mon Sep 17 00:00:00 2001 From: Nicolas Campuzano Jimenez Date: Wed, 15 Jan 2025 18:32:19 -0500 Subject: [PATCH 01/16] Initial lsof profile (+ comments) --- profiles/apparmor.d/lsof | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 profiles/apparmor.d/lsof diff --git a/profiles/apparmor.d/lsof b/profiles/apparmor.d/lsof new file mode 100644 index 000000000..9034cd475 --- /dev/null +++ b/profiles/apparmor.d/lsof @@ -0,0 +1,38 @@ +#------------------------------------------------------------------ +# Copyright (C) 2024 Canonical Ltd. +# +# Author: Nicolas Campuzano Jimenez +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of version 2 of the GNU General Public +# License published by the Free Software Foundation. +#------------------------------------------------------------------ +# vim: ft=apparmor +# + +abi , +include + +profile lsof /usr/bin/lsof { + include + + # Allow to read certain proc filesystem information + ptrace read, + + # Networking-related rules for address resolution + @{sys}/etc/host.conf r, + @{sys}/etc/hosts r, + @{sys}/etc/nsswitch.conf r, + @{sys}/etc/passwd r, + @{sys}/etc/services r, + @{run}/systemd/resolve/stub-resolv.conf r, + + # Access specific files (First wildcard matches PID + @{PROC}/*/stat r, # process-specific status info. + @{PROC}/*/task/ r, # info. about threads open by process + @{PROC}/*/fd/ r, # file descriptors in use by process + @{PROC}/*/fdinfo/* r, # further info. about file descriptors + @{PROC}/*/task/** r, # further info about threads open by process + +} + From 115ff87df731ddc66786120b68cc12172a35cd54 Mon Sep 17 00:00:00 2001 From: Nicolas Campuzano Jimenez Date: Thu, 16 Jan 2025 13:22:12 -0500 Subject: [PATCH 02/16] Address MR reviews; remove comments --- profiles/apparmor.d/lsof | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/profiles/apparmor.d/lsof b/profiles/apparmor.d/lsof index 9034cd475..7e9c67de5 100644 --- a/profiles/apparmor.d/lsof +++ b/profiles/apparmor.d/lsof @@ -1,5 +1,5 @@ #------------------------------------------------------------------ -# Copyright (C) 2024 Canonical Ltd. +# Copyright (C) 2025 Canonical Ltd. # # Author: Nicolas Campuzano Jimenez # @@ -15,24 +15,16 @@ include profile lsof /usr/bin/lsof { include + include - # Allow to read certain proc filesystem information ptrace read, - # Networking-related rules for address resolution - @{sys}/etc/host.conf r, - @{sys}/etc/hosts r, - @{sys}/etc/nsswitch.conf r, - @{sys}/etc/passwd r, - @{sys}/etc/services r, - @{run}/systemd/resolve/stub-resolv.conf r, - - # Access specific files (First wildcard matches PID - @{PROC}/*/stat r, # process-specific status info. - @{PROC}/*/task/ r, # info. about threads open by process - @{PROC}/*/fd/ r, # file descriptors in use by process - @{PROC}/*/fdinfo/* r, # further info. about file descriptors - @{PROC}/*/task/** r, # further info about threads open by process + @{PROC}/@{pid}/stat r, + @{PROC}/@{pid}/task/ r, + @{PROC}/@{pid}/fd/ r, + @{PROC}/@{pid}/fdinfo/* r, + @{PROC}/@{pid}/task/** r, + include if exists } From b50eb2d18e151db906015f43290d39d0fed966d1 Mon Sep 17 00:00:00 2001 From: Nicolas Campuzano Jimenez Date: Thu, 16 Jan 2025 14:12:01 -0500 Subject: [PATCH 03/16] more granularity for process's child threads --- profiles/apparmor.d/lsof | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/profiles/apparmor.d/lsof b/profiles/apparmor.d/lsof index 7e9c67de5..60cc6751c 100644 --- a/profiles/apparmor.d/lsof +++ b/profiles/apparmor.d/lsof @@ -23,7 +23,10 @@ profile lsof /usr/bin/lsof { @{PROC}/@{pid}/task/ r, @{PROC}/@{pid}/fd/ r, @{PROC}/@{pid}/fdinfo/* r, - @{PROC}/@{pid}/task/** r, + + @{PROC}/@{pid}/task/@{pid}/stat r, + @{PROC}/@{pid}/task/@{pid}/fd r, + @{PROC}/@{pid}/task/@{pid}/fdinfo/* r, include if exists } From 41a90d41772f588f671682f6db2b65611494eb5a Mon Sep 17 00:00:00 2001 From: Nicolas Campuzano Jimenez Date: Fri, 17 Jan 2025 15:52:25 -0500 Subject: [PATCH 04/16] address review; hopefully trigger CI run? --- profiles/apparmor.d/lsof | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/profiles/apparmor.d/lsof b/profiles/apparmor.d/lsof index 60cc6751c..b76e928e4 100644 --- a/profiles/apparmor.d/lsof +++ b/profiles/apparmor.d/lsof @@ -19,14 +19,14 @@ profile lsof /usr/bin/lsof { ptrace read, - @{PROC}/@{pid}/stat r, - @{PROC}/@{pid}/task/ r, - @{PROC}/@{pid}/fd/ r, - @{PROC}/@{pid}/fdinfo/* r, + @{PROC}/@{pids}/stat r, + @{PROC}/@{pids}/task/ r, + @{PROC}/@{pids}/fd/ r, + @{PROC}/@{pids}/fdinfo/* r, - @{PROC}/@{pid}/task/@{pid}/stat r, - @{PROC}/@{pid}/task/@{pid}/fd r, - @{PROC}/@{pid}/task/@{pid}/fdinfo/* r, + @{PROC}/@{pids}/task/@{tid}/stat r, + @{PROC}/@{pids}/task/@{tid}/fd r, + @{PROC}/@{pids}/task/@{tid}/fdinfo/* r, include if exists } From a8319dcf0c8d2412dd5a2cbef57f3dc1162f7b1d Mon Sep 17 00:00:00 2001 From: Nicolas Campuzano Jimenez Date: Fri, 17 Jan 2025 17:01:54 -0500 Subject: [PATCH 05/16] address reviews; further testing -> read mqueues + sys_ptrace --- profiles/apparmor.d/lsof | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/profiles/apparmor.d/lsof b/profiles/apparmor.d/lsof index b76e928e4..1675d858d 100644 --- a/profiles/apparmor.d/lsof +++ b/profiles/apparmor.d/lsof @@ -1,3 +1,8 @@ +# Last Modified: Fri Jan 17 16:48:13 2025 +abi , + +include + #------------------------------------------------------------------ # Copyright (C) 2025 Canonical Ltd. # @@ -10,24 +15,29 @@ # vim: ft=apparmor # -abi , -include profile lsof /usr/bin/lsof { include + include include + include if exists + + capability sys_ptrace, ptrace read, - @{PROC}/@{pids}/stat r, - @{PROC}/@{pids}/task/ r, + /dev/mqueue/ r, + @{PROC} r, @{PROC}/@{pids}/fd/ r, @{PROC}/@{pids}/fdinfo/* r, - - @{PROC}/@{pids}/task/@{tid}/stat r, - @{PROC}/@{pids}/task/@{tid}/fd r, + @{PROC}/@{pids}/lock r, + @{PROC}/@{pids}/mounts r, + @{PROC}/@{pids}/stat r, + @{PROC}/@{pids}/task/ r, + @{PROC}/@{pids}/task/@{tid}/fd/ r, @{PROC}/@{pids}/task/@{tid}/fdinfo/* r, + @{PROC}/@{pids}/task/@{tid}/maps r, + @{PROC}/@{pids}/task/@{tid}/stat r, + @{PROC}/locks r, - include if exists } - From b3cccb7c852dbafb980da268307b61139a1da84e Mon Sep 17 00:00:00 2001 From: Nicolas Campuzano Jimenez Date: Fri, 17 Jan 2025 20:13:41 -0500 Subject: [PATCH 06/16] Remove libvirt-qemu abstraction; remove /dev/mqueue r, rule: --- profiles/apparmor.d/lsof | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/profiles/apparmor.d/lsof b/profiles/apparmor.d/lsof index 1675d858d..757c393fb 100644 --- a/profiles/apparmor.d/lsof +++ b/profiles/apparmor.d/lsof @@ -1,4 +1,4 @@ -# Last Modified: Fri Jan 17 16:48:13 2025 +# Last Modified: Fri Jan 17 20:12:40 2025 abi , include @@ -18,15 +18,11 @@ include profile lsof /usr/bin/lsof { include - include include - include if exists capability sys_ptrace, - ptrace read, - /dev/mqueue/ r, @{PROC} r, @{PROC}/@{pids}/fd/ r, @{PROC}/@{pids}/fdinfo/* r, @@ -40,4 +36,5 @@ profile lsof /usr/bin/lsof { @{PROC}/@{pids}/task/@{tid}/stat r, @{PROC}/locks r, + include if exists } From d6e23dc80afe59327d8950d3710018431c9945f9 Mon Sep 17 00:00:00 2001 From: Nicolas Campuzano Jimenez Date: Wed, 22 Jan 2025 23:15:14 -0500 Subject: [PATCH 07/16] add rule --- profiles/apparmor.d/lsof | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/profiles/apparmor.d/lsof b/profiles/apparmor.d/lsof index 757c393fb..886fee601 100644 --- a/profiles/apparmor.d/lsof +++ b/profiles/apparmor.d/lsof @@ -1,4 +1,4 @@ -# Last Modified: Fri Jan 17 20:12:40 2025 +# Last Modified: Mon Jan 20 20:17:22 2025 abi , include @@ -15,15 +15,16 @@ include # vim: ft=apparmor # - profile lsof /usr/bin/lsof { include include capability sys_ptrace, + ptrace read, @{PROC} r, + @{PROC}/locks r, @{PROC}/@{pids}/fd/ r, @{PROC}/@{pids}/fdinfo/* r, @{PROC}/@{pids}/lock r, @@ -36,5 +37,8 @@ profile lsof /usr/bin/lsof { @{PROC}/@{pids}/task/@{tid}/stat r, @{PROC}/locks r, + owner @{PROC}/@{pid}/net/* r, + include if exists } + From e69781ac736127df57ecb609e2ae641089449aba Mon Sep 17 00:00:00 2001 From: Nicolas Campuzano Jimenez Date: Thu, 23 Jan 2025 22:44:49 -0500 Subject: [PATCH 08/16] add mqueue getattr rule; remove owner from /proc/PID/net; attach paths to aa_disconnected --- profiles/apparmor.d/lsof | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/profiles/apparmor.d/lsof b/profiles/apparmor.d/lsof index 886fee601..eca29052b 100644 --- a/profiles/apparmor.d/lsof +++ b/profiles/apparmor.d/lsof @@ -15,14 +15,15 @@ include # vim: ft=apparmor # -profile lsof /usr/bin/lsof { +profile lsof /usr/bin/lsof flags=(attach_disconnected.path=/aa_disconnected/) { include include capability sys_ptrace, - ptrace read, + mqueue getattr type=posix, + @{PROC} r, @{PROC}/locks r, @{PROC}/@{pids}/fd/ r, @@ -35,9 +36,8 @@ profile lsof /usr/bin/lsof { @{PROC}/@{pids}/task/@{tid}/fdinfo/* r, @{PROC}/@{pids}/task/@{tid}/maps r, @{PROC}/@{pids}/task/@{tid}/stat r, - @{PROC}/locks r, - owner @{PROC}/@{pid}/net/* r, + @{PROC}/@{pid}/net/* r, include if exists } From 5dba8b05b5d77f13b614e7df18ad89484ce5a0ad Mon Sep 17 00:00:00 2001 From: Nicolas Campuzano Jimenez Date: Thu, 23 Jan 2025 23:01:16 -0500 Subject: [PATCH 09/16] add '/ r,' rule --- profiles/apparmor.d/lsof | 2 ++ 1 file changed, 2 insertions(+) diff --git a/profiles/apparmor.d/lsof b/profiles/apparmor.d/lsof index eca29052b..35ca20784 100644 --- a/profiles/apparmor.d/lsof +++ b/profiles/apparmor.d/lsof @@ -24,6 +24,8 @@ profile lsof /usr/bin/lsof flags=(attach_disconnected.path=/aa_disconnected/) { mqueue getattr type=posix, + / r, + @{PROC} r, @{PROC}/locks r, @{PROC}/@{pids}/fd/ r, From c9cd3606b081fd3563af45307a990e1fa30722c4 Mon Sep 17 00:00:00 2001 From: Nicolas Campuzano Jimenez Date: Mon, 17 Feb 2025 19:46:24 -0500 Subject: [PATCH 10/16] Updated profile + tests --- profiles/apparmor.d/lsof | 30 ++--- tests/profiles/lsof/task.yaml | 212 ++++++++++++++++++++++++++++++++++ 2 files changed, 228 insertions(+), 14 deletions(-) create mode 100644 tests/profiles/lsof/task.yaml diff --git a/profiles/apparmor.d/lsof b/profiles/apparmor.d/lsof index 35ca20784..28dedd773 100644 --- a/profiles/apparmor.d/lsof +++ b/profiles/apparmor.d/lsof @@ -26,21 +26,23 @@ profile lsof /usr/bin/lsof flags=(attach_disconnected.path=/aa_disconnected/) { / r, - @{PROC} r, - @{PROC}/locks r, - @{PROC}/@{pids}/fd/ r, - @{PROC}/@{pids}/fdinfo/* r, - @{PROC}/@{pids}/lock r, - @{PROC}/@{pids}/mounts r, - @{PROC}/@{pids}/stat r, - @{PROC}/@{pids}/task/ r, - @{PROC}/@{pids}/task/@{tid}/fd/ r, - @{PROC}/@{pids}/task/@{tid}/fdinfo/* r, - @{PROC}/@{pids}/task/@{tid}/maps r, - @{PROC}/@{pids}/task/@{tid}/stat r, + /** r, + #the permissions below are now redundant + #@{PROC} r, + #@{PROC}/locks r, + #@{PROC}/@{pids}/fd/ r, + #@{PROC}/@{pids}/fdinfo/* r, + #@{PROC}/@{pids}/lock r, + #@{PROC}/@{pids}/mounts r, + #@{PROC}/@{pids}/stat r, + #@{PROC}/@{pids}/task/ r, + #@{PROC}/@{pids}/task/@{tid}/fd/ r, + #@{PROC}/@{pids}/task/@{tid}/fdinfo/* r, + #@{PROC}/@{pids}/task/@{tid}/maps r, + #@{PROC}/@{pids}/task/@{tid}/stat r, + + #@{PROC}/@{pid}/net/* r, - @{PROC}/@{pid}/net/* r, - include if exists } diff --git a/tests/profiles/lsof/task.yaml b/tests/profiles/lsof/task.yaml new file mode 100644 index 000000000..fc030f3e3 --- /dev/null +++ b/tests/profiles/lsof/task.yaml @@ -0,0 +1,212 @@ +summary: stress test for the lsof profile +execute: | + ### Trivial test cases + #lsof /usr/bin/bash | MATCH '/usr/bin/bash' #initial basic test + # lsof >/dev/null 2>&1 + # test $? -eq 0$ + + #if debugging necessary, run spread with '-vv' and '-debugging' and uncomment below + #lsof | tee /var/tmp/lsof_no_denials.txt + + # Create block and character devices only if they don't exist + ########### + ## SETUP ## + ########### + # Create character device (check it doesn't exist!!) + [ -e /dev/mem ] || sudo mknod /dev/mem c 1 1 #major 1-> memory device; #minor 1-> DMA + # make sure we can run lsof -d mem later + sudo chmod 660 /dev/mem + + # Create loopback test device (chck it doesn't exist either!) + [ -e /dev/loop10 ] || sudo mknod /dev/loop10 b 7 10 # major 1 -> loopback device; #minor10 -> instance 10 of device driver; shouldn't be in use. + dd if=/dev/zero of=/tmp/test.img bs=1M count=10 # Fill /tmp/test.img with 10MB of 0's + sudo losetup /dev/loop10 /tmp/test.img #mount /tmp/test.img on /dev/loop10 so it looks like a block device + + # Create character test device (check again!) + [ -e /dev/char-test ] || sudo mknod /dev/char-test c 99 1 #this major shouldn't be defined, should be a useless device just for extra testing + + + ########### + ## TESTS ## + ########### + + # List all open files attached to /, recursively + #sudo lsof +D / + # these 2 could be combined in one (-i -U) to list all UNIX sockets and network files$$$$ + sudo lsof -i + sudo lsof -U + # these 5 could be combined ( -d mem,mmap,txt,CHR,BLK) for mapped, memory-mapped, binaries, character & block devices) + sudo lsof -d mem + sudo lsof -d mmap + sudo lsof -d txt + sudo lsof -d CHR + sudo lsof -d BLK + + # ########################################################################## + # Test Deleted but Open Files + # Create a test file and open it in the background + echo "test data" > /tmp/deleted-file + sleep 1 + tail -f /tmp/deleted-file & # Keep file open in background + TAIL_PID=$! + sleep 2 + # Delete the file while it's in use + rm /tmp/deleted-file + + # See if lsof still detects it + sudo lsof | grep "(deleted)" + + # Cleanup + kill $TAIL_PID + + + # ####################################################### + # Start a temporary web server + python3 -m http.server 8080 & + PYTHON_PID=$! + sleep 2 + # Check what process is using port 8080 + sudo lsof -i :8080 + + # Cleanup + kill $PYTHON_PID + + # ######################################################## + # Test Named Pipe + # Open a named pipe + mkfifo /tmp/testpipe + cat /tmp/testpipe & # Open for reading in the background + CAT_PID=$! + sleep 2 + echo "test" > /tmp/testpipe #so that grep doesn't hang + sleep 1 + # Check lsof dislays open pipe + sudo lsof +E | tee /tmp/lsof.log | grep /tmp/testpipe || grep FIFO /tmp/lsof.log + # Cleanup + #kill $CAT_PID 2>/dev/null #in case cat terminates as soon as it outputs the redirected input from echoi + rm /tmp/testpipe + # + # + + # cat /tmp/script_debug.log + # ########################### + #Open network sockets + # Start a temporary web server + python3 -m http.server 8080 & + sleep 1 + PYTHON_PID=$! + sleep 1 + # Check what process is using port 8080 + sudo lsof -i :8080 + sleep 1 + # Cleanup + kill $PYTHON_PID + + # ################################### + #Process deletes its own binary + echo -e '#!/bin/bash\nrm -- "$0"\nsleep 60' > /tmp/self-delete.sh + chmod +x /tmp/self-delete.sh + + # Run it in the background + /tmp/self-delete.sh & + SCRIPT_PID=$! + sleep 2 + # Check if `lsof` can still track it + echo "Process PID: $SCRIPT_PID" + sudo lsof -p $SCRIPT_PID + + # Cleanup + kill $SCRIPT_PID 2>/dev/null + + + # ################################### + # #Zombie process + # ## Create a process that turns into a zombie + bash -c 'sleep 10 & wait $!' & + PARENT_PID=$! + + # # Wait a moment and check for zombies + sleep 2 + ps -ef | grep defunct + sudo lsof -p $PARENT_PID + + # # Cleanup + kill $PARENT_PID 2>/dev/null + + + # ######################################### + # #Encrypted loopback device + # Create an encrypted loopback device + dd if=/dev/zero of=/tmp/encrypted.img bs=1M count=30 + sudo losetup /dev/loop20 /tmp/encrypted.img + echo "securest passphrase" | sudo cryptsetup luksFormat /dev/loop20 --key-file=- + echo "securest passphrase" | sudo cryptsetup luksOpen /dev/loop20 encdev --key-file=- + + # # Mount it and check open files + sudo mkfs.ext4 /dev/mapper/encdev + mkdir -p /mnt/encrypted + sudo mount /dev/mapper/encdev /mnt/encrypted + sleep 2 + echo "test data" > /mnt/encrypted/testfile + # Start tail in the background and capture the correct PID + exec 3 Date: Tue, 18 Feb 2025 18:31:51 -0500 Subject: [PATCH 11/16] change recursive root read rule to only dirs, no files; uncomment file specific rules --- profiles/apparmor.d/lsof | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/profiles/apparmor.d/lsof b/profiles/apparmor.d/lsof index 28dedd773..c928102fb 100644 --- a/profiles/apparmor.d/lsof +++ b/profiles/apparmor.d/lsof @@ -26,22 +26,22 @@ profile lsof /usr/bin/lsof flags=(attach_disconnected.path=/aa_disconnected/) { / r, - /** r, - #the permissions below are now redundant - #@{PROC} r, - #@{PROC}/locks r, - #@{PROC}/@{pids}/fd/ r, - #@{PROC}/@{pids}/fdinfo/* r, - #@{PROC}/@{pids}/lock r, - #@{PROC}/@{pids}/mounts r, - #@{PROC}/@{pids}/stat r, - #@{PROC}/@{pids}/task/ r, - #@{PROC}/@{pids}/task/@{tid}/fd/ r, - #@{PROC}/@{pids}/task/@{tid}/fdinfo/* r, - #@{PROC}/@{pids}/task/@{tid}/maps r, - #@{PROC}/@{pids}/task/@{tid}/stat r, + /**/ r, - #@{PROC}/@{pid}/net/* r, + @{PROC} r, + @{PROC}/locks r, + @{PROC}/@{pids}/fd/ r, + @{PROC}/@{pids}/fdinfo/* r, + @{PROC}/@{pids}/lock r, + @{PROC}/@{pids}/mounts r, + @{PROC}/@{pids}/stat r, + @{PROC}/@{pids}/task/ r, + @{PROC}/@{pids}/task/@{tid}/fd/ r, + @{PROC}/@{pids}/task/@{tid}/fdinfo/* r, + @{PROC}/@{pids}/task/@{tid}/maps r, + @{PROC}/@{pids}/task/@{tid}/stat r, + + @{PROC}/@{pid}/net/* r, include if exists } From a65924c28a13166ed152b5ccad09f4ead25d1636 Mon Sep 17 00:00:00 2001 From: Nicolas Campuzano Jimenez Date: Mon, 3 Mar 2025 17:05:09 -0500 Subject: [PATCH 12/16] cleaner way to keep files open for lsof --- tests/profiles/lsof/task.yaml | 150 ++++++++++++++++------------------ 1 file changed, 72 insertions(+), 78 deletions(-) diff --git a/tests/profiles/lsof/task.yaml b/tests/profiles/lsof/task.yaml index fc030f3e3..317b4f290 100644 --- a/tests/profiles/lsof/task.yaml +++ b/tests/profiles/lsof/task.yaml @@ -1,49 +1,41 @@ -summary: stress test for the lsof profile -execute: | - ### Trivial test cases - #lsof /usr/bin/bash | MATCH '/usr/bin/bash' #initial basic test - # lsof >/dev/null 2>&1 - # test $? -eq 0$ +summary: stress test for the lsof profile +execute: | + ########### + ## SETUP ## + ########### + # Create character device (check it doesn't exist!!) + [ -e /dev/mem ] || sudo mknod /dev/mem c 1 1 # major 1-> memory device; #minor 1-> DMA + # make sure we can run lsof -d mem later + sudo chmod 660 /dev/mem - #if debugging necessary, run spread with '-vv' and '-debugging' and uncomment below - #lsof | tee /var/tmp/lsof_no_denials.txt + # Create loopback test device (check it doesn't exist either!) + [ -e /dev/loop10 ] || sudo mknod /dev/loop10 b 7 10 # major 1 -> loopback device; #minor10 -> instance 10 of device driver; shouldn't be in use. + dd if=/dev/zero of=/tmp/test.img bs=1M count=10 # Fill /tmp/test.img with 10MB of 0's + sudo losetup /dev/loop10 /tmp/test.img # mount /tmp/test.img on /dev/loop10 so it looks like a block device - # Create block and character devices only if they don't exist - ########### - ## SETUP ## - ########### - # Create character device (check it doesn't exist!!) - [ -e /dev/mem ] || sudo mknod /dev/mem c 1 1 #major 1-> memory device; #minor 1-> DMA - # make sure we can run lsof -d mem later - sudo chmod 660 /dev/mem - - # Create loopback test device (chck it doesn't exist either!) - [ -e /dev/loop10 ] || sudo mknod /dev/loop10 b 7 10 # major 1 -> loopback device; #minor10 -> instance 10 of device driver; shouldn't be in use. - dd if=/dev/zero of=/tmp/test.img bs=1M count=10 # Fill /tmp/test.img with 10MB of 0's - sudo losetup /dev/loop10 /tmp/test.img #mount /tmp/test.img on /dev/loop10 so it looks like a block device - - # Create character test device (check again!) - [ -e /dev/char-test ] || sudo mknod /dev/char-test c 99 1 #this major shouldn't be defined, should be a useless device just for extra testing + # Create character test device (check again!) + [ -e /dev/char-test ] || sudo mknod /dev/char-test c 99 1 # this major shouldn't be defined, should be a useless device just for extra testing - ########### - ## TESTS ## - ########### + ########### + ## TESTS ## + ########### - # List all open files attached to /, recursively - #sudo lsof +D / - # these 2 could be combined in one (-i -U) to list all UNIX sockets and network files$$$$ - sudo lsof -i - sudo lsof -U + # List all open files attached to /, recursively + # sudo lsof +D / + # these 2 could be combined in one (-i -U) to list all UNIX sockets and network files + sudo lsof -i + sudo lsof -U # these 5 could be combined ( -d mem,mmap,txt,CHR,BLK) for mapped, memory-mapped, binaries, character & block devices) - sudo lsof -d mem - sudo lsof -d mmap - sudo lsof -d txt - sudo lsof -d CHR - sudo lsof -d BLK + sudo lsof -d mem + sudo lsof -d mmap + sudo lsof -d txt + sudo lsof -d CHR + sudo lsof -d BLK - # ########################################################################## + ############################# # Test Deleted but Open Files + ############################# # Create a test file and open it in the background echo "test data" > /tmp/deleted-file sleep 1 @@ -60,8 +52,9 @@ execute: | kill $TAIL_PID - # ####################################################### + ############################## # Start a temporary web server + ############################## python3 -m http.server 8080 & PYTHON_PID=$! sleep 2 @@ -71,26 +64,23 @@ execute: | # Cleanup kill $PYTHON_PID - # ######################################################## - # Test Named Pipe + #################### + # Test Named Pipe + #################### # Open a named pipe mkfifo /tmp/testpipe - cat /tmp/testpipe & # Open for reading in the background - CAT_PID=$! - sleep 2 - echo "test" > /tmp/testpipe #so that grep doesn't hang - sleep 1 + # open the pipe for r/w so that it remains open + exec 3<> /tmp/testpipe # Check lsof dislays open pipe sudo lsof +E | tee /tmp/lsof.log | grep /tmp/testpipe || grep FIFO /tmp/lsof.log # Cleanup - #kill $CAT_PID 2>/dev/null #in case cat terminates as soon as it outputs the redirected input from echoi + exec 3<&- # Close fd 3 rm /tmp/testpipe - # - # - # cat /tmp/script_debug.log - # ########################### - #Open network sockets + + ##################### + # Open network sockets + ##################### # Start a temporary web server python3 -m http.server 8080 & sleep 1 @@ -103,7 +93,7 @@ execute: | kill $PYTHON_PID # ################################### - #Process deletes its own binary + # Process deletes its own binary echo -e '#!/bin/bash\nrm -- "$0"\nsleep 60' > /tmp/self-delete.sh chmod +x /tmp/self-delete.sh @@ -119,30 +109,31 @@ execute: | kill $SCRIPT_PID 2>/dev/null - # ################################### - # #Zombie process - # ## Create a process that turns into a zombie + ################# + # Zombie process + ################# + # Create a process that turns into a zombie bash -c 'sleep 10 & wait $!' & PARENT_PID=$! - # # Wait a moment and check for zombies + # Wait a moment and check for zombies sleep 2 ps -ef | grep defunct sudo lsof -p $PARENT_PID - # # Cleanup + # Cleanup kill $PARENT_PID 2>/dev/null - - # ######################################### - # #Encrypted loopback device + ########################### + # Encrypted loopback device + ########################### # Create an encrypted loopback device dd if=/dev/zero of=/tmp/encrypted.img bs=1M count=30 sudo losetup /dev/loop20 /tmp/encrypted.img echo "securest passphrase" | sudo cryptsetup luksFormat /dev/loop20 --key-file=- echo "securest passphrase" | sudo cryptsetup luksOpen /dev/loop20 encdev --key-file=- - # # Mount it and check open files + # Mount it and check open files sudo mkfs.ext4 /dev/mapper/encdev mkdir -p /mnt/encrypted sudo mount /dev/mapper/encdev /mnt/encrypted @@ -154,55 +145,57 @@ execute: | sudo lsof /mnt/encrypted exec 3<&- # Close file descriptor after lsof - # # Cleanup + # Cleanup sudo umount /mnt/encrypted sudo cryptsetup luksClose encdev sudo losetup -d /dev/loop20 rm /tmp/encrypted.img - # ############################################# + ######## #Try SMB + ######## #Install SMB and Mount SMB share sudo apt update && sudo apt install -y samba sleep 1 sudo mkdir -p /srv/samba/share sudo chmod 777 /srv/samba/share # Allow all users to access (for testing) + # Inline the 'testshare' entry to the samba config file printf "\n[testshare]\npath = /srv/samba/share\nbrowseable = yes\nread only = no\nguest ok = yes\nforce user = nobody\n" | sudo tee -a /etc/samba/smb.conf sleep 1 sudo systemctl restart smbd nmbd - - sudo ss -tulnp | grep smbd - + + # sudo ss -tulnp | grep smbd # uncomment if need to troubleshoot SMB. + sudo modprobe cifs - - - #testparm - + + sleep 1 sudo mkdir -p /mnt/smb sudo mount -t cifs //127.0.0.1/testshare /mnt/smb -o guest - # Try open file from mounted sharew + # Try open file from mounted share echo "test content" | sudo tee /srv/samba/share/testfile.txt - sudo sync #sync samba or no content is cat'd - cat /mnt/smb/testfile.txt & - CAT_PID=$! + sudo sync # sync samba to update testfile.txt + # Open shared file for reading ans assign fd 3. Opoen for r/w can be tricky in smb, this does the trick. + exec 3 Date: Fri, 2 May 2025 12:51:49 -0700 Subject: [PATCH 13/16] profiles: switch lsof profile to abstractions/nameservice for DNS lookups lsof will attempt (reverse?) DNS queries to resolve IP addresses in open sockets to domain names, so the full nameservice abstraction is needed. Signed-off-by: Ryan Lee --- profiles/apparmor.d/lsof | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/profiles/apparmor.d/lsof b/profiles/apparmor.d/lsof index c928102fb..e6f8ce2ea 100644 --- a/profiles/apparmor.d/lsof +++ b/profiles/apparmor.d/lsof @@ -17,7 +17,7 @@ include profile lsof /usr/bin/lsof flags=(attach_disconnected.path=/aa_disconnected/) { include - include + include capability sys_ptrace, ptrace read, From e278575799c909ad96c68108c8044d222b30a82e Mon Sep 17 00:00:00 2001 From: Ryan Lee Date: Fri, 2 May 2025 12:54:15 -0700 Subject: [PATCH 14/16] profiles: give lsof access to its own binary for confined execution contexts Signed-off-by: Ryan Lee --- profiles/apparmor.d/lsof | 2 ++ 1 file changed, 2 insertions(+) diff --git a/profiles/apparmor.d/lsof b/profiles/apparmor.d/lsof index e6f8ce2ea..62e3d73f0 100644 --- a/profiles/apparmor.d/lsof +++ b/profiles/apparmor.d/lsof @@ -19,6 +19,8 @@ profile lsof /usr/bin/lsof flags=(attach_disconnected.path=/aa_disconnected/) { include include + /usr/bin/lsof mr, + capability sys_ptrace, ptrace read, From d9028aea4eddc71f11cfb0fa10d4cc6b61a5ddca Mon Sep 17 00:00:00 2001 From: Ryan Lee Date: Fri, 2 May 2025 15:00:23 -0700 Subject: [PATCH 15/16] profiles: give lsof CAP_DAC_READ_SEARCH and CAP_DAC_OVERRIDE This is necessary for lsof run as root to be able to return results from processes run by other users. Signed-off-by: Ryan Lee --- profiles/apparmor.d/lsof | 2 ++ 1 file changed, 2 insertions(+) diff --git a/profiles/apparmor.d/lsof b/profiles/apparmor.d/lsof index 62e3d73f0..754c009b3 100644 --- a/profiles/apparmor.d/lsof +++ b/profiles/apparmor.d/lsof @@ -22,6 +22,8 @@ profile lsof /usr/bin/lsof flags=(attach_disconnected.path=/aa_disconnected/) { /usr/bin/lsof mr, capability sys_ptrace, + capability dac_read_search, + capability dac_override, ptrace read, mqueue getattr type=posix, From 3b012c3a2425c802bf022887578b7b72e244a1d8 Mon Sep 17 00:00:00 2001 From: Ryan Lee Date: Wed, 7 May 2025 16:49:14 -0700 Subject: [PATCH 16/16] profiles: fix lsof profile test Signed-off-by: Ryan Lee --- tests/profiles/lsof/task.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/profiles/lsof/task.yaml b/tests/profiles/lsof/task.yaml index 317b4f290..00773fd45 100644 --- a/tests/profiles/lsof/task.yaml +++ b/tests/profiles/lsof/task.yaml @@ -46,7 +46,7 @@ execute: | rm /tmp/deleted-file # See if lsof still detects it - sudo lsof | grep "(deleted)" + sudo lsof | grep -F "/tmp/deleted-file (deleted)" # Cleanup kill $TAIL_PID @@ -177,7 +177,7 @@ execute: | # Try open file from mounted share echo "test content" | sudo tee /srv/samba/share/testfile.txt sudo sync # sync samba to update testfile.txt - # Open shared file for reading ans assign fd 3. Opoen for r/w can be tricky in smb, this does the trick. + # Open shared file for reading and assign fd 3. Open for r/w can be tricky in smb, this does the trick. exec 3