Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package fatrace for openSUSE:Factory checked in at 2025-01-27 20:56:52 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/fatrace (Old) and /work/SRC/openSUSE:Factory/.fatrace.new.2316 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "fatrace" Mon Jan 27 20:56:52 2025 rev:11 rq:1240552 version:0.18.0 Changes: -------- --- /work/SRC/openSUSE:Factory/fatrace/fatrace.changes 2022-12-13 18:57:43.191924561 +0100 +++ /work/SRC/openSUSE:Factory/.fatrace.new.2316/fatrace.changes 2025-01-27 20:57:39.252569122 +0100 @@ -1,0 +2,8 @@ +Sun Jan 26 16:41:19 UTC 2025 - Andrea Manzini <andrea.manz...@suse.com> + +- update to 0.18.0: + * Add -u/--user option to show [uid:gid] in events + * Truncate overly long --command matches + * Turn invalid FID type error into warning + +------------------------------------------------------------------- Old: ---- fatrace-0.17.0.tar.gz New: ---- fatrace-0.18.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ fatrace.spec ++++++ --- /var/tmp/diff_new_pack.l0PD31/_old 2025-01-27 20:57:40.264610836 +0100 +++ /var/tmp/diff_new_pack.l0PD31/_new 2025-01-27 20:57:40.264610836 +0100 @@ -1,7 +1,7 @@ # # spec file for package fatrace # -# Copyright (c) 2022 SUSE LLC +# Copyright (c) 2025 SUSE LLC # Copyright (c) 2013 Philipp Thomas <p...@suse.de> # # All modifications and additions to the file contributed by third parties @@ -19,7 +19,7 @@ %bcond_with tests Name: fatrace -Version: 0.17.0 +Version: 0.18.0 Release: 0 Summary: System wide file access event reporting utility License: GPL-3.0-or-later ++++++ fatrace-0.17.0.tar.gz -> fatrace-0.18.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fatrace-0.17.0/.github/workflows/release.yml new/fatrace-0.18.0/.github/workflows/release.yml --- old/fatrace-0.17.0/.github/workflows/release.yml 2022-11-11 11:04:56.000000000 +0100 +++ new/fatrace-0.18.0/.github/workflows/release.yml 2025-01-19 12:02:43.000000000 +0100 @@ -9,7 +9,7 @@ runs-on: ubuntu-latest steps: - name: Clone repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Create GitHub release uses: docker://antonyurchenko/git-release:latest diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fatrace-0.17.0/.github/workflows/tests.yml new/fatrace-0.18.0/.github/workflows/tests.yml --- old/fatrace-0.17.0/.github/workflows/tests.yml 2022-11-11 11:04:56.000000000 +0100 +++ new/fatrace-0.18.0/.github/workflows/tests.yml 2025-01-19 12:02:43.000000000 +0100 @@ -6,10 +6,10 @@ - cron: 0 4 * * MON,FRI jobs: vm: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - name: Clone repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Build run: make @@ -18,7 +18,7 @@ run: sudo tests/run container: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest strategy: fail-fast: false matrix: @@ -33,7 +33,7 @@ options: --privileged steps: - name: Clone repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install build and test dependencies run: | diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fatrace-0.17.0/NEWS new/fatrace-0.18.0/NEWS --- old/fatrace-0.17.0/NEWS 2022-11-11 11:04:56.000000000 +0100 +++ new/fatrace-0.18.0/NEWS 2025-01-19 12:02:43.000000000 +0100 @@ -1,3 +1,8 @@ +## [0.18.0] - 2025-01-19 + - Add -u/--user option to show [uid:gid] in events (thanks Gabriel Kulp!) + - Truncate overly long --command matches + - Turn invalid FID type error into warning + ## [0.17.0] - 2022-11-11 - Work around kernel bug with blocking FAN_REPORT_FID with btrfs - Improve event formatting diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fatrace-0.17.0/fatrace.8 new/fatrace-0.18.0/fatrace.8 --- old/fatrace-0.17.0/fatrace.8 2022-11-11 11:04:56.000000000 +0100 +++ new/fatrace-0.18.0/fatrace.8 2025-01-19 12:02:43.000000000 +0100 @@ -89,6 +89,10 @@ is printed as seconds/microseconds since the epoch. .TP +.B \-u\fR, \fB\-\-user +Add process user information to events, formatted as "[uid:gid]". + +.TP .B \-p \fIPID\fR, \fB\-\-ignore\-pid=\fIPID Ignore events for this process ID. Can be specified multiple times. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fatrace-0.17.0/fatrace.c new/fatrace-0.18.0/fatrace.c --- old/fatrace-0.17.0/fatrace.c 2022-11-11 11:04:56.000000000 +0100 +++ new/fatrace-0.18.0/fatrace.c 2025-01-19 12:02:43.000000000 +0100 @@ -45,6 +45,11 @@ #define BUFSIZE 256*1024 +/* https://man7.org/linux/man-pages/man5/proc_pid_comm.5.html ; not defined in any include file */ +#ifndef TASK_COMM_LEN +#define TASK_COMM_LEN 16 +#endif + #define DEBUG 0 #if DEBUG #define debug(fmt, ...) fprintf (stderr, "DEBUG: " fmt "\n", ##__VA_ARGS__) @@ -58,6 +63,7 @@ static long option_timeout = -1; static int option_current_mount = 0; static int option_timestamp = 0; +static int option_user = 0; static pid_t ignored_pids[1024]; static unsigned int ignored_pids_len = 0; static char* option_comm = NULL; @@ -144,8 +150,10 @@ const struct fanotify_event_info_fid *fid = (const struct fanotify_event_info_fid *) (data + 1); int fd; - if (fid->hdr.info_type != FAN_EVENT_INFO_TYPE_FID) - errx (EXIT_FAILURE, "Received unexpected event info type %i", fid->hdr.info_type); + if (fid->hdr.info_type != FAN_EVENT_INFO_TYPE_FID) { + warnx ("Received unexpected event info type %i, cannot get affected file", fid->hdr.info_type); + return -1; + } /* get affected file fd from fanotify_event_info_fid */ fd = open_by_handle_at (get_mount_id ((const fsid_t *) &fid->fsid), @@ -226,14 +234,13 @@ print_event (const struct fanotify_event_metadata *data, const struct timeval *event_time) { - int proc_fd; int event_fd = data->fd; static char printbuf[100]; - static char procname[100]; + static char procname[TASK_COMM_LEN]; static int procname_pid = -1; static char pathname[PATH_MAX]; bool got_procname = false; - struct stat st; + struct stat proc_fd_stat = { .st_uid = -1 }; if ((data->mask & option_filter_mask) == 0 || !show_pid (data->pid)) { if (event_fd >= 0) @@ -241,11 +248,12 @@ return; } - /* read process name */ - snprintf (printbuf, sizeof (printbuf), "/proc/%i/comm", data->pid); - proc_fd = open (printbuf, O_RDONLY); + snprintf (printbuf, sizeof (printbuf), "/proc/%i", data->pid); + int proc_fd = open (printbuf, O_RDONLY | O_DIRECTORY); if (proc_fd >= 0) { - ssize_t len = read (proc_fd, procname, sizeof (procname)); + /* read process name */ + int procname_fd = openat (proc_fd, "comm", O_RDONLY); + ssize_t len = read (procname_fd, procname, sizeof (procname)); if (len >= 0) { while (len > 0 && procname[len-1] == '\n') len--; @@ -256,9 +264,18 @@ debug ("failed to read /proc/%i/comm", data->pid); } + close (procname_fd); + + /* get user and group */ + if (option_user) { + if (fstat (proc_fd, &proc_fd_stat) < 0) + debug ("failed to stat /proc/%i: %m", data->pid); + } + close (proc_fd); } else { - debug ("failed to open /proc/%i/comm: %m", data->pid); + debug ("failed to open /proc/%i: %m", data->pid); + procname[0] = '\0'; } /* /proc/pid/comm often goes away before processing the event; reuse previously cached value if pid still matches */ @@ -289,6 +306,7 @@ ssize_t len = readlink (printbuf, pathname, sizeof (pathname)); if (len < 0) { /* fall back to the device/inode */ + struct stat st; if (fstat (event_fd, &st) < 0) err (EXIT_FAILURE, "stat"); snprintf (pathname, sizeof (pathname), "device %i:%i inode %ld\n", major (st.st_dev), minor (st.st_dev), st.st_ino); @@ -308,7 +326,14 @@ } else if (option_timestamp == 2) { printf ("%li.%06li ", event_time->tv_sec, event_time->tv_usec); } - printf ("%s(%i): %-3s %s\n", procname[0] == '\0' ? "unknown" : procname, data->pid, mask2str (data->mask), pathname); + + /* print user and group */ + if (option_user && proc_fd_stat.st_uid != (uid_t)-1) + snprintf(printbuf, sizeof printbuf, " [%u:%u]", proc_fd_stat.st_uid, proc_fd_stat.st_gid); + else + printbuf[0] = '\0'; + + printf ("%s(%i)%s: %-3s %s\n", procname[0] == '\0' ? "unknown" : procname, data->pid, printbuf, mask2str (data->mask), pathname); } static void @@ -412,6 +437,7 @@ " -o FILE, --output=FILE\tWrite events to a file instead of standard output.\n" " -s SECONDS, --seconds=SECONDS\tStop after the given number of seconds.\n" " -t, --timestamp\t\tAdd timestamp to events. Give twice for seconds since the epoch.\n" +" -u, --user\t\t\tAdd user ID and group ID to events.\n" " -p PID, --ignore-pid PID\tIgnore events for this process ID. Can be specified multiple times.\n" " -f TYPES, --filter=TYPES\tShow only the given event types; choose from C, R, O, or W, e. g. --filter=OC.\n" " -C COMM, --command=COMM\tShow only events for this command.\n" @@ -436,6 +462,7 @@ {"output", required_argument, 0, 'o'}, {"seconds", required_argument, 0, 's'}, {"timestamp", no_argument, 0, 't'}, + {"user", no_argument, 0, 'u'}, {"ignore-pid", required_argument, 0, 'p'}, {"filter", required_argument, 0, 'f'}, {"command", required_argument, 0, 'C'}, @@ -444,7 +471,7 @@ }; while (1) { - c = getopt_long (argc, argv, "C:co:s:tp:f:h", long_options, NULL); + c = getopt_long (argc, argv, "C:co:s:tup:f:h", long_options, NULL); if (c == -1) break; @@ -452,6 +479,11 @@ switch (c) { case 'C': option_comm = strdup (optarg); + /* see https://man7.org/linux/man-pages/man5/proc_pid_comm.5.html */ + if (strlen (option_comm) > TASK_COMM_LEN - 1) { + option_comm[TASK_COMM_LEN - 1] = '\0'; + warnx ("--command truncated to %i characters: %s", TASK_COMM_LEN - 1, option_comm); + } break; case 'c': @@ -462,6 +494,10 @@ option_output = strdup (optarg); break; + case 'u': + option_user = 1; + break; + case 'f': j = 0; option_filter_mask = 0; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fatrace-0.17.0/tests/fatrace-comm new/fatrace-0.18.0/tests/fatrace-comm --- old/fatrace-0.17.0/tests/fatrace-comm 1970-01-01 01:00:00.000000000 +0100 +++ new/fatrace-0.18.0/tests/fatrace-comm 2025-01-19 12:02:43.000000000 +0100 @@ -0,0 +1,54 @@ +#!/bin/sh +set -euC + +mkdir -m 777 tmp +trap "rm -rf tmp" EXIT INT QUIT PIPE + +LOG="$AUTOPKGTEST_TMP/fatrace.log" +echo "starting fatrace --command touch..." +fatrace --current-mount --command touch -s 2 -o $LOG & +sleep 1 + +echo "create files with different programs" +touch tmp/includeme +dd if=/dev/zero of=tmp/notme bs=1 count=1 + +echo "waiting for fatrace..." +wait + +echo "checking log..." +RC=0 +check_log() { + if ! grep -q "$1" $LOG; then + echo "$1 not found in log" >&2 + ((RC=RC+1)) + fi +} + +check_log "^touch([0-9]*).*includeme$" + +if grep -Eq "notme|^dd" $LOG; then + echo "notme found in log" >&2 + ((RC=RC+1)) +fi + +# exceeds TASK_COMM_LEN +rm $LOG +cp $(which touch) tmp/VeryLongTouchCommand +echo "starting fatrace --command VeryLongTouchCommand..." +fatrace --current-mount --command VeryLongTouchCommand -s 2 -o $LOG & +sleep 1 +tmp/VeryLongTouchCommand tmp/hello.txt +echo "waiting for fatrace..." +wait + +check_log "^VeryLongTouchCo([0-9]*).*hello.txt$" + +if [ $RC -ne 0 ]; then + echo "$RC checks failed -- log:" >&2 + echo "===================" >&2 + cat $LOG >&2 + echo "===================" >&2 +fi + +exit $RC diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fatrace-0.17.0/tests/fatrace-user new/fatrace-0.18.0/tests/fatrace-user --- old/fatrace-0.17.0/tests/fatrace-user 1970-01-01 01:00:00.000000000 +0100 +++ new/fatrace-0.18.0/tests/fatrace-user 2025-01-19 12:02:43.000000000 +0100 @@ -0,0 +1,64 @@ +#!/bin/sh +set -euC + +USER=nobody +ROOT_LOG="\\[0:0\\]" +USER_LOG="\\[$(id -u $USER):$(id -g $USER)\\]" + +mkdir -m 777 tmp +trap "rm -rf tmp" EXIT INT QUIT PIPE + +LOG="$AUTOPKGTEST_TMP/fatrace.log" +echo "starting fatrace..." +fatrace --current-mount --user -s 2 -o $LOG & +sleep 1 + +echo "read a file as root ..." +head NEWS > /dev/null + +echo "read a file as user ..." +runuser -u $USER tail NEWS > /dev/null + +echo "create/remove a file as root..." +TEST_FILE_ROOT=testroot.txt +touch "$TEST_FILE_ROOT" +rm "$TEST_FILE_ROOT" + +echo "create/remove a file as usr..." +TEST_FILE_USER=tmp/test$USER.txt +runuser -u $USER touch "$TEST_FILE_USER" +runuser -u $USER rm "$TEST_FILE_USER" + +echo "waiting for fatrace..." +wait + +echo "checking log..." +RC=0 +check_log() { + if ! grep -q "$1" $LOG; then + echo "$1 not found in log" >&2 + ((RC=RC+1)) + fi +} + +# accessing the NEWS file as root +check_log "^head([0-9]*) $ROOT_LOG: RC\?O\? \+$(pwd)/NEWS$" + +# accessing the NEWS file as user +check_log "^tail([0-9]*) $USER_LOG: RC\?O\? \+$(pwd)/NEWS$" + +# file creation as root +TEST_FILE_ROOT=$(realpath "$TEST_FILE_ROOT") +check_log "^touch([0-9]*) $ROOT_LOG: C\?W\?O \+$TEST_FILE_ROOT" + +TEST_FILE_USER=$(realpath "$TEST_FILE_USER") +check_log "^touch([0-9]*) $USER_LOG: C\?W\?O \+$TEST_FILE_USER" + +if [ $RC -ne 0 ]; then + echo "$RC checks failed -- log:" >&2 + echo "===================" >&2 + cat $LOG >&2 + echo "===================" >&2 +fi + +exit $RC diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fatrace-0.17.0/tests/run new/fatrace-0.18.0/tests/run --- old/fatrace-0.17.0/tests/run 2022-11-11 11:04:56.000000000 +0100 +++ new/fatrace-0.18.0/tests/run 2025-01-19 12:02:43.000000000 +0100 @@ -4,7 +4,7 @@ MYDIR=$(dirname $(readlink -f "$0")) export PATH=$(pwd):$PATH -for t in fatrace fatrace-currentmount fatrace-btrfs; do +for t in fatrace fatrace-currentmount fatrace-btrfs fatrace-user fatrace-comm; do export AUTOPKGTEST_TMP=$(mktemp -d) echo "===== $t ====" "$MYDIR"/$t