Merge pull request #23369 from yuwata/error-handling-fixlets

Several fixlets
This commit is contained in:
Yu Watanabe
2022-05-14 04:59:56 +09:00
committed by GitHub
4 changed files with 54 additions and 4 deletions

View File

@@ -776,7 +776,7 @@ int read_full_file_full(
/* Seeking is not supported on AF_UNIX sockets */
if (offset != UINT64_MAX)
return -ESPIPE;
return -ENXIO;
if (dir_fd == AT_FDCWD)
r = sockaddr_un_set_path(&sa.un, filename);
@@ -809,7 +809,7 @@ int read_full_file_full(
return r;
if (bind(sk, &bsa.sa, r) < 0)
return r;
return -errno;
}
if (connect(sk, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0)

View File

@@ -1236,7 +1236,10 @@ int sockaddr_un_set_path(struct sockaddr_un *ret, const char *path) {
* addresses!), which the kernel doesn't. We do this to reduce chance of incompatibility with other apps that
* do not expect non-NUL terminated file system path. */
if (l+1 > sizeof(ret->sun_path))
return -EINVAL;
return path[0] == '@' ? -EINVAL : -ENAMETOOLONG; /* return a recognizable error if this is
* too long to fit into a sockaddr_un, but
* is a file system path, and thus might be
* connectible via O_PATH indirection. */
*ret = (struct sockaddr_un) {
.sun_family = AF_UNIX,

View File

@@ -2,6 +2,7 @@
#include <fcntl.h>
#include <grp.h>
#include <net/if_arp.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
@@ -11,11 +12,15 @@
#include "escape.h"
#include "exit-status.h"
#include "fd-util.h"
#include "fs-util.h"
#include "in-addr-util.h"
#include "io-util.h"
#include "log.h"
#include "macro.h"
#include "path-util.h"
#include "process-util.h"
#include "random-util.h"
#include "rm-rf.h"
#include "socket-util.h"
#include "string-util.h"
#include "tests.h"
@@ -478,4 +483,46 @@ TEST(ipv6_enabled) {
log_info("IPv6 enabled: %s", yes_no(socket_ipv6_is_enabled()));
}
TEST(sockaddr_un_set_path) {
_cleanup_(rm_rf_physical_and_freep) char *t = NULL;
_cleanup_(unlink_and_freep) char *sh = NULL;
_cleanup_free_ char *j = NULL;
union sockaddr_union sa;
_cleanup_close_ int fd1 = -1, fd2 = -1, fd3 = -1;
assert_se(mkdtemp_malloc("/tmp/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaXXXXXX", &t) >= 0);
assert_se(strlen(t) > SUN_PATH_LEN);
assert_se(j = path_join(t, "sock"));
assert_se(sockaddr_un_set_path(&sa.un, j) == -ENAMETOOLONG); /* too long for AF_UNIX socket */
assert_se(asprintf(&sh, "/tmp/%" PRIx64, random_u64()) >= 0);
assert_se(symlink(t, sh) >= 0); /* create temporary symlink, to access it anyway */
free(j);
assert_se(j = path_join(sh, "sock"));
assert_se(sockaddr_un_set_path(&sa.un, j) >= 0);
fd1 = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0);
assert_se(fd1 >= 0);
assert_se(bind(fd1, &sa.sa, SOCKADDR_LEN(sa)) >= 0);
assert_se(listen(fd1, 1) >= 0);
sh = unlink_and_free(sh); /* remove temporary symlink */
fd2 = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0);
assert_se(fd2 >= 0);
assert_se(connect(fd2, &sa.sa, SOCKADDR_LEN(sa)) < 0);
assert_se(errno == ENOENT); /* we removed the symlink, must fail */
free(j);
assert_se(j = path_join(t, "sock"));
fd3 = open(j, O_CLOEXEC|O_PATH|O_NOFOLLOW);
assert_se(fd3 > 0);
assert_se(sockaddr_un_set_path(&sa.un, FORMAT_PROC_FD_PATH(fd3)) >= 0); /* connect via O_PATH instead, circumventing 108ch limit */
assert_se(connect(fd2, &sa.sa, SOCKADDR_LEN(sa)) >= 0);
}
DEFINE_TEST_MAIN(LOG_DEBUG);

View File

@@ -957,7 +957,7 @@ static int display_services(int argc, char *argv[], void *userdata) {
fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
if (fd < 0)
return log_error_errno(r, "Failed to allocate AF_UNIX/SOCK_STREAM socket: %m");
return log_error_errno(errno, "Failed to allocate AF_UNIX/SOCK_STREAM socket: %m");
if (connect(fd, &sockaddr.sa, sockaddr_len) < 0) {
no = strjoin("No (", errno_to_name(errno), ")");