Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

util-lib: rework get_process_cmdline() #3529

Merged
merged 1 commit into from
Jun 14, 2016

Conversation

poettering
Copy link
Member

@poettering poettering commented Jun 13, 2016

This reworks get_process_cmdline() quite substantially, fixing the following:

  • Fixes:
    a4e3bf4#r66837630
  • The passed max_length is also applied to the "comm" name, if comm_fallback is
    set.
  • The right thing happens if max_length == 1 is specified
  • when the cmdline "foobar" is abbreviated to 6 characters the result is now
    "foobar" instead of "foo...".
  • trailing whitespace are removed before the ... suffix is appended. The 7
    character abbreviation of "foo barz" is hence "foo..." instead of "foo ...".
  • leading whitespace are suppressed from the cmdline
  • a comprehensive test case is added

assert_se(streq(line, "[testa]"));
line = mfree(line);

assert_se(write(fd, "\0\0\0\0\0\0\0\0\0", 10) == 10);
Copy link
Contributor

@mcspr mcspr Jun 14, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

idk if this is just placeholder, but cmdline really could be just NULs.
max_length == 0 -> len would be 0 but line would still be allocated and returned
max_length > 1 -> k would be still equal to r and result in ENOENT

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you mean if comm_fallback is false, then an entirely zero (but not empty) cmdline would result in the empty string being returned, but it should return -ENOENT?

Are you sure it should?

or maybe i am not grokking what you are saying?

Copy link
Contributor

@mcspr mcspr Jun 14, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, correct. I was just running dummy setproctitle process that zeroes argv and test-process-util (pid) fails instantly, because of comm_fallback=false at the start of testcases. But there is no empty string result

PID3032 comm: 'setproctitle'
PID3032 cmdline: '913 27745 34816 4913 4194304 95 0 0 0 0 0 0 0 20 0 1 0 314104177 8953856a
Assertion 'get_process_cmdline(pid, 8, false, &d) >= 0' failed at src/test/test-process-util.c:65, function test_get_process_comm(). Aborting.
Aborted

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should really treat an all-zero cmdline also as a reason to fall back to the comm field. Hence i think the current behaviour is actually right. That said, we should test this explicitly, hence I will post an updated patch shortly, that explicitly checks for this.

This reworks get_process_cmdline() quite substantially, fixing the following:

- Fixes:
  systemd@a4e3bf4#r66837630

- The passed max_length is also applied to the "comm" name, if comm_fallback is
  set.

- The right thing happens if max_length == 1 is specified

- when the cmdline "foobar" is abbreviated to 6 characters the result is not
  "foobar" instead of "foo...".

- trailing whitespace are removed before the ... suffix is appended. The 7
  character abbreviation of "foo barz" is hence "foo..." instead of "foo ...".

- leading whitespace are suppressed from the cmdline

- a comprehensive test case is added
@poettering
Copy link
Member Author

OK, I force pushed a new version that leaves the behaviour as before, but extends the test to verify this explicitly. This means we will fallback to comm whenever the cmdline is entirely absent or contains only zeroes, and is thus empty. I am pretty sure this is the right behaviour to follow here, as this call is primarily for presentational purposes and as such we should try to return something more useful than the empty string if we can.

I also added a longer comment to the function describing its behaviour, in particular some corner cases.

@keszybz keszybz merged commit 69281c4 into systemd:master Jun 14, 2016
@evverx
Copy link
Member

evverx commented Jun 16, 2016

$ sudo make check TESTS=test-process-util
[...]
FAIL: test-process-util
[...]

$ cat ./test-process-util.log
PID1 comm: 'systemd'
PID1 cmdline: '/usr/lib/systemd/systemd --system --deserialize 17'
PID1 cmdline truncated to 8: '/usr...0'
PID1 cmdline truncated to 1: ''
PID1 PPID: 0
PID1 exe: '/usr/lib/systemd/systemd'
PID1 UID: 0
PID1 GID: 0
PID1 strlen(environ): 0
PID1 $PATH: 'n/a'
PID29210 comm: 'test-process-ut'
PID29210 cmdline: './test-process-util'
PID29210 cmdline truncated to 8: './te...'
PID29210 cmdline truncated to 1: ''
PID29210 PPID: 29209
PID29210 exe: '/home/vagrant/systemd/test-process-util'
PID29210 UID: 0
PID29210 GID: 0
PID29210 strlen(environ): 2199
PID29210 $PATH: '/sbin:/bin:/usr/sbin:/usr/bin'
Assertion 'get_process_cmdline(getpid(), 0, false, &line) == -ENOENT' failed at src/test/test-process-util.c:229, function test_get_process_cmdline_harder(). Aborting.
Assertion 'si.si_code == CLD_EXITED' failed at src/test/test-process-util.c:173, function test_get_process_cmdline_harder(). Aborting.
FAIL test-process-util (exit status: 134)

get_process_cmdline(getpid(), 0, false, &line) returns 0, *line contains some junk

...
0 "[t...]"
test_get_process_cmdline_harder+0x73e [test-process-util]
main+0x85 [test-process-util]
__libc_start_main+0xf0 [libc-2.22.so]
_start+0x29 [test-process-util]
--

0 "[testa]"
test_get_process_cmdline_harder+0x7e0 [test-process-util]
main+0x85 [test-process-util]
__libc_start_main+0xf0 [libc-2.22.so]
_start+0x29 [test-process-util]
--

0 "\f$\255\373"
test_get_process_cmdline_harder+0x8c9 [test-process-util]
main+0x85 [test-process-util]
__libc_start_main+0xf0 [libc-2.22.so]
_start+0x29 [test-process-util]

ABRT

@evverx
Copy link
Member

evverx commented Jun 16, 2016

We allocate a memory there. But don't add trailing "\0".
So, isempty returns false (sometimes)

Seems like GREEDY_REALLOC0 fixes this

@keszybz
Copy link
Member

keszybz commented Jun 16, 2016

Do we need the if (len >0) here https://github.com/systemd/systemd/pull/3529/files#diff-4455c5d492b8b6c422f8c86c2929f861R162? Maybe it should be if (allocated > 0) instead?

@poettering
Copy link
Member Author

I prepped a fix for the issue @evverx pointed out in PR #3555, please have a look

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

Successfully merging this pull request may close these issues.

None yet

4 participants