Bug#1023429: pgrep/pkill: remove trailing 0x00 from matching?

2023-12-06 Thread Christoph Anton Mitterer
Hey.

Just for the records:
At least as of now, ssh no longer seems to add the multiple 0x0 to it's
cmdline.

But I guess the "problem" (should it ever come back or exist for other
programs) in pgrep/pkill still remains.


Cheers,
Chris.



Bug#1023429: pgrep/pkill: remove trailing 0x00 from matching?

2022-11-14 Thread Christoph Anton Mitterer
Hey Craig.


On Tue, 2022-11-15 at 08:01 +1100, Craig Small wrote:
> > 
> It can, but what we think the string is is not what the string
> actually is, I suspect.
> Each one of those 0x0 are delimiters, so if there was two of them at
> the end we would have:
> argv[0] DELIM argv[1] DELIM argv[2]
> Where DELIM is the " " delimiter ps uses and argv[2]=""

AFAIU the cmdline ist defined to be the fields, separated with 0x0 with
the last one terminated by 0x0 (so in other words, all are NULL
terminated strings).

For the matching, we need to make the fields one string, right? Because
BRE/ERE are not really defined for multiline/field matches and I guess
even if one makes something up, like one RE per field, it wouldn't be
so much useful in practise.

How does one reasonably make the multiple fields one true line without
any 0x0?

a) We concatenate simply, separated by space (which I guess is what's
   done now and causes the issue?).
   And this is already ambiguous if on wants perfect matching, cause:
   Was "foo  " actually:
 foo "" ""
   or was it rather:
 foo " "
   ?
b) we try to escape/quote the fields, so if e.g. the 2nd one would be
   
   we'd concatenate: '' (i.e. shell style quoting)
   But that's obviously more complex, since the filed may also contain
   quote characters.
c) Since (a) already looses the information how the fields actually
   looked like, we could also just say, that any whitespace in fields
   is effectively ignored, which means again, that one cannot
   specifically match a e.g. 2nd field 
   But therefore, we could apply the following rule:
 Only if a field in cmdline is non-empty, we actually append it
 and a spearating whitespace to the string that we match against.

 With the question left open, whether we strip any surrounding
 whitespace from a field, i.e. does
   foo " bar baz "
 result in
   "foo  bar baz "
   ^
   \- being the field spearatinspace
 or in
   "foo bar baz"


> The arglist is doesn't end with "[mux]" but "[mux]     ". While
> looking odd, this is what the argument list actually is.

Well I think it's difficult to say what it "actually" is, since we
cannot really express it in ONE string without a separator characters
like 0x0 that is otherwise not allowed or without loosing information.
Right?


> Another strange thing, the proc(5) manpage says:
>        /proc/[pid]/cmdline
>               This read-only file holds the complete command line for
> the process, unless the process is a zombie.  In the latter case,
> there is nothing in this file: that is, a read on this file will
> return 0 characters.  The command-line arguments appear in this file
> as a
>               set of strings separated by null bytes ('\0'), with a
> further null byte after the last string.
> 
> But neither your or my example has that, its a space. That's the
> kernel doing something odd.

That I don't understand?
The (field-)separating (single)  that you presumably add as a
convenience does not "really" exist in the command line. It's just
something that *might* have been used in the shell, that caused the
exec for the command, but the kernel never sees those.

The separator could have very well been always two   or a .


Cheers,
Chris.



Bug#1023429: pgrep/pkill: remove trailing 0x00 from matching?

2022-11-14 Thread Craig Small
On Tue, 15 Nov 2022 at 00:36, Christoph Anton Mitterer <
cales...@scientia.org> wrote:

> $ hd /proc/19557/cmdline
>   73 73 68 3a 20 2f 68 6f  6d 65 2f 63 61 6c 65 73  |ssh:
> /home/cales|
> 0010  74 79 6f 2f 2e 73 73 68  2f 6d 75 78 2f 72 6f 6f
> |tyo/.ssh/mux/roo|
> 0020  74 40 6c 63 67 2d 6c 72  7a 2d 61 64 6d 69 6e 2e
> |t@lcg-lrz-admin.|
> 0030  67 72 69 64 2e 6c 72 7a  2e 64 65 3a 32 32 20 5b  |
> grid.lrz.de:22 [|
> 0040  6d 75 78 5d 00|mux].|
> 0045
>
> That there's only exactly one trailing 0x0.
>
Ah, that might be the hint I needed.


> > That's how the argument list is stored. libproc parses it out into a
> > set of strings or one long string.
>
> Okay... but shouldn't it still be able to match?
>
It can, but what we think the string is is not what the string actually is,
I suspect.
Each one of those 0x0 are delimiters, so if there was two of them at the
end we would have:
argv[0] DELIM argv[1] DELIM argv[2]
Where DELIM is the " " delimiter ps uses and argv[2]=""

So when the cmdline is:
$ cat /proc/34724/cmdline | hd
  73 73 68 3a 20 2f 68 6f  6d 65 2f 63 61 6c 65 73  |ssh:
/home/cales|
0010  74 79 6f 2f 2e 73 73 68  2f 6d 75 78 2f 72 6f 6f
|tyo/.ssh/mux/roo|
0020  74 40 6c 63 67 2d 6c 72  7a 2d 61 64 6d 69 6e 2e
|t@lcg-lrz-admin.|
0030  67 72 69 64 2e 6c 72 7a  2e 64 65 3a 32 32 20 5b  |grid.lrz.de:22
 [|
0040  6d 75 78 5d 00 00 00 00  00 00|mux]..|
004a

The arglist is doesn't end with "[mux]" but "[mux] ". While looking
odd, this is what the argument list actually is.
There is a difference between
 If it does that strange not-matching again, try ending with " *"  or
[[:space:]]*"

I found postgres does this too.
$ hd /proc/1291/cmdline
  70 6f 73 74 67 72 65 73  3a 20 31 33 2f 6d 61 69  |postgres:
13/mai|
0010  6e 3a 20 44 65 62 69 61  6e 2d 6d 69 6e 65 74 65  |n:
Debian-minete|
0020  73 74 20 6d 69 6e 65 74  65 73 74 5f 77 6f 72 6c  |st
minetest_worl|
0030  64 31 20 5b 6c 6f 63 61  6c 5d 20 69 64 6c 65 00  |d1 [local]
idle.|
0040  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
 ||
*
0070  00 00 00 00 00 00 00 00  00 00|..|
007a

$ pgrep --full 'idle$'
$ pgrep --full 'idle[[:space:]]+$'
1075
1088
1089
1291
1293
1298
1300
1715
1720
2349

Another strange thing, the proc(5) manpage says:
   /proc/[pid]/cmdline
  This read-only file holds the complete command line for the
process, unless the process is a zombie.  In the latter case, there is
nothing in this file: that is, a read on this file will return 0
characters.  The command-line arguments appear in this file as a
  set of strings separated by null bytes ('\0'), with a further
null byte after the last string.

But neither your or my example has that, its a space. That's the kernel
doing something odd.

 - Craig


 - Craig


Bug#1023429: pgrep/pkill: remove trailing 0x00 from matching?

2022-11-14 Thread Christoph Anton Mitterer
Hey Craig

On Mon, 2022-11-14 at 19:25 +1100, Craig Small wrote:
> I'm not sure why it is not matching, my test script above works fine.
> That was with 3.3.17-5

I also just tried again, with 2:3.3.17-7.1, and oddly enough it worked
again.

$ ps ax | grep mux 
  19557 ?Ss 0:00 ssh: 
/home/calestyo/.ssh/mux/r...@lcg-lrz-admin.grid.lrz.de:22 [mux]

$ pgrep --full --exact --euid "${LOGNAME}" --list-full -- "^ssh: 
${HOME}/\.ssh/mux/.+ \[mux]$"
19557 ssh: /home/calestyo/.ssh/mux/r...@lcg-lrz-admin.grid.lrz.de:22 [mux]


The difference seems to be: ...

$ hd /proc/19557/cmdline 
  73 73 68 3a 20 2f 68 6f  6d 65 2f 63 61 6c 65 73  |ssh: /home/cales|
0010  74 79 6f 2f 2e 73 73 68  2f 6d 75 78 2f 72 6f 6f  |tyo/.ssh/mux/roo|
0020  74 40 6c 63 67 2d 6c 72  7a 2d 61 64 6d 69 6e 2e  |t@lcg-lrz-admin.|
0030  67 72 69 64 2e 6c 72 7a  2e 64 65 3a 32 32 20 5b  |grid.lrz.de:22 [|
0040  6d 75 78 5d 00|mux].|
0045

That there's only exactly one trailing 0x0.


> That's how the argument list is stored. libproc parses it out into a
> set of strings or one long string.

Okay... but shouldn't it still be able to match?


Thanks,
Chris.



Bug#1023429: pgrep/pkill: remove trailing 0x00 from matching?

2022-11-14 Thread Craig Small
On Fri, 4 Nov 2022 at 12:09, Christoph Anton Mitterer 
wrote:

> pgrep --full --exact --euid "${LOGNAME}" --list-full -- "^ssh:
> ${HOME}/\.ssh/mux/.+ \[mux]$"
>
$ ./blah [4565] &
[1] 769
$ pgrep --full --exact --list-full '^/bin/sh ./blah \[4565]$'
769 /bin/sh ./blah [4565]
$ cat blah
#!/bin/sh
sleep 100

I'm was also pretty sure that this script used to work (but no longer does
> now),
> but I've tested on some ancient Debian, and even there it fails.
>
 I'm not sure why it is not matching, my test script above works fine. That
was with 3.3.17-5

The reason seems to be, that there are trailing 0x00.
>
That's how the argument list is stored. libproc parses it out into a set of
strings or one long string.

You can't really directly use grep because the library is parsing it, while
grep uses the raw input.

 - Craig


Bug#1023429: pgrep/pkill: remove trailing 0x00 from matching?

2022-11-03 Thread Christoph Anton Mitterer
Package: procps
Version: 2:3.3.17-7.1
Severity: wishlist


Hey.

I have a script that matches on any ssh channel multiplexing process
(and then kills it) after printing them.

It basically does:
pgrep --full --exact --euid "${LOGNAME}" --list-full -- "^ssh: 
${HOME}/\.ssh/mux/.+ \[mux]$"
printf '\nPress return to kill these processes.\n'
read tmp
pkill --full --exact --euid "${LOGNAME}" -- "^ssh: ${HOME}/\.ssh/mux/.+ 
\[mux]$"

Where ".ssh/mux/" is simply my configured path.

I'm was also pretty sure that this script used to work (but no longer does now),
but I've tested on some ancient Debian, and even there it fails.

The reason seems to be, that there are trailing 0x00.

E.g. I have:
$ cat /proc/34724/cmdline | hd
  73 73 68 3a 20 2f 68 6f  6d 65 2f 63 61 6c 65 73  |ssh: /home/cales|
0010  74 79 6f 2f 2e 73 73 68  2f 6d 75 78 2f 72 6f 6f  |tyo/.ssh/mux/roo|
0020  74 40 6c 63 67 2d 6c 72  7a 2d 61 64 6d 69 6e 2e  |t@lcg-lrz-admin.|
0030  67 72 69 64 2e 6c 72 7a  2e 64 65 3a 32 32 20 5b  |grid.lrz.de:22 [|
0040  6d 75 78 5d 00 00 00 00  00 00|mux]..|
004a

$ pgrep --full --exact --euid "${LOGNAME}" --list-full -- "^ssh: 
${HOME}/\.ssh/mux/.+ \[mux]$"
$

$ pgrep --full --exact --euid "${LOGNAME}" --list-full -- "^ssh: 
${HOME}/\.ssh/mux/.+ \[mux].+$"
34724 ssh: /home/calestyo/.ssh/mux/r...@lcg-lrz-admin.grid.lrz.de:22 [mux] 
$
works again, but is of course inferior, as it would posibly match undesired
processes.


In POSIX EREs it should never be possible to match 0x00.

Wouldn't it therefore make sense to e.g. strip any trailing 0x00 from cmdline
and e.g. print a warning if any non-trailing ones are encountered?
Or maybe add some commant line switches, one that allows to ignore trailing
0x00 one, that allows to ignore non-trailing ones.



Thanks,
Chris.



-- System Information:
Debian Release: bookworm/sid
  APT prefers unstable-debug
  APT policy: (500, 'unstable-debug'), (500, 'unstable')
merged-usr: no
Architecture: amd64 (x86_64)

Kernel: Linux 6.0.0-2-amd64 (SMP w/16 CPU threads; PREEMPT)
Kernel taint flags: TAINT_WARN
Locale: LANG=en_DE.UTF-8, LC_CTYPE=en_DE.UTF-8 (charmap=UTF-8), LANGUAGE not set
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)

Versions of packages procps depends on:
ii  init-system-helpers  1.64
ii  libc62.36-4
ii  libncurses6  6.3+20220423-2
ii  libncursesw6 6.3+20220423-2
ii  libprocps8   2:3.3.17-7.1
ii  libtinfo66.3+20220423-2

Versions of packages procps recommends:
ii  psmisc  23.5-3

procps suggests no packages.

-- Configuration Files:
/etc/sysctl.conf changed [not included]

-- no debconf information