Skip to content

Commit 750431a

Browse files
athampymattklein123
authored andcommitted
Add mode to PipeInstance (envoyproxy#8423)
Signed-off-by: Akhil Thampy <[email protected]>
1 parent a23eff5 commit 750431a

File tree

14 files changed

+114
-7
lines changed

14 files changed

+114
-7
lines changed

api/envoy/api/v2/core/address.proto

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ message Pipe {
2020
// Paths starting with '@' will result in an error in environments other than
2121
// Linux.
2222
string path = 1 [(validate.rules).string = {min_bytes: 1}];
23+
24+
// The mode for the Pipe. Not applicable for abstract sockets.
25+
uint32 mode = 2 [(validate.rules).uint32 = {lte: 511}];
2326
}
2427

2528
// [#next-free-field: 7]

api/envoy/api/v3alpha/core/address.proto

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ message Pipe {
2424
// Paths starting with '@' will result in an error in environments other than
2525
// Linux.
2626
string path = 1 [(validate.rules).string = {min_bytes: 1}];
27+
28+
// The mode for the Pipe. Not applicable for abstract sockets.
29+
uint32 mode = 2 [(validate.rules).uint32 = {lte: 511}];
2730
}
2831

2932
// [#next-free-field: 7]

docs/root/intro/version_history.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Version history
66
* access log: added FILTER_STATE :ref:`access log formatters <config_access_log_format>` and gRPC access logger.
77
* access log: added a :ref:`typed JSON logging mode <config_access_log_format_dictionaries>` to output access logs in JSON format with non-string values
88
* api: remove all support for v1
9+
* api: added ability to specify `mode` for :ref:`Pipe <envoy_api_field_core.Pipe.mode>`.
910
* buffer: remove old implementation
1011
* build: official released binary is now built against libc++.
1112
* cluster: added :ref: `aggregate cluster <arch_overview_aggregate_cluster>` that allows load balancing between clusters.

include/envoy/api/os_sys_calls.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ class OsSysCalls {
2121
*/
2222
virtual SysCallIntResult bind(int sockfd, const sockaddr* addr, socklen_t addrlen) PURE;
2323

24+
/**
25+
* @see chmod (man 2 chmod)
26+
*/
27+
virtual SysCallIntResult chmod(const std::string& path, mode_t mode) PURE;
28+
2429
/**
2530
* @see ioctl (man 2 ioctl)
2631
*/

include/envoy/common/platform.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ typedef unsigned int sa_family_t;
4848
#include <sys/socket.h>
4949
#include <sys/uio.h> // for iovec
5050
#include <sys/un.h>
51+
#include <sys/stat.h>
52+
#include <fcntl.h>
5153
#include <unistd.h>
5254

5355
#if defined(__linux__)

source/common/api/os_sys_calls_impl.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <unistd.h>
66

77
#include <cerrno>
8+
#include <string>
89

910
namespace Envoy {
1011
namespace Api {
@@ -14,6 +15,11 @@ SysCallIntResult OsSysCallsImpl::bind(int sockfd, const sockaddr* addr, socklen_
1415
return {rc, errno};
1516
}
1617

18+
SysCallIntResult OsSysCallsImpl::chmod(const std::string& path, mode_t mode) {
19+
const int rc = ::chmod(path.c_str(), mode);
20+
return {rc, errno};
21+
}
22+
1723
SysCallIntResult OsSysCallsImpl::ioctl(int sockfd, unsigned long int request, void* argp) {
1824
const int rc = ::ioctl(sockfd, request, argp);
1925
return {rc, errno};

source/common/api/os_sys_calls_impl.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#pragma once
22

3+
#include <string>
4+
35
#include "envoy/api/os_sys_calls.h"
46

57
#include "common/singleton/threadsafe_singleton.h"
@@ -11,6 +13,7 @@ class OsSysCallsImpl : public OsSysCalls {
1113
public:
1214
// Api::OsSysCalls
1315
SysCallIntResult bind(int sockfd, const sockaddr* addr, socklen_t addrlen) override;
16+
SysCallIntResult chmod(const std::string& path, mode_t mode) override;
1417
SysCallIntResult ioctl(int sockfd, unsigned long int request, void* argp) override;
1518
SysCallSizeResult writev(int fd, const iovec* iovec, int num_iovec) override;
1619
SysCallSizeResult readv(int fd, const iovec* iovec, int num_iovec) override;

source/common/network/address_impl.cc

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ IoHandlePtr Ipv6Instance::socket(SocketType type) const {
332332
return io_handle;
333333
}
334334

335-
PipeInstance::PipeInstance(const sockaddr_un* address, socklen_t ss_len)
335+
PipeInstance::PipeInstance(const sockaddr_un* address, socklen_t ss_len, mode_t mode)
336336
: InstanceBase(Type::Pipe) {
337337
if (address->sun_path[0] == '\0') {
338338
#if !defined(__linux__)
@@ -345,15 +345,19 @@ PipeInstance::PipeInstance(const sockaddr_un* address, socklen_t ss_len)
345345
}
346346
address_ = *address;
347347
if (abstract_namespace_) {
348+
if (mode != 0) {
349+
throw EnvoyException("Cannot set mode for Abstract AF_UNIX sockets");
350+
}
348351
// Replace all null characters with '@' in friendly_name_.
349352
friendly_name_ =
350353
friendlyNameFromAbstractPath(absl::string_view(address_.sun_path, address_length_));
351354
} else {
352355
friendly_name_ = address->sun_path;
353356
}
357+
this->mode = mode;
354358
}
355359

356-
PipeInstance::PipeInstance(const std::string& pipe_path) : InstanceBase(Type::Pipe) {
360+
PipeInstance::PipeInstance(const std::string& pipe_path, mode_t mode) : InstanceBase(Type::Pipe) {
357361
if (pipe_path.size() >= sizeof(address_.sun_path)) {
358362
throw EnvoyException(
359363
fmt::format("Path \"{}\" exceeds maximum UNIX domain socket path size of {}.", pipe_path,
@@ -370,6 +374,9 @@ PipeInstance::PipeInstance(const std::string& pipe_path) : InstanceBase(Type::Pi
370374
#if !defined(__linux__)
371375
throw EnvoyException("Abstract AF_UNIX sockets are only supported on linux.");
372376
#endif
377+
if (mode != 0) {
378+
throw EnvoyException("Cannot set mode for Abstract AF_UNIX sockets");
379+
}
373380
abstract_namespace_ = true;
374381
address_length_ = pipe_path.size();
375382
memcpy(&address_.sun_path[0], pipe_path.data(), pipe_path.size());
@@ -385,6 +392,7 @@ PipeInstance::PipeInstance(const std::string& pipe_path) : InstanceBase(Type::Pi
385392
StringUtil::strlcpy(&address_.sun_path[0], pipe_path.c_str(), sizeof(address_.sun_path));
386393
friendly_name_ = address_.sun_path;
387394
}
395+
this->mode = mode;
388396
}
389397

390398
bool PipeInstance::operator==(const Instance& rhs) const { return asString() == rhs.asString(); }
@@ -397,7 +405,14 @@ Api::SysCallIntResult PipeInstance::bind(int fd) const {
397405
unlink(address_.sun_path);
398406
}
399407
auto& os_syscalls = Api::OsSysCallsSingleton::get();
400-
return os_syscalls.bind(fd, sockAddr(), sockAddrLen());
408+
auto bind_result = os_syscalls.bind(fd, sockAddr(), sockAddrLen());
409+
if (mode != 0 && !abstract_namespace_ && bind_result.rc_ == 0) {
410+
auto set_permissions = os_syscalls.chmod(address_.sun_path, mode);
411+
if (set_permissions.rc_ != 0) {
412+
throw EnvoyException(fmt::format("Failed to create socket with mode {}", mode));
413+
}
414+
}
415+
return bind_result;
401416
}
402417

403418
Api::SysCallIntResult PipeInstance::connect(int fd) const {

source/common/network/address_impl.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,12 +228,12 @@ class PipeInstance : public InstanceBase {
228228
/**
229229
* Construct from an existing unix address.
230230
*/
231-
explicit PipeInstance(const sockaddr_un* address, socklen_t ss_len);
231+
explicit PipeInstance(const sockaddr_un* address, socklen_t ss_len, mode_t mode = 0);
232232

233233
/**
234234
* Construct from a string pipe path.
235235
*/
236-
explicit PipeInstance(const std::string& pipe_path);
236+
explicit PipeInstance(const std::string& pipe_path, mode_t mode = 0);
237237

238238
// Network::Address::Instance
239239
bool operator==(const Instance& rhs) const override;
@@ -256,6 +256,7 @@ class PipeInstance : public InstanceBase {
256256
// For abstract namespaces.
257257
bool abstract_namespace_{false};
258258
uint32_t address_length_{0};
259+
mode_t mode{0};
259260
};
260261

261262
} // namespace Address

source/common/network/utility.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,8 @@ Utility::protobufAddressToAddress(const envoy::api::v2::core::Address& proto_add
455455
proto_address.socket_address().port_value(),
456456
!proto_address.socket_address().ipv4_compat());
457457
case envoy::api::v2::core::Address::kPipe:
458-
return std::make_shared<Address::PipeInstance>(proto_address.pipe().path());
458+
return std::make_shared<Address::PipeInstance>(proto_address.pipe().path(),
459+
proto_address.pipe().mode());
459460
default:
460461
NOT_REACHED_GCOVR_EXCL_LINE;
461462
}

0 commit comments

Comments
 (0)