diff options
Diffstat (limited to 'git-compat-util.h')
-rw-r--r-- | git-compat-util.h | 102 |
1 files changed, 96 insertions, 6 deletions
diff --git a/git-compat-util.h b/git-compat-util.h index e50e2fafae..96293b6c43 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -197,12 +197,6 @@ #endif #include <windows.h> #define GIT_WINDOWS_NATIVE -#ifdef HAVE_RTLGENRANDOM -/* This is required to get access to RtlGenRandom. */ -#define SystemFunction036 NTAPI SystemFunction036 -#include <NTSecAPI.h> -#undef SystemFunction036 -#endif #endif #include <unistd.h> @@ -442,6 +436,69 @@ static inline int git_offset_1st_component(const char *path) #define is_valid_path(path) 1 #endif +#ifndef is_path_owned_by_current_user + +#ifdef __TANDEM +#define ROOT_UID 65535 +#else +#define ROOT_UID 0 +#endif + +/* + * Do not use this function when + * (1) geteuid() did not say we are running as 'root', or + * (2) using this function will compromise the system. + * + * PORTABILITY WARNING: + * This code assumes uid_t is unsigned because that is what sudo does. + * If your uid_t type is signed and all your ids are positive then it + * should all work fine. + * If your version of sudo uses negative values for uid_t or it is + * buggy and return an overflowed value in SUDO_UID, then git might + * fail to grant access to your repository properly or even mistakenly + * grant access to someone else. + * In the unlikely scenario this happened to you, and that is how you + * got to this message, we would like to know about it; so sent us an + * email to git@vger.kernel.org indicating which platform you are + * using and which version of sudo, so we can improve this logic and + * maybe provide you with a patch that would prevent this issue again + * in the future. + */ +static inline void extract_id_from_env(const char *env, uid_t *id) +{ + const char *real_uid = getenv(env); + + /* discard anything empty to avoid a more complex check below */ + if (real_uid && *real_uid) { + char *endptr = NULL; + unsigned long env_id; + + errno = 0; + /* silent overflow errors could trigger a bug here */ + env_id = strtoul(real_uid, &endptr, 10); + if (!*endptr && !errno) + *id = env_id; + } +} + +static inline int is_path_owned_by_current_uid(const char *path) +{ + struct stat st; + uid_t euid; + + if (lstat(path, &st)) + return 0; + + euid = geteuid(); + if (euid == ROOT_UID) + extract_id_from_env("SUDO_UID", &euid); + + return st.st_uid == euid; +} + +#define is_path_owned_by_current_user is_path_owned_by_current_uid +#endif + #ifndef find_last_dir_sep static inline char *git_find_last_dir_sep(const char *path) { @@ -531,6 +588,10 @@ void warning_errno(const char *err, ...) __attribute__((format (printf, 1, 2))); #include <openssl/x509v3.h> #endif /* NO_OPENSSL */ +#ifdef HAVE_OPENSSL_CSPRNG +#include <openssl/rand.h> +#endif + /* * Let callers be aware of the constant return value; this can help * gcc with -Wuninitialized analysis. We restrict this trick to gcc, though, @@ -1263,6 +1324,35 @@ __attribute__((format (printf, 3, 4))) NORETURN void BUG_fl(const char *file, int line, const char *fmt, ...); #define BUG(...) BUG_fl(__FILE__, __LINE__, __VA_ARGS__) +#ifdef __APPLE__ +#define FSYNC_METHOD_DEFAULT FSYNC_METHOD_WRITEOUT_ONLY +#else +#define FSYNC_METHOD_DEFAULT FSYNC_METHOD_FSYNC +#endif + +enum fsync_action { + FSYNC_WRITEOUT_ONLY, + FSYNC_HARDWARE_FLUSH +}; + +/* + * Issues an fsync against the specified file according to the specified mode. + * + * FSYNC_WRITEOUT_ONLY attempts to use interfaces available on some operating + * systems to flush the OS cache without issuing a flush command to the storage + * controller. If those interfaces are unavailable, the function fails with + * ENOSYS. + * + * FSYNC_HARDWARE_FLUSH does an OS writeout and hardware flush to ensure that + * changes are durable. It is not expected to fail. + */ +int git_fsync(int fd, enum fsync_action action); + +/* + * Writes out trace statistics for fsync using the trace2 API. + */ +void trace_git_fsync_stats(void); + /* * Preserves errno, prints a message, but gives no warning for ENOENT. * Returns 0 on success, which includes trying to unlink an object that does |