Browse Source

MT#63317 preload: allow port-anonymous binds

Change-Id: I944809e18158c6983775664f036908d5d84815c1
rfuchs/2010
Richard Fuchs 2 months ago
parent
commit
798ec58e21
1 changed files with 35 additions and 7 deletions
  1. +35
    -7
      t/tests-preload.c

+ 35
- 7
t/tests-preload.c View File

@ -103,12 +103,14 @@ int socket(int domain, int type, int protocol) {
static const char *addr_translate(struct sockaddr_un *sun, const struct sockaddr *addr,
socklen_t addrlen,
int type,
int allow_anon)
int allow_anon,
int alloc_port)
{
const char *err;
char sockname[64];
const char *any_name;
unsigned int port;
uint16_t *set_port = NULL;
const char *prefix = "unk";
switch (type) {
@ -131,6 +133,7 @@ static const char *addr_translate(struct sockaddr_un *sun, const struct sockaddr
goto err;
any_name = "0.0.0.0";
port = ntohs(sin->sin_port);
set_port = &sin->sin_port;
break;
case AF_INET6:;
struct sockaddr_in6 *sin6 = (void *) addr;
@ -142,6 +145,7 @@ static const char *addr_translate(struct sockaddr_un *sun, const struct sockaddr
goto err;
any_name = "::";
port = ntohs(sin6->sin6_port);
set_port = &sin6->sin6_port;
break;
default:
goto skip;
@ -149,27 +153,51 @@ static const char *addr_translate(struct sockaddr_un *sun, const struct sockaddr
int do_specific = 1;
if (allow_anon) {
retry_anon:
err = "Unix socket path truncated";
unsigned int use_port = port;
if (!use_port && alloc_port)
use_port = rand() % 1000 + 63000;
if (snprintf(sun->sun_path, sizeof(sun->sun_path), "%s/%s:[%s]:%u", path_prefix(),
prefix, any_name, port)
prefix, any_name, use_port)
>= sizeof(sun->sun_path))
goto err;
struct stat sb;
int ret = stat(sun->sun_path, &sb);
if (ret == 0 && sb.st_mode & S_IFSOCK)
if (ret == 0 && sb.st_mode & S_IFSOCK) {
if (!port && alloc_port)
goto retry_anon;
do_specific = 0;
}
port = use_port;
}
if (do_specific) {
retry_specific:
err = "Unix socket path truncated";
unsigned int use_port = port;
if (!use_port && alloc_port)
use_port = rand() % 1000 + 63000;
if (snprintf(sun->sun_path, sizeof(sun->sun_path), "%s/%s:[%s]:%u", path_prefix(),
prefix, sockname, port)
prefix, sockname, use_port)
>= sizeof(sun->sun_path))
goto err;
if (!port && alloc_port) {
struct stat sb;
int ret = stat(sun->sun_path, &sb);
if (ret == 0 && sb.st_mode & S_IFSOCK)
goto retry_specific;
}
port = use_port;
}
if (alloc_port)
*set_port = htons(port);
sun->sun_family = AF_UNIX;
return NULL;
skip:
@ -278,7 +306,7 @@ int bind(int fd, const struct sockaddr *addr, socklen_t addrlen) {
assert(s->wanted_domain == addr->sa_family);
struct sockaddr_un sun;
err = addr_translate(&sun, addr, addrlen, s->type, 0);
err = addr_translate(&sun, addr, addrlen, s->type, 0, 1);
if (err) {
if (!err[0])
goto do_bind;
@ -506,7 +534,7 @@ int connect(int fd, const struct sockaddr *addr, socklen_t addrlen) {
assert(s->wanted_domain == addr->sa_family);
struct sockaddr_un sun;
err = addr_translate(&sun, addr, addrlen, s->type, 1);
err = addr_translate(&sun, addr, addrlen, s->type, 1, 0);
if (err) {
if (!err[0])
goto do_connect;
@ -758,7 +786,7 @@ static const struct sockaddr *addr_send_translate(const struct sockaddr *addr, i
return ret;
static __thread struct sockaddr_un sun;
const char *err = addr_translate(&sun, addr, *addrlen, type, 0);
const char *err = addr_translate(&sun, addr, *addrlen, type, 0, 0);
if (!err) {
*addrlen = sizeof(sun);
return (void *) &sun;


Loading…
Cancel
Save