Skip to content

Commit 1a22780

Browse files
committed
Merge branch 'jk/credentials'
* jk/credentials: credential-cache: ignore "connection refused" errors unix-socket: do not let close() or chdir() clobber errno during cleanup credential-cache: report more daemon connection errors unix-socket: handle long socket pathnames
2 parents c74f97a + 35a71f1 commit 1a22780

File tree

2 files changed

+92
-22
lines changed

2 files changed

+92
-22
lines changed

credential-cache.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,14 @@ static void do_cache(const char *socket, const char *action, int timeout,
7171
die_errno("unable to relay credential");
7272
}
7373

74-
if (send_request(socket, &buf) < 0 && (flags & FLAG_SPAWN)) {
75-
spawn_daemon(socket);
76-
if (send_request(socket, &buf) < 0)
74+
if (send_request(socket, &buf) < 0) {
75+
if (errno != ENOENT && errno != ECONNREFUSED)
7776
die_errno("unable to connect to cache daemon");
77+
if (flags & FLAG_SPAWN) {
78+
spawn_daemon(socket);
79+
if (send_request(socket, &buf) < 0)
80+
die_errno("unable to connect to cache daemon");
81+
}
7882
}
7983
strbuf_release(&buf);
8084
}

unix-socket.c

Lines changed: 85 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,48 +9,114 @@ static int unix_stream_socket(void)
99
return fd;
1010
}
1111

12-
static void unix_sockaddr_init(struct sockaddr_un *sa, const char *path)
12+
static int chdir_len(const char *orig, int len)
13+
{
14+
char *path = xmemdupz(orig, len);
15+
int r = chdir(path);
16+
free(path);
17+
return r;
18+
}
19+
20+
struct unix_sockaddr_context {
21+
char orig_dir[PATH_MAX];
22+
};
23+
24+
static void unix_sockaddr_cleanup(struct unix_sockaddr_context *ctx)
25+
{
26+
if (!ctx->orig_dir[0])
27+
return;
28+
/*
29+
* If we fail, we can't just return an error, since we have
30+
* moved the cwd of the whole process, which could confuse calling
31+
* code. We are better off to just die.
32+
*/
33+
if (chdir(ctx->orig_dir) < 0)
34+
die("unable to restore original working directory");
35+
}
36+
37+
static int unix_sockaddr_init(struct sockaddr_un *sa, const char *path,
38+
struct unix_sockaddr_context *ctx)
1339
{
1440
int size = strlen(path) + 1;
15-
if (size > sizeof(sa->sun_path))
16-
die("socket path is too long to fit in sockaddr");
41+
42+
ctx->orig_dir[0] = '\0';
43+
if (size > sizeof(sa->sun_path)) {
44+
const char *slash = find_last_dir_sep(path);
45+
const char *dir;
46+
47+
if (!slash) {
48+
errno = ENAMETOOLONG;
49+
return -1;
50+
}
51+
52+
dir = path;
53+
path = slash + 1;
54+
size = strlen(path) + 1;
55+
if (size > sizeof(sa->sun_path)) {
56+
errno = ENAMETOOLONG;
57+
return -1;
58+
}
59+
60+
if (!getcwd(ctx->orig_dir, sizeof(ctx->orig_dir))) {
61+
errno = ENAMETOOLONG;
62+
return -1;
63+
}
64+
if (chdir_len(dir, slash - dir) < 0)
65+
return -1;
66+
}
67+
1768
memset(sa, 0, sizeof(*sa));
1869
sa->sun_family = AF_UNIX;
1970
memcpy(sa->sun_path, path, size);
71+
return 0;
2072
}
2173

2274
int unix_stream_connect(const char *path)
2375
{
24-
int fd;
76+
int fd, saved_errno;
2577
struct sockaddr_un sa;
78+
struct unix_sockaddr_context ctx;
2679

27-
unix_sockaddr_init(&sa, path);
28-
fd = unix_stream_socket();
29-
if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
30-
close(fd);
80+
if (unix_sockaddr_init(&sa, path, &ctx) < 0)
3181
return -1;
32-
}
82+
fd = unix_stream_socket();
83+
if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0)
84+
goto fail;
85+
unix_sockaddr_cleanup(&ctx);
3386
return fd;
87+
88+
fail:
89+
saved_errno = errno;
90+
unix_sockaddr_cleanup(&ctx);
91+
close(fd);
92+
errno = saved_errno;
93+
return -1;
3494
}
3595

3696
int unix_stream_listen(const char *path)
3797
{
38-
int fd;
98+
int fd, saved_errno;
3999
struct sockaddr_un sa;
100+
struct unix_sockaddr_context ctx;
40101

41-
unix_sockaddr_init(&sa, path);
102+
if (unix_sockaddr_init(&sa, path, &ctx) < 0)
103+
return -1;
42104
fd = unix_stream_socket();
43105

44106
unlink(path);
45-
if (bind(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
46-
close(fd);
47-
return -1;
48-
}
107+
if (bind(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0)
108+
goto fail;
49109

50-
if (listen(fd, 5) < 0) {
51-
close(fd);
52-
return -1;
53-
}
110+
if (listen(fd, 5) < 0)
111+
goto fail;
54112

113+
unix_sockaddr_cleanup(&ctx);
55114
return fd;
115+
116+
fail:
117+
saved_errno = errno;
118+
unix_sockaddr_cleanup(&ctx);
119+
close(fd);
120+
errno = saved_errno;
121+
return -1;
56122
}

0 commit comments

Comments
 (0)