Skip to content

Commit 5938454

Browse files
committed
Merge branch 'dt/xgethostname-nul-termination'
gethostname(2) may not NUL terminate the buffer if hostname does not fit; unfortunately there is no easy way to see if our buffer was too small, but at least this will make sure we will not end up using garbage past the end of the buffer. * dt/xgethostname-nul-termination: xgethostname: handle long hostnames use HOST_NAME_MAX to size buffers for gethostname(2)
2 parents 2d646e3 + 5781a9a commit 5938454

File tree

7 files changed

+33
-14
lines changed

7 files changed

+33
-14
lines changed

builtin/gc.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ static int need_to_gc(void)
232232
static const char *lock_repo_for_gc(int force, pid_t* ret_pid)
233233
{
234234
static struct lock_file lock;
235-
char my_host[128];
235+
char my_host[HOST_NAME_MAX + 1];
236236
struct strbuf sb = STRBUF_INIT;
237237
struct stat st;
238238
uintmax_t pid;
@@ -244,15 +244,19 @@ static const char *lock_repo_for_gc(int force, pid_t* ret_pid)
244244
/* already locked */
245245
return NULL;
246246

247-
if (gethostname(my_host, sizeof(my_host)))
247+
if (xgethostname(my_host, sizeof(my_host)))
248248
xsnprintf(my_host, sizeof(my_host), "unknown");
249249

250250
pidfile_path = git_pathdup("gc.pid");
251251
fd = hold_lock_file_for_update(&lock, pidfile_path,
252252
LOCK_DIE_ON_ERROR);
253253
if (!force) {
254-
static char locking_host[128];
254+
static char locking_host[HOST_NAME_MAX + 1];
255+
static char *scan_fmt;
255256
int should_exit;
257+
258+
if (!scan_fmt)
259+
scan_fmt = xstrfmt("%s %%%dc", "%"SCNuMAX, HOST_NAME_MAX);
256260
fp = fopen(pidfile_path, "r");
257261
memset(locking_host, 0, sizeof(locking_host));
258262
should_exit =
@@ -268,7 +272,7 @@ static const char *lock_repo_for_gc(int force, pid_t* ret_pid)
268272
* running.
269273
*/
270274
time(NULL) - st.st_mtime <= 12 * 3600 &&
271-
fscanf(fp, "%"SCNuMAX" %127c", &pid, locking_host) == 2 &&
275+
fscanf(fp, scan_fmt, &pid, locking_host) == 2 &&
272276
/* be gentle to concurrent "gc" on remote hosts */
273277
(strcmp(locking_host, my_host) || !kill(pid, 0) || errno == EPERM);
274278
if (fp != NULL)

builtin/receive-pack.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1697,12 +1697,12 @@ static const char *unpack(int err_fd, struct shallow_info *si)
16971697
if (status)
16981698
return "unpack-objects abnormal exit";
16991699
} else {
1700-
char hostname[256];
1700+
char hostname[HOST_NAME_MAX + 1];
17011701

17021702
argv_array_pushl(&child.args, "index-pack", "--stdin", NULL);
17031703
push_header_arg(&child.args, &hdr);
17041704

1705-
if (gethostname(hostname, sizeof(hostname)))
1705+
if (xgethostname(hostname, sizeof(hostname)))
17061706
xsnprintf(hostname, sizeof(hostname), "localhost");
17071707
argv_array_pushf(&child.args,
17081708
"--keep=receive-pack %"PRIuMAX" on %s",

daemon.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,6 @@
44
#include "strbuf.h"
55
#include "string-list.h"
66

7-
#ifndef HOST_NAME_MAX
8-
#define HOST_NAME_MAX 256
9-
#endif
10-
117
#ifdef NO_INITGROUPS
128
#define initgroups(x, y) (0) /* nothing */
139
#endif

fetch-pack.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -804,8 +804,8 @@ static int get_pack(struct fetch_pack_args *args,
804804
if (args->use_thin_pack)
805805
argv_array_push(&cmd.args, "--fix-thin");
806806
if (args->lock_pack || unpack_limit) {
807-
char hostname[256];
808-
if (gethostname(hostname, sizeof(hostname)))
807+
char hostname[HOST_NAME_MAX + 1];
808+
if (xgethostname(hostname, sizeof(hostname)))
809809
xsnprintf(hostname, sizeof(hostname), "localhost");
810810
argv_array_pushf(&cmd.args,
811811
"--keep=fetch-pack %"PRIuMAX " on %s",

git-compat-util.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -884,6 +884,12 @@ static inline size_t xsize_t(off_t len)
884884
__attribute__((format (printf, 3, 4)))
885885
extern int xsnprintf(char *dst, size_t max, const char *fmt, ...);
886886

887+
#ifndef HOST_NAME_MAX
888+
#define HOST_NAME_MAX 256
889+
#endif
890+
891+
extern int xgethostname(char *buf, size_t len);
892+
887893
/* in ctype.c, for kwset users */
888894
extern const unsigned char tolower_trans_tbl[256];
889895

ident.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,9 @@ static int canonical_name(const char *host, struct strbuf *out)
120120

121121
static void add_domainname(struct strbuf *out, int *is_bogus)
122122
{
123-
char buf[1024];
123+
char buf[HOST_NAME_MAX + 1];
124124

125-
if (gethostname(buf, sizeof(buf))) {
125+
if (xgethostname(buf, sizeof(buf))) {
126126
warning_errno("cannot get host name");
127127
strbuf_addstr(out, "(none)");
128128
*is_bogus = 1;

wrapper.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,3 +655,16 @@ void sleep_millisec(int millisec)
655655
{
656656
poll(NULL, 0, millisec);
657657
}
658+
659+
int xgethostname(char *buf, size_t len)
660+
{
661+
/*
662+
* If the full hostname doesn't fit in buf, POSIX does not
663+
* specify whether the buffer will be null-terminated, so to
664+
* be safe, do it ourselves.
665+
*/
666+
int ret = gethostname(buf, len);
667+
if (!ret)
668+
buf[len - 1] = 0;
669+
return ret;
670+
}

0 commit comments

Comments
 (0)