[SERVER-45894] mongocryptd pid file does not follow Unix conventions Created: 30/Jan/20  Updated: 27/Oct/23  Resolved: 17/Jun/20

Status: Closed
Project: Core Server
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Oleg Pudeyev (Inactive) Assignee: Mark Benvenuto
Resolution: Works as Designed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Duplicate
is duplicated by SERVER-45893 mongocryptd conflates lock and pid file Closed
Sprint: Security 2020-02-24, Security 2020-03-09, Security 2020-03-23, Security 2020-04-06, Security 2020-04-20, Security 2020-05-04, Security 2020-05-18, Security 2020-06-01, Security 2020-06-15, Security 2020-06-29
Participants:

 Description   

The Unix convention is for a pid file to contain the process id of the process which created the file. This is described in http://www.pathname.com/fhs/2.2/fhs-5.13.html which I found via https://stackoverflow.com/questions/688343/reference-for-proper-handling-of-pid-file-on-unix.

mongocryptd produces a file called mongocryptd.pid with the following contents:

{ "port" : 27020, "pid" : 14620 }                                                                             

This contents is contrary to the expected contents of the pid file.

For example, using the common Unix idiom of

kill `cat *pid`

produces:

kill: illegal pid: {
kill: illegal pid: "port"
kill: illegal pid: :
kill: illegal pid: 27020,
kill: illegal pid: "pid"
kill: illegal pid: :
kill: illegal pid: }

Tested on 4.2 server built from source recently.



 Comments   
Comment by Oleg Pudeyev (Inactive) [ 17/Jun/20 ]

There are many daemons that do not perform authentication. For example, most MTAs allow local users to submit mail without authentication.

It was my understanding that the changes that were being discussed was adding an FHS-compliant file, not changing existing behavior.

Comment by Mark Benvenuto [ 17/Jun/20 ]

Unfortunately, while monocryptd was never designed to follow conventions likes the Linux FHS standard, fixing it now is a breaking change for all affected drivers.

Also, mongocryptd is not designed to be run as a system-wide daemon because it has no authentication.

Comment by Oleg Pudeyev (Inactive) [ 20/Apr/20 ]

I think a name like "unix pid file path" would be more clear to sysadmins since generally files ending in .lock are private to the application and are not to be touched from outside. Someone who sees a "lock file path" argument most likely won't expect it to be the application's public interface.

Comment by Mark Benvenuto [ 17/Apr/20 ]

I cannot remove the existing parameter even though it may not follow the FHS spec because it would break everyone who uses it. I also cannot change its current behavior since I would break the case of old drivers and new mongocryptd.

I can create a new parameter instead called "lockFilePath" and hide the "pidFilePath". This way it would be free to have its own semantics.

Example of possible changes (I have not tested this, it is just a POC):
https://github.com/markbenvenuto/mongo-enterprise-modules/tree/fle_new_lock
https://github.com/markbenvenuto/mongo/tree/fle_new_lock

Comment by Oleg Pudeyev (Inactive) [ 05/Feb/20 ]

> In version 3.0 of the Linux FHS standard, there are no limits on /var/run about what a pid file may contain (see http://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch05s13.html).

See http://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch03s15.html. The directory for pid files was moved from /var/run to /run. Requirements for pid file contents haven't changed as far as I can tell.

> Regardless of the FHS spec, it is an unorthodox but it was done to allow arbitrary clients to find the tcp port/unix domain socket to connect to.

I am having a hard time understanding this rationale. How do the clients know the path to the pid file in the first place? If that path is hardcoded into the client, there is no loss of generality to also separately hardcode a different path to the socket file while maintaining the expected purpose and layout of both files. If the path is configurable there is similarly no loss of generality to provide two paths. If the requirement is to have a single input, this input could have been called something like a "state file" which is separate from either pid or socket files, and if a pid file is desired then this should be provided separately in the customary pid file format.

I am pretty sure all Unix/Linux daemonization and daemon management software I have ever used expects pid file to just have the pid of the daemon process. It is possible to run mongocryptd system-wide (and doing so offers significant user experience benefit in terms of application runtime over spawning on demand, I find) and if mongocryptd does not obey the pid file convention I expect it will not be manageable by the standard system utilities used for managing other daemons.

> Clients can follow the pseudo code below to start mongocryptd and get a singleton.

In unix/linux administration daemon management is often done from shell scripts. The referenced pseudocode is not easy to implement in a shell script, for one because "json parsing" is not a function provided by bourne shell-compatible shells.

Even if one installed additional utilities for parsing json, I expect it is still significantly more work to manage mongocryptd in this fashion compared to using one of a large number of existing tools developed for this purpose. As well, if a system administrator DOES already use an existing tool, they would generally prefer to continue using that one tool instead of developing their own tool to manage a singe daemon like mongocryptd.

Comment by Mark Benvenuto [ 04/Feb/20 ]

In version 3.0 of the Linux FHS standard, there are no limits on /var/run about what a pid file may contain (see http://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch05s13.html).

Regardless of the FHS spec, it is an unorthodox but it was done to allow arbitrary clients to find the tcp port/unix domain socket to connect to. I could have stored it in separate files but that adds a synchronization issue across files.

Singleton Behavior

Mongocryptd can be used as a singleton since it is a stateless daemon. To support this, mongocryptd dumps key information about its configuration to the pid file as a JSON document. The pid file also doubles as a lock file to ensure that only one instance of mongocryptd is running if the same pid file is specified.

The pid file contains the following information:

Unknown macro: { port }

port - is the port that mongocryptd is running on
pid - is the process number of mongocryptd
domainSocket - path to unix domain socket, not present on Windows

Clients can follow the pseudo code below to start mongocryptd and get a singleton. This psuedo code returns the tcp/ip port that mongocryptd is running on:

function get_port(pid_file)
if pid_file exists and pid_file is not empty:
return read_json(pid_file)[“port”]
return -1

function start(pid_file, port)
running_port = get_port(pid_file)
while (running_port == -1):
process = spawn(“mongocryptd --port=$port”)

  1. give it a chance to start or hit a lock file conflict
    process.wait(10ms)
    running_port = get_port(pid_file)
    return running_port
Generated at Thu Feb 08 05:09:58 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.