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

[Linux] psutil.users() always produces "host=localhost", not expected IP #2470

Closed
Ixtalo opened this issue Nov 10, 2024 · 4 comments
Closed

Comments

@Ixtalo
Copy link

Ixtalo commented Nov 10, 2024

Summary

  • OS: Linux
  • Architecture: 64bit
  • Psutil version: 6.1.0
  • Python version: 3.10.12
  • Type: core

Description

For python3 -c "import psutil; print(psutil.users())" it gives always "host=localhost":

suser(name='user', terminal='pts/1', host='localhost', started=..., pid=13535)

But, the expected is an IP (as long as getutent() doesn't produce ":0"/":0.0"), e.g.:

suser(name='user', terminal='pts/1', host='192.168.56.1', started=..., pid=13535)

With psutil version 5.9.0 I get the correct host='192.168.56.1'.
With 6.1.0 it's always "localhost".

Is it possible that the strcmp could be the problem?

IS:

SHOULD:

  • if (strcmp(ut->ut_host, ":0") == 0 || strcmp(ut->ut_host, ":0.0") == 0)

I would expect the IF to check whether host is ":0" or ":0.0".

@Ixtalo Ixtalo added the bug label Nov 10, 2024
@github-actions github-actions bot added the linux label Nov 10, 2024
@giampaolo
Copy link
Owner

I think I'm misinterpreting what your saying here but here goes. Are you saying that you expect "127.0.0.1" instead of "localhost"? Current doc doesn't say that it will always be an IP, so "localhost" technically is correct. You can later use gethostbyname to resolve it to either an IPv4 or IPv6 address:

>>> socket.gethostbyname("localhost")
'127.0.0.1'

@Ixtalo
Copy link
Author

Ixtalo commented Nov 10, 2024

Thanks @giampaolo for your response.

Yes, I'm afraid we're talking about different things here.

My issue is not with the name resolution, nor regarding localhost/127.0.0.1.
I am concerned about a possibly improper use of “strcmp”.

The described problem here is that with psutil.users the host-field is always set to "localhost" - even if there is a remote connection (e.g., 192.168.56.1). This is because strcmp(..) || strcmp(...) is always 1/true.

I think, the intention of the referenced code line (for Linux X Window System check) is:
IF host equals to ":0"/":0.0" THEN "localhost" ELSE host.

But, IMHO, for this to work as intended you would need (because of the lexicographical comparison done by strcmp):

if (strcmp(ut->ut_host, ":0") == 0 || strcmp(ut->ut_host, ":0.0") == 0)

A small code example:

// g++ ut_strcmp.cc -o ut_strcmp
// ./ut_strcmp :0
// ./ut_strcmp foobar
#include <iostream>
#include <cstring>

int main(int argn, char** args) {
	if (argn < 2) {
		std::cerr << "... <arg>" << std::endl;
		return 1;
	}
    const char* host = args[1];
    std::cout << "strcmp(host, :0): " << strcmp(host, ":0") << std::endl;
    std::cout << "strcmp(host, :0.0): " << strcmp(host, ":0:0") << std::endl;
    std::cout << "strcmp(..) || strcmp(...): " << (strcmp(host, ":0") || strcmp(host, ":0:0")) << std::endl;
    
    // incorrect
    if (strcmp(host, ":0") || strcmp(host, ":0.0"))
        std::cout << "(with no check for == 0, host this is always)  " << "localhost" << std::endl;
    else
	// never happens
        std::cout << "this never happens :(" << host << std::endl;

    // correct
    if (strcmp(host, ":0") == 0 || strcmp(host, ":0.0") == 0)
        // host is a standard X Window identifier
        std::cout << "(this is correct) " << "localhost" << std::endl;
    else
        std::cout << host << std::endl;

    return 0;
}
$ g++ ut_strcmp.cc -o ut_strcmp && ./ut_strcmp :0
strcmp(host, :0): 0
strcmp(host, :0.0): -58
strcmp(..) || strcmp(...): 1
with no check for == 0, host this is always: localhost
host: localhost

$ g++ ut_strcmp.cc -o ut_strcmp && ./ut_strcmp 192.168.56.1
strcmp(host, :0): 44
strcmp(host, :0.0): 44
strcmp(..) || strcmp(...): 1
with no check for == 0, host this is always: localhost
host: 192.168.56.1

@giampaolo
Copy link
Owner

Oh I get it now. And now that I re-read your first message it was clear already, but my brain malfunctioned. :)
Yeah it seems we should check strcmp return code as you suggest. Feel free to make a PR or I will do it later on.

@Ixtalo
Copy link
Author

Ixtalo commented Nov 11, 2024

@giampaolo thanks a lot! I just wanted to start the PR... ;-)

However, I can confirm that it now works (again) as expected.

I tested it with a VM with 1 login on console (tty7) and 1 remote SSH login (pts/1).

Now, fixed, correct (687695c):

In [3]: psutil.users()
Out[3]: 
[suser(name='user', terminal='tty7', host='localhost', started=1731328029.0, pid=1273),
 suser(name='user', terminal='pts/1', host='192.168.56.1', started=1731328170.0, pid=3439)]

=> host='192.168.56.1' is now correct 😄

For comparison, before, incorrect, with bug (3d12e67):

In [2]: psutil.users()
Out[2]: 
[suser(name='user', terminal='tty7', host='localhost', started=1731328029.0, pid=1273),
 suser(name='user', terminal='pts/1', host='localhost', started=1731328170.0, pid=3439)]

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

No branches or pull requests

2 participants