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

nss client: make innetgr() thread safe #5541

Closed
wants to merge 2 commits into from

Conversation

sumit-bose
Copy link
Contributor

The innetgr() call is expected to be thread safe but SSSD's the current
implementation isn't. In glibc innetgr() is implementend by calling the
setnetgrent(), getnetgrent(), endgrent() sequence with a private context
(struct __netgrent) with provides a member where NSS modules can store data
between the calls.

With this patch setnetgrent() will read all required data from the NSS
responder and store it in the data member of the __netgrent struct.
Upcoming getnetgrent() calls will only operate on the stored data and not
connect to the NSS responder anymore. endgrent() will free the data. Since
the netgroup data is read in a single request to the NSS responder
protected by a mutex and stored in private context of innetgr() this call
is now thread-safe.

Resolves: #5540

@sumit-bose
Copy link
Contributor Author

Hi,

I have send two different implementations, the second is #5542.

Each has its pros and cons. This one requires more memory since all data is read in a single run and kept in the client process between the calls. This is more or less the same as libnss_files.so does, the related data from /etc/netgroup is read by setnetgrent() and processed later.

The second one uses a new connection for each request sequences. Since the socket has to be opened and the connection established this will require a bit more time. My main concern here is that the file descriptor might get lost and the connection stays open if the caller does not implement the setnetgrent(), getentgrent(), endgrent() sequence correctly or calls them in threads because the sequence itself is not thread-safe, only the implementation with innetgr().

bye,
Sumit

@alexey-tikhonov
Copy link
Member

In general, I prefer this solution as more clear and simple. See #5542 (comment)

@sumit-bose
Copy link
Contributor Author

Hi,

thank you for the review. I set enum_limit to 0 and added a comment which explains that it is not used for this specific call.

bye,
Sumit

@alexey-tikhonov
Copy link
Member

Sorry I missed test code last time (I have a couple of minor comments in its regard.)
Main patch looks good to me now (but Pavel self-assigned so probably wants to take a look as well).

@sumit-bose
Copy link
Contributor Author

Hi,

the latest version fixes the comments for the test program as well and adds a GPLv3 header to the file.

bye,
Sumit

@alexey-tikhonov
Copy link
Member

Hi, a couple of other remarks.

The innetgr() call is expected to be thread safe but SSSD's the current
implementation isn't. In glibc innetgr() is implementend by calling the
setnetgrent(), getnetgrent(), endgrent() sequence with a private context
(struct __netgrent) with provides a member where NSS modules can store
data between the calls.

With this patch setnetgrent() will read all required data from the NSS
responder and store it in the data member of the __netgrent struct.
Upcoming getnetgrent() calls will only operate on the stored data and
not connect to the NSS responder anymore. endgrent() will free the data.
Since the netgroup data is read in a single request to the NSS responder
protected by a mutex and stored in private context of innetgr() this
call is now thread-safe.

Resolves: SSSD#5540
This integration test adds 2 large netgroups in LDAP and runs a program
with 2 threads looking up those netgroups in parallel.

Resolves: SSSD#5540
@alexey-tikhonov
Copy link
Member

Thank you. ACK from my side.

@pbrezina, what is your opinion (in general and on "this PR vs #5542")?

@pbrezina
Copy link
Member

I'm fine with this. Ack.

@pbrezina
Copy link
Member

Pushed PR: #5541

  • master
    • 29abf94 - intg test: test is innetgr() is thread-safe
    • 88eec1c - nss client: make innetgr() thread safe

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

Successfully merging this pull request may close these issues.

sssd not thread-safe in innetgr()
3 participants