admin
2023-03-07 8b06b1cbf112d55307ea8a6efe711db4e7506d89
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// Copyright 2019 The Crashpad Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
 
#ifndef CRASHPAD_UTIL_LINUX_SOCKET_H_
#define CRASHPAD_UTIL_LINUX_SOCKET_H_
 
#include <sys/socket.h>
#include <sys/types.h>
 
#include <vector>
 
#include "base/macros.h"
#include "util/file/file_io.h"
 
namespace crashpad {
 
//! \brief Utilities for communicating over `SO_PASSCRED` enabled `AF_UNIX`
//!     sockets.
class UnixCredentialSocket {
 public:
  //! \brief Creates an `AF_UNIX` family socket pair with `SO_PASSCRED` set on
  //!     each socket.
  //!
  //! \param[out] s1 One end of the connected pair.
  //! \param[out] s2 The other end of the connected pair.
  //! \return `true` on success. Otherwise, `false` with a message logged.
  static bool CreateCredentialSocketpair(ScopedFileHandle* s1,
                                         ScopedFileHandle* s2);
 
  //! \brief The maximum number of file descriptors that may be sent/received
  //!     with `SendMsg()` or `RecvMsg()`.
  static constexpr size_t kMaxSendRecvMsgFDs = 4;
 
  //! \brief Wraps `sendmsg()` to send a message with file descriptors.
  //!
  //! This function is intended for use with `AF_UNIX` family sockets and
  //! passes file descriptors with `SCM_RIGHTS`.
  //!
  //! This function may be used in a compromised context.
  //!
  //! \param[in] fd The file descriptor to write the message to.
  //! \param[in] buf The buffer containing the message.
  //! \param[in] buf_size The size of the message.
  //! \param[in] fds An array of at most `kMaxSendRecvMsgFDs` file descriptors.
  //!     Optional.
  //! \param[in] fd_count The number of file descriptors in \a fds. Required
  //!     only if \a fds was set.
  //! \return 0 on success or an error code on failure.
  static int SendMsg(int fd,
                     const void* buf,
                     size_t buf_size,
                     const int* fds = nullptr,
                     size_t fd_count = 0);
 
  //! \brief Wraps `recvmsg()` to receive a message with file descriptors and
  //!     credentials.
  //!
  //! This function is intended to be used with `AF_UNIX` family sockets. Up to
  //! `kMaxSendRecvMsgFDs` file descriptors may be received (via `SCM_RIGHTS`).
  //! The socket must have `SO_PASSCRED` set.
  //!
  //! \param[in] fd The file descriptor to receive the message on.
  //! \param[out] buf The buffer to fill with the message.
  //! \param[in] buf_size The size of the message.
  //! \param[out] creds The credentials of the sender.
  //! \param[out] fds The recieved file descriptors. Optional. If `nullptr`, all
  //!     received file descriptors will be closed.
  //! \return `true` on success. Otherwise, `false`, with a message logged. No
  //!     message will be logged if the message was detected to be an EOF
  //!     condition triggered by all clients disconnecting. This case is
  //!     indistinguishable from misuses of this interface that haven't set
  //!     `SO_PASSCRED` on \a fd.
  static bool RecvMsg(int fd,
                      void* buf,
                      size_t buf_size,
                      ucred* creds,
                      std::vector<ScopedFileHandle>* fds = nullptr);
 
 private:
  DISALLOW_IMPLICIT_CONSTRUCTORS(UnixCredentialSocket);
};
 
}  // namespace crashpad
 
#endif  // CRASHPAD_UTIL_LINUX_SOCKET_H_