Skip to content

Commit f813520

Browse files
authored
Implements socket ancillary data on FreeBSD. (#7708)
using LOCAL_CREDS_PERSISTENT/SCM_CREDS2 instead so we also get the send process id.
1 parent 171ebb1 commit f813520

File tree

7 files changed

+125
-10
lines changed

7 files changed

+125
-10
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ PHP NEWS
6767
(David Carlier)
6868
. Added TCP_KEEPALIVE, TCP_KEEPIDLE, TCP_KEEPINTVL, TCP_KEEPCNT socket
6969
options. (David Carlier)
70+
. Added ancillary data support for FreeBSD. (David Carlier)
7071

7172
- Sodium:
7273
. Added sodium_crypto_stream_xchacha20_xor_ic(). (Scott)

UPGRADING

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,8 @@ PHP 8.2 UPGRADE NOTES
246246
. TCP_KEEPIDLE (Linux, others)
247247
. TCP_KEEPINTVL (Linux, others)
248248
. TCP_NOTSENT_LOWAT
249+
. LOCAL_CREDS_PERSISTENT (FreeBSD)
250+
. SCM_CREDS2 (FreeBSD)
249251

250252
========================================
251253
11. Changes to INI File Handling

ext/sockets/conversions.c

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,7 @@ static void from_zval_write_sa_family(const zval *arr_value, char *field, ser_co
435435
memcpy(field, &ival, sizeof(ival));
436436
}
437437

438-
#ifdef SO_PASSCRED
438+
#if defined(SO_PASSCRED) || defined(LOCAL_CREDS_PERSISTENT)
439439
static void from_zval_write_pid_t(const zval *arr_value, char *field, ser_context *ctx)
440440
{
441441
zend_long lval;
@@ -522,7 +522,7 @@ static void to_zval_read_uint32(const char *data, zval *zv, res_context *ctx)
522522
ZVAL_LONG(zv, (zend_long)ival);
523523
}
524524
#endif
525-
#ifdef SO_PASSCRED
525+
#if defined(SO_PASSCRED) || defined(LOCAL_CREDS_PERSISTENT)
526526
static void to_zval_read_pid_t(const char *data, zval *zv, res_context *ctx)
527527
{
528528
pid_t ival;
@@ -1301,19 +1301,24 @@ void to_zval_read_in6_pktinfo(const char *data, zval *zv, res_context *ctx)
13011301
}
13021302
#endif
13031303

1304-
/* CONVERSIONS for struct ucred/cmsgcred */
1305-
#ifdef SO_PASSCRED
1304+
/* CONVERSIONS for struct ucred */
1305+
#if defined(SO_PASSCRED) || defined(LOCAL_CREDS_PERSISTENT)
13061306
static const field_descriptor descriptors_ucred[] = {
1307-
#if defined(ANC_CREDS_UCRED)
1308-
{"pid", sizeof("pid"), 1, offsetof(struct ucred, pid), from_zval_write_pid_t, to_zval_read_pid_t},
1309-
{"uid", sizeof("uid"), 1, offsetof(struct ucred, uid), from_zval_write_uid_t, to_zval_read_uid_t},
1310-
/* assume the type gid_t is the same as uid_t: */
1311-
{"gid", sizeof("gid"), 1, offsetof(struct ucred, gid), from_zval_write_uid_t, to_zval_read_uid_t},
1307+
#if defined(LOCAL_CREDS_PERSISTENT)
1308+
{"pid", sizeof("pid"), 1, offsetof(struct sockcred2, sc_pid), from_zval_write_pid_t, to_zval_read_pid_t},
1309+
{"uid", sizeof("uid"), 1, offsetof(struct sockcred2, sc_euid), from_zval_write_uid_t, to_zval_read_uid_t},
1310+
/* the type gid_t is the same as uid_t: */
1311+
{"gid", sizeof("gid"), 1, offsetof(struct sockcred2, sc_egid), from_zval_write_uid_t, to_zval_read_uid_t},
13121312
#elif defined(ANC_CREDS_CMSGCRED)
13131313
{"pid", sizeof("pid"), 1, offsetof(struct cmsgcred, cmcred_pid), from_zval_write_pid_t, to_zval_read_pid_t},
13141314
{"uid", sizeof("uid"), 1, offsetof(struct cmsgcred, cmcred_uid), from_zval_write_uid_t, to_zval_read_uid_t},
13151315
/* assume the type gid_t is the same as uid_t: */
13161316
{"gid", sizeof("gid"), 1, offsetof(struct cmsgcred, cmcred_gid), from_zval_write_uid_t, to_zval_read_uid_t},
1317+
#elif defined(SO_PASSCRED)
1318+
{"pid", sizeof("pid"), 1, offsetof(struct ucred, pid), from_zval_write_pid_t, to_zval_read_pid_t},
1319+
{"uid", sizeof("uid"), 1, offsetof(struct ucred, uid), from_zval_write_uid_t, to_zval_read_uid_t},
1320+
/* assume the type gid_t is the same as uid_t: */
1321+
{"gid", sizeof("gid"), 1, offsetof(struct ucred, gid), from_zval_write_uid_t, to_zval_read_uid_t},
13171322
#endif
13181323
{0}
13191324
};

ext/sockets/conversions.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
#ifndef PHP_WIN32
77
# include <netinet/in.h>
88
# include <sys/socket.h>
9+
# ifdef __FreeBSD__
10+
# include <sys/un.h>
11+
# endif
912
#else
1013
# include <Ws2tcpip.h>
1114
#endif
@@ -51,7 +54,7 @@ void from_zval_write_in6_pktinfo(const zval *container, char *in6_pktinfo_c, ser
5154
void to_zval_read_in6_pktinfo(const char *data, zval *zv, res_context *ctx);
5255
#endif
5356

54-
#ifdef SO_PASSCRED
57+
#if defined(SO_PASSCRED) || defined(LOCAL_CREDS_PERSISTENT)
5558
void from_zval_write_ucred(const zval *container, char *ucred_c, ser_context *ctx);
5659
void to_zval_read_ucred(const char *data, zval *zv, res_context *ctx);
5760
#endif

ext/sockets/sendrecvmsg.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,11 @@ static void init_ancillary_registry(void)
134134
#endif
135135
#endif
136136

137+
#ifdef LOCAL_CREDS_PERSISTENT
138+
PUT_ENTRY(SOCKCRED2SIZE(1), 1, 0, from_zval_write_ucred,
139+
to_zval_read_ucred, SOL_SOCKET, SCM_CREDS2);
140+
#endif
141+
137142
#ifdef SCM_RIGHTS
138143
PUT_ENTRY(0, sizeof(int), calculate_scm_rights_space, from_zval_write_fd_array,
139144
to_zval_read_fd_array, SOL_SOCKET, SCM_RIGHTS);
@@ -452,6 +457,10 @@ void php_socket_sendrecvmsg_init(INIT_FUNC_ARGS)
452457
#endif
453458
REGISTER_LONG_CONSTANT("SO_PASSCRED", SO_PASSCRED, CONST_CS | CONST_PERSISTENT);
454459
#endif
460+
#ifdef LOCAL_CREDS_PERSISTENT
461+
REGISTER_LONG_CONSTANT("SCM_CREDS2", SCM_CREDS2, CONST_CS | CONST_PERSISTENT);
462+
REGISTER_LONG_CONSTANT("LOCAL_CREDS_PERSISTENT", LOCAL_CREDS_PERSISTENT, CONST_CS | CONST_PERSISTENT);
463+
#endif
455464

456465
#ifdef ZTS
457466
ancillary_mutex = tsrm_mutex_alloc();

ext/sockets/sockets.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,9 @@ static PHP_MINIT_FUNCTION(sockets)
638638
#ifdef AI_NUMERICSERV
639639
REGISTER_LONG_CONSTANT("AI_NUMERICSERV", AI_NUMERICSERV, CONST_CS | CONST_PERSISTENT);
640640
#endif
641+
#ifdef SOL_LOCAL
642+
REGISTER_LONG_CONSTANT("SOL_LOCAL", SOL_LOCAL, CONST_CS | CONST_PERSISTENT);
643+
#endif
641644

642645
php_socket_sendrecvmsg_init(INIT_FUNC_ARGS_PASSTHRU);
643646

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
--TEST--
2+
recvmsg(): receive SCM_CREDS messages
3+
--EXTENSIONS--
4+
sockets
5+
--SKIPIF--
6+
<?php
7+
8+
if (!str_contains(PHP_OS, 'FreeBSD')) {
9+
die('skipped supported only on FreeBSD');
10+
}
11+
--FILE--
12+
<?php
13+
include __DIR__."/mcast_helpers.php.inc";
14+
$path = __DIR__ . "/socket_cmsg_credentials_fbsd.sock";
15+
16+
@unlink($path);
17+
18+
echo "creating send socket\n";
19+
$sends1 = socket_create(AF_UNIX, SOCK_DGRAM, 0) or die("err");
20+
var_dump($sends1);
21+
socket_set_nonblock($sends1) or die("Could not put in non-blocking mode");
22+
23+
echo "creating receive socket\n";
24+
$s = socket_create(AF_UNIX, SOCK_DGRAM, 0) or die("err");
25+
var_dump($s);
26+
$br = socket_bind($s, $path) or die("err");
27+
var_dump($br);
28+
socket_set_nonblock($s) or die("Could not put in non-blocking mode");
29+
socket_set_option($s, SOL_LOCAL, LOCAL_CREDS_PERSISTENT, 1) or die("could not set LOCAL_CREDS");
30+
31+
32+
$r = socket_sendto($sends1, $msg = "dread", strlen($msg), 0, $path);
33+
var_dump($r);
34+
checktimeout($s, 500);
35+
36+
$data = [
37+
"name" => [],
38+
"buffer_size" => 2000,
39+
"controllen" => socket_cmsg_space(SOL_SOCKET, SCM_CREDS2, 1)
40+
];
41+
if (!socket_recvmsg($s, $data, 0)) die("recvmsg");
42+
print_r($data);
43+
44+
$pid = getmypid();
45+
var_dump($data['control'][0]['data']['pid'] === $pid);
46+
?>
47+
--CLEAN--
48+
<?php
49+
$path = __DIR__ . "/socket_cmsg_credentials_fbsd.sock";
50+
@unlink($path);
51+
--EXPECTF--
52+
creating send socket
53+
object(Socket)#%d (0) {
54+
}
55+
creating receive socket
56+
object(Socket)#%d (0) {
57+
}
58+
bool(true)
59+
int(5)
60+
Array
61+
(
62+
[name] => Array
63+
(
64+
[family] => %d
65+
[path] =>
66+
)
67+
68+
[control] => Array
69+
(
70+
[0] => Array
71+
(
72+
[level] => %d
73+
[type] => %d
74+
[data] => Array
75+
(
76+
[pid] => %d
77+
[uid] => %d
78+
[gid] => %d
79+
)
80+
81+
)
82+
83+
)
84+
85+
[iov] => Array
86+
(
87+
[0] => dread
88+
)
89+
90+
[flags] => 0
91+
)
92+
bool(true)

0 commit comments

Comments
 (0)