aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2017-04-23 22:07:57 -0700
committerJunio C Hamano <gitster@pobox.com>2017-04-23 22:07:57 -0700
commit5938454cbc585e0f4bdd9f1cc87c6886a3c1bff3 (patch)
tree72bb28f592f0b3207fcfb25f243287ca6e4b18c3
parent2d646e3e1fd0ae7f525034abee73d06ac8946729 (diff)
parent5781a9a2703e96b01587bb95ceebcc53f2cee91c (diff)
downloadgit-5938454cbc585e0f4bdd9f1cc87c6886a3c1bff3.tar.gz
git-5938454cbc585e0f4bdd9f1cc87c6886a3c1bff3.tar.xz
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)
-rw-r--r--builtin/gc.c12
-rw-r--r--builtin/receive-pack.c4
-rw-r--r--daemon.c4
-rw-r--r--fetch-pack.c4
-rw-r--r--git-compat-util.h6
-rw-r--r--ident.c4
-rw-r--r--wrapper.c13
7 files changed, 33 insertions, 14 deletions
diff --git a/builtin/gc.c b/builtin/gc.c
index 2daede782..91f7696a8 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -232,7 +232,7 @@ static int need_to_gc(void)
static const char *lock_repo_for_gc(int force, pid_t* ret_pid)
{
static struct lock_file lock;
- char my_host[128];
+ char my_host[HOST_NAME_MAX + 1];
struct strbuf sb = STRBUF_INIT;
struct stat st;
uintmax_t pid;
@@ -244,15 +244,19 @@ static const char *lock_repo_for_gc(int force, pid_t* ret_pid)
/* already locked */
return NULL;
- if (gethostname(my_host, sizeof(my_host)))
+ if (xgethostname(my_host, sizeof(my_host)))
xsnprintf(my_host, sizeof(my_host), "unknown");
pidfile_path = git_pathdup("gc.pid");
fd = hold_lock_file_for_update(&lock, pidfile_path,
LOCK_DIE_ON_ERROR);
if (!force) {
- static char locking_host[128];
+ static char locking_host[HOST_NAME_MAX + 1];
+ static char *scan_fmt;
int should_exit;
+
+ if (!scan_fmt)
+ scan_fmt = xstrfmt("%s %%%dc", "%"SCNuMAX, HOST_NAME_MAX);
fp = fopen(pidfile_path, "r");
memset(locking_host, 0, sizeof(locking_host));
should_exit =
@@ -268,7 +272,7 @@ static const char *lock_repo_for_gc(int force, pid_t* ret_pid)
* running.
*/
time(NULL) - st.st_mtime <= 12 * 3600 &&
- fscanf(fp, "%"SCNuMAX" %127c", &pid, locking_host) == 2 &&
+ fscanf(fp, scan_fmt, &pid, locking_host) == 2 &&
/* be gentle to concurrent "gc" on remote hosts */
(strcmp(locking_host, my_host) || !kill(pid, 0) || errno == EPERM);
if (fp != NULL)
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 7f484e7f6..f96834f42 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -1697,12 +1697,12 @@ static const char *unpack(int err_fd, struct shallow_info *si)
if (status)
return "unpack-objects abnormal exit";
} else {
- char hostname[256];
+ char hostname[HOST_NAME_MAX + 1];
argv_array_pushl(&child.args, "index-pack", "--stdin", NULL);
push_header_arg(&child.args, &hdr);
- if (gethostname(hostname, sizeof(hostname)))
+ if (xgethostname(hostname, sizeof(hostname)))
xsnprintf(hostname, sizeof(hostname), "localhost");
argv_array_pushf(&child.args,
"--keep=receive-pack %"PRIuMAX" on %s",
diff --git a/daemon.c b/daemon.c
index f70d27b82..ac7181a48 100644
--- a/daemon.c
+++ b/daemon.c
@@ -4,10 +4,6 @@
#include "strbuf.h"
#include "string-list.h"
-#ifndef HOST_NAME_MAX
-#define HOST_NAME_MAX 256
-#endif
-
#ifdef NO_INITGROUPS
#define initgroups(x, y) (0) /* nothing */
#endif
diff --git a/fetch-pack.c b/fetch-pack.c
index c5e686706..afb8b0502 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -804,8 +804,8 @@ static int get_pack(struct fetch_pack_args *args,
if (args->use_thin_pack)
argv_array_push(&cmd.args, "--fix-thin");
if (args->lock_pack || unpack_limit) {
- char hostname[256];
- if (gethostname(hostname, sizeof(hostname)))
+ char hostname[HOST_NAME_MAX + 1];
+ if (xgethostname(hostname, sizeof(hostname)))
xsnprintf(hostname, sizeof(hostname), "localhost");
argv_array_pushf(&cmd.args,
"--keep=fetch-pack %"PRIuMAX " on %s",
diff --git a/git-compat-util.h b/git-compat-util.h
index 8a4a3f85e..bd04564a6 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -884,6 +884,12 @@ static inline size_t xsize_t(off_t len)
__attribute__((format (printf, 3, 4)))
extern int xsnprintf(char *dst, size_t max, const char *fmt, ...);
+#ifndef HOST_NAME_MAX
+#define HOST_NAME_MAX 256
+#endif
+
+extern int xgethostname(char *buf, size_t len);
+
/* in ctype.c, for kwset users */
extern const unsigned char tolower_trans_tbl[256];
diff --git a/ident.c b/ident.c
index c0364fe3a..bea871c8e 100644
--- a/ident.c
+++ b/ident.c
@@ -120,9 +120,9 @@ static int canonical_name(const char *host, struct strbuf *out)
static void add_domainname(struct strbuf *out, int *is_bogus)
{
- char buf[1024];
+ char buf[HOST_NAME_MAX + 1];
- if (gethostname(buf, sizeof(buf))) {
+ if (xgethostname(buf, sizeof(buf))) {
warning_errno("cannot get host name");
strbuf_addstr(out, "(none)");
*is_bogus = 1;
diff --git a/wrapper.c b/wrapper.c
index 0542fc758..d83741770 100644
--- a/wrapper.c
+++ b/wrapper.c
@@ -655,3 +655,16 @@ void sleep_millisec(int millisec)
{
poll(NULL, 0, millisec);
}
+
+int xgethostname(char *buf, size_t len)
+{
+ /*
+ * If the full hostname doesn't fit in buf, POSIX does not
+ * specify whether the buffer will be null-terminated, so to
+ * be safe, do it ourselves.
+ */
+ int ret = gethostname(buf, len);
+ if (!ret)
+ buf[len - 1] = 0;
+ return ret;
+}