diff --git a/backport-Check-h_addr_list-0-before-accessing-1.patch b/backport-Check-h_addr_list-0-before-accessing-1.patch new file mode 100644 index 0000000000000000000000000000000000000000..202729942d85f32d963ce715495a52822f2038ef --- /dev/null +++ b/backport-Check-h_addr_list-0-before-accessing-1.patch @@ -0,0 +1,26 @@ +From d6ad8e0850e22098f9d46373454aa2f575434630 Mon Sep 17 00:00:00 2001 +From: Jiajie Chen +Date: Wed, 18 Jan 2023 00:34:25 +0800 +Subject: [PATCH] Check h_addr_list[0] before accessing [1] + +It triggered segfaults on Fedora 37 CI. +--- + arg.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arg.c b/arg.c +index 4e906e9..818fc58 100644 +--- a/arg.c ++++ b/arg.c +@@ -1926,6 +1926,8 @@ enter_nwad(n, sp, ep, s, he) + */ + if (!he) + break; ++ if (!he->h_addr_list[ac-1]) /* Check if address list ended prematurely */ ++ break; + if (!(ap = (unsigned char *)he->h_addr_list[ac++])) + break; + +-- +2.27.0 + diff --git a/backport-Check-if-h_addr-non-null-before-memcpy.patch b/backport-Check-if-h_addr-non-null-before-memcpy.patch new file mode 100644 index 0000000000000000000000000000000000000000..382a94a8265dd1967d4ff34acc8981cfe91c75a8 --- /dev/null +++ b/backport-Check-if-h_addr-non-null-before-memcpy.patch @@ -0,0 +1,26 @@ +From 7f74854bad25fa401cb3e739f5aeb269efd1555f Mon Sep 17 00:00:00 2001 +From: Jiajie Chen +Date: Wed, 18 Jan 2023 00:16:21 +0800 +Subject: [PATCH] Check if h_addr non-null before memcpy + +It triggered segfaults on Fedora 37 CI. +--- + arg.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arg.c b/arg.c +index d001303..4e906e9 100644 +--- a/arg.c ++++ b/arg.c +@@ -2471,7 +2471,7 @@ lkup_hostnm(hn, n) + he = gethostbyname(hn); + #endif /* defined(HASIPv6) */ + +- if (!he) ++ if (!he || !he->h_addr) + return(he); + /* + * Copy first hostname structure address to destination structure. +-- +2.27.0 + diff --git a/backport-Fix-check-of-return-value-of-stat.patch b/backport-Fix-check-of-return-value-of-stat.patch new file mode 100644 index 0000000000000000000000000000000000000000..683bb06e4a4e56d31f7acc7d576c37cd9e7b62ab --- /dev/null +++ b/backport-Fix-check-of-return-value-of-stat.patch @@ -0,0 +1,25 @@ +From 66fe6dc5ae282dbd488c19e4d9ff0be8128a4aad Mon Sep 17 00:00:00 2001 +From: Jiajie Chen +Date: Mon, 16 Jan 2023 19:30:28 +0800 +Subject: [PATCH] Fix check of return value of stat() + +--- + dialects/linux/dsock.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dialects/linux/dsock.c b/dialects/linux/dsock.c +index 0e1acf6..1fce1d9 100644 +--- a/dialects/linux/dsock.c ++++ b/dialects/linux/dsock.c +@@ -3569,7 +3569,7 @@ get_unix(p) + sr = statsafely(path, &sb); + else + sr = stat(path, &sb); +- if (sr && ((sb.st_mode & S_IFMT) == S_IFSOCK)) { ++ if (sr == 0 && ((sb.st_mode & S_IFMT) == S_IFSOCK)) { + up->sb_def = 1; + up->sb_dev = sb.st_dev; + up->sb_ino = (INODETYPE)sb.st_ino; +-- +2.27.0 + diff --git a/backport-Fix-empty-process-name-testcase-to-allow-the-dialect.patch b/backport-Fix-empty-process-name-testcase-to-allow-the-dialect.patch new file mode 100644 index 0000000000000000000000000000000000000000..2956497158375b9235f09e60dcf41dbe657b5337 --- /dev/null +++ b/backport-Fix-empty-process-name-testcase-to-allow-the-dialect.patch @@ -0,0 +1,28 @@ +From afb159fa4b56bf51d5dfecf442556a6cd31423c7 Mon Sep 17 00:00:00 2001 +From: Jiajie Chen +Date: Wed, 18 Jan 2023 22:18:44 +0800 +Subject: [PATCH] Fix empty process name testcase to allow the dialect to not + report changed command name + +--- + tests/case-22-empty-process-name.bash | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/tests/case-22-empty-process-name.bash b/tests/case-22-empty-process-name.bash +index ce4039c..5aa8113 100755 +--- a/tests/case-22-empty-process-name.bash ++++ b/tests/case-22-empty-process-name.bash +@@ -19,7 +19,9 @@ source tests/common.bash + exit 1 + fi + elif [[ $entry =~ c* ]]; then +- if [[ $entry != c ]]; then ++ if [[ $entry =~ cperl* ]]; then ++ echo "The platform does not report changed command name, that's okay" >> $report ++ elif [[ $entry != c ]]; then + echo "Process name should be empty, expect c, got $entry" >> $report + exit 1 + fi +-- +2.27.0 + diff --git a/backport-linux-Fix-handling-of-empty-command-name-closing-246.patch b/backport-linux-Fix-handling-of-empty-command-name-closing-246.patch new file mode 100644 index 0000000000000000000000000000000000000000..3dc344f0bc59d4ea09ff5df6969e24e3b9efdb67 --- /dev/null +++ b/backport-linux-Fix-handling-of-empty-command-name-closing-246.patch @@ -0,0 +1,232 @@ +From 849655be491b2fe3023bc87f6a650c2917e0c198 Mon Sep 17 00:00:00 2001 +From: Jiajie Chen +Date: Wed, 18 Jan 2023 21:36:12 +0800 +Subject: [PATCH] [linux] Fix handling of empty command name, closing #246 + +Add test from #246, where lsof returns stale command name when the +command name is empty. + +If getting command name failed, return NULL instead of empty string. +--- + dialects/linux/dproc.c | 88 +++++++++++++++------------ + print.c | 11 ++-- + tests/case-22-empty-process-name.bash | 29 +++++++++ + 3 files changed, 80 insertions(+), 40 deletions(-) + create mode 100755 tests/case-22-empty-process-name.bash + +diff --git a/dialects/linux/dproc.c b/dialects/linux/dproc.c +index e2dce74..922db6e 100644 +--- a/dialects/linux/dproc.c ++++ b/dialects/linux/dproc.c +@@ -339,12 +339,12 @@ gather_proc_info() + continue; + uid = (UID_ARG)sb.st_uid; + ht = pidts = 0; +- /* +- * Get the PID's command name. +- */ ++ /* ++ * Get the PID's command name. ++ */ + (void) make_proc_path(pidpath, n, &path, &pathl, "stat"); + if ((prv = read_id_stat(path, pid, &cmd, &ppid, &pgid)) < 0) +- cmd = "(unknown)"; ++ cmd = NULL; /* NULL means failure to get command name */ + + #if defined(HASTASKS) + /* +@@ -356,11 +356,16 @@ gather_proc_info() + * options work properly. + */ + else if (!IgnTasks && (Selflags & SELTASK)) { ++ /* ++ * Copy cmd before next call to read_id_stat due to static ++ * variables ++ */ + if (cmd) { + strncpy(cmdbuf, cmd, sizeof(cmdbuf) - 1); ++ cmdbuf[sizeof(cmdbuf) - 1] = '\0'; ++ cmd = cmdbuf; + } +- cmdbuf[sizeof(cmdbuf) - 1] = '\0'; +- cmd = cmdbuf; ++ + (void) make_proc_path(pidpath, n, &taskpath, &taskpathl, + "task"); + tx = n + 4; +@@ -1436,10 +1441,9 @@ compare_mntns(pid) + */ + + static void +-process_proc_map(p, s, ss) +- char *p; /* path to process maps file */ +- struct stat *s; /* executing text file state buffer */ +- int ss; /* *s status -- i.e., SB_* values */ ++process_proc_map(char *p, /* path to process maps file */ ++ struct stat *s, /* executing text file state buffer */ ++ int ss) /* *s status -- i.e., SB_* values */ + { + char buf[MAXPATHLEN + 1], *ep, fmtbuf[32], **fp, nmabuf[MAXPATHLEN + 1]; + dev_t dev; +@@ -1705,14 +1709,12 @@ process_proc_map(p, s, ss) + * 1 == ID is a zombie + * 2 == ID is a thread + */ +- + static int +-read_id_stat(p, id, cmd, ppid, pgid) +- char *p; /* path to status file */ +- int id; /* ID: PID or LWP */ +- char **cmd; /* malloc'd command name */ +- int *ppid; /* returned parent PID for PID type */ +- int *pgid; /* returned process group ID for PID ++read_id_stat(char *p, /* path to status file */ ++ int id, /* ID: PID or LWP */ ++ char **cmd, /* malloc'd command name */ ++ int *ppid, /* returned parent PID for PID type */ ++ int *pgid) /* returned process group ID for PID + * type */ + { + char buf[MAXPATHLEN], *cp, *cp1, **fp; +@@ -1757,14 +1759,22 @@ read_id_stat(p, id, cmd, ppid, pgid) + goto read_id_stat_exit; + cp++; + pc = 1; /* start the parenthesis balance count at 1 */ +-/* +- * Enter the command characters safely. Supply them from the initial read +- * of the stat file line, a '\n' if the initial read didn't yield a ')' +- * command closure, or by reading the rest of the command a character at +- * a time from the stat file. Count embedded '(' characters and balance +- * them with embedded ')' characters. The opening '(' starts the balance +- * count at one. +- */ ++ ++ /* empty process name to avoid leaking previous process name, ++ * see issue #246 ++ */ ++ if (cbf) { ++ cbf[0] = '\0'; ++ } ++ ++ /* ++ * Enter the command characters safely. Supply them from the initial read ++ * of the stat file line, a '\n' if the initial read didn't yield a ')' ++ * command closure, or by reading the rest of the command a character at ++ * a time from the stat file. Count embedded '(' characters and balance ++ * them with embedded ')' characters. The opening '(' starts the balance ++ * count at one. ++ */ + for (cx = es = 0;;) { + if (!es) + ch = *cp++; +@@ -1776,10 +1786,10 @@ read_id_stat(p, id, cmd, ppid, pgid) + pc++; + if (ch == ')') { + +- /* +- * Balance parentheses when a closure is encountered. When +- * they are balanced, this is the end of the command. +- */ ++ /* ++ * Balance parentheses when a closure is encountered. When ++ * they are balanced, this is the end of the command. ++ */ + pc--; + if (!pc) + break; +@@ -1793,12 +1803,12 @@ read_id_stat(p, id, cmd, ppid, pgid) + es = 1; /* Switch to fgetc() when a '\0' appears. */ + } + *cmd = cbf; +-/* +- * Read the remainder of the stat line if it was necessary to read command +- * characters individually from the stat file. +- * +- * Separate the reminder into fields. +- */ ++ /* ++ * Read the remainder of the stat line if it was necessary to read command ++ * characters individually from the stat file. ++ * ++ * Separate the reminder into fields. ++ */ + if (es) + cp = fgets(buf, sizeof(buf), fs); + (void) fclose(fs); +@@ -1841,13 +1851,11 @@ read_id_stat(p, id, cmd, ppid, pgid) + * This function should be used only when links have been successfully + * resolved in the /proc path by getlinksrc(). + */ +- + static int +-statEx(p, s, ss) +- char *p; /* file path */ +- struct stat *s; /* stat() result -- NULL if none ++statEx(char *p, /* file path */ ++ struct stat *s, /* stat() result -- NULL if none + * wanted */ +- int *ss; /* stat() status -- SB_* values */ ++ int *ss) /* stat() status -- SB_* values */ + { + static size_t ca = 0; + static char *cb = NULL; +diff --git a/print.c b/print.c +index 3671a69..4b9f14c 100644 +--- a/print.c ++++ b/print.c +@@ -742,10 +742,13 @@ print_file() + (void) printf(" %*s %s\n", NodeColW, NODETTL, NMTTL); + Hdr++; + } +-/* +- * Size or print the command. +- */ +- cp = (Lp->cmd && *Lp->cmd != '\0') ? Lp->cmd : "(unknown)"; ++ /* ++ * Size or print the command. ++ * ++ * CAUTION: command can be empty, see issue #246, ++ * use NULL to represent failure instead of empty string ++ */ ++ cp = Lp->cmd ? Lp->cmd : "(unknown)"; + if (!PrPass) { + len = safestrlen(cp, 2); + if (CmdLim && (len > CmdLim)) +diff --git a/tests/case-22-empty-process-name.bash b/tests/case-22-empty-process-name.bash +new file mode 100755 +index 0000000..ce4039c +--- /dev/null ++++ b/tests/case-22-empty-process-name.bash +@@ -0,0 +1,29 @@ ++#!/bin/bash ++# See https://github.com/lsof-org/lsof/issues/246 ++source tests/common.bash ++ ++{ ++ perl -e '$0 = ""; sleep 999' & ++ pid=$! ++ sleep 1 ++ ++ output=$($lsof -w -ad cwd -F c -p "$pid") ++ echo "lsof output:" >> $report ++ echo "$output" >> $report ++ kill $pid ++ for entry in $output ++ do ++ if [[ $entry =~ ^p[0-9]+$ ]]; then ++ if [[ $entry != p$pid ]]; then ++ echo "Incorrect pid, expect p$pid, got $entry" >> $report ++ exit 1 ++ fi ++ elif [[ $entry =~ c* ]]; then ++ if [[ $entry != c ]]; then ++ echo "Process name should be empty, expect c, got $entry" >> $report ++ exit 1 ++ fi ++ fi ++ done ++ exit 0 ++} > $report 2>&1 +-- +2.27.0 + diff --git a/backport-linux-Fix-potential-null-pointer-argument-to-strncpy.patch b/backport-linux-Fix-potential-null-pointer-argument-to-strncpy.patch new file mode 100644 index 0000000000000000000000000000000000000000..7d2714ab9b19d4f63a4b4a8fa1dd4c75547cebc2 --- /dev/null +++ b/backport-linux-Fix-potential-null-pointer-argument-to-strncpy.patch @@ -0,0 +1,42 @@ +From f637ed601195685e23d2b60deb3b40ed96919978 Mon Sep 17 00:00:00 2001 +From: Jiajie Chen +Date: Tue, 17 Jan 2023 09:28:21 +0800 +Subject: [PATCH] [linux] Fix potential null pointer argument to strncpy, + reported by clang-analyzer + +--- + arg.c | 2 +- + dialects/linux/dproc.c | 4 +++- + 2 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/arg.c b/arg.c +index 467e774..d001303 100644 +--- a/arg.c ++++ b/arg.c +@@ -2083,7 +2083,7 @@ enter_state_spec(ss) + *cp = '\0'; + cp++; + } +- if (!(len = (size_t)(ne - ns))) { ++ if (!(size_t)(ne - ns)) { + (void) fprintf(stderr, "%s: NULL %s state name in: %s\n", + Pn, pr, ss); + err = 1; +diff --git a/dialects/linux/dproc.c b/dialects/linux/dproc.c +index 17025de..a1d1276 100644 +--- a/dialects/linux/dproc.c ++++ b/dialects/linux/dproc.c +@@ -356,7 +356,9 @@ gather_proc_info() + * options work properly. + */ + else if (!IgnTasks && (Selflags & SELTASK)) { +- strncpy(cmdbuf, cmd, sizeof(cmdbuf) - 1); ++ if (cmd) { ++ strncpy(cmdbuf, cmd, sizeof(cmdbuf) - 1); ++ } + cmdbuf[sizeof(cmdbuf) - 1] = '\0'; + cmd = cmdbuf; + (void) make_proc_path(pidpath, n, &taskpath, &taskpathl, +-- +2.27.0 + diff --git a/backport-linux-Fix-potential-oob-write.patch b/backport-linux-Fix-potential-oob-write.patch new file mode 100644 index 0000000000000000000000000000000000000000..b103a8d521eef52af30cae07aaec62b18d93f60c --- /dev/null +++ b/backport-linux-Fix-potential-oob-write.patch @@ -0,0 +1,35 @@ +From 5f8baa286c57ebe839069d48c755a90402ef7b77 Mon Sep 17 00:00:00 2001 +From: Jiajie Chen +Date: Mon, 16 Jan 2023 23:51:03 +0800 +Subject: [PATCH] [linux] Fix potential oob write + +--- + dialects/linux/dsock.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/dialects/linux/dsock.c b/dialects/linux/dsock.c +index 1fce1d9..84b8d73 100644 +--- a/dialects/linux/dsock.c ++++ b/dialects/linux/dsock.c +@@ -4020,8 +4020,8 @@ process_proc_sock(p, pbr, s, ss, l, lss) + * Store the local IPX address. + */ + len = strlen(ip->la); +- if (len > nl) +- len = nl; ++ if (len > nl - 1) ++ len = nl - 1; + (void) strncpy(cp, ip->la, len); + cp += len; + *cp = '\0'; +@@ -4039,6 +4039,7 @@ process_proc_sock(p, pbr, s, ss, l, lss) + } + if (nl) { + (void) snpf(cp, nl, "%s", ip->ra); ++ len = strlen(ip->ra); + cp += len; + nl -= len; + } +-- +2.27.0 + diff --git a/lsof.spec b/lsof.spec index 7a84dc30ef7a980afbec863cac3df4452f447563..625f856750abc9daad9695cc33fed8b16832866b 100644 --- a/lsof.spec +++ b/lsof.spec @@ -1,11 +1,19 @@ Name: lsof Version: 4.94.0 -Release: 4 +Release: 5 Summary: A tool for list open files License: zlib and Sendmail and LGPLv2+ URL: https://people.freebsd.org/~abe/ Source0: https://github.com/lsof-org/%{name}/archive/%{version}.tar.gz#/%{name}-%{version}.tar.gz +Patch1: backport-Fix-check-of-return-value-of-stat.patch +Patch2: backport-linux-Fix-potential-oob-write.patch +Patch3: backport-linux-Fix-potential-null-pointer-argument-to-strncpy.patch +Patch4: backport-Check-if-h_addr-non-null-before-memcpy.patch +Patch5: backport-Check-h_addr_list-0-before-accessing-1.patch +Patch6: backport-linux-Fix-handling-of-empty-command-name-closing-246.patch +Patch7: backport-Fix-empty-process-name-testcase-to-allow-the-dialect.patch + BuildRequires: gcc git libtirpc-devel libselinux-devel %description @@ -50,6 +58,9 @@ popd %{_mandir}/man*/* %changelog +* Thu Mar 23 2023 yixiangzhike - 4.94.0-5 +- backport patches from upstream + * Tue Nov 15 2022 dongyuzhen - 4.94.0-4 - fix the format error in changelog