summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--git-compat-util.h7
-rw-r--r--wrapper.c16
2 files changed, 23 insertions, 0 deletions
diff --git a/git-compat-util.h b/git-compat-util.h
index 838246289c..fd99eaeb6d 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -1231,6 +1231,13 @@ int access_or_die(const char *path, int mode, unsigned flag);
/* Warn on an inaccessible file if errno indicates this is an error */
int warn_on_fopen_errors(const char *path);
+/*
+ * Open with O_NOFOLLOW, or equivalent. Note that the fallback equivalent
+ * may be racy. Do not use this as protection against an attacker who can
+ * simultaneously create paths.
+ */
+int open_nofollow(const char *path, int flags);
+
#if !defined(USE_PARENS_AROUND_GETTEXT_N) && defined(__GNUC__)
#define USE_PARENS_AROUND_GETTEXT_N 1
#endif
diff --git a/wrapper.c b/wrapper.c
index bcda41e374..563ad590df 100644
--- a/wrapper.c
+++ b/wrapper.c
@@ -678,3 +678,19 @@ int is_empty_or_missing_file(const char *filename)
return !st.st_size;
}
+
+int open_nofollow(const char *path, int flags)
+{
+#ifdef O_NOFOLLOW
+ return open(path, flags | O_NOFOLLOW);
+#else
+ struct stat st;
+ if (lstat(path, &st) < 0)
+ return -1;
+ if (S_ISLNK(st.st_mode)) {
+ errno = ELOOP;
+ return -1;
+ }
+ return open(path, flags);
+#endif
+}