Subject: Re: [RFC PATCH v2] git-compat-util: avoid failing dir ownership checks if running privileged

From: Junio C Hamano <[email-masked]>
Date: Wed, 27 Apr 2022 15:33:43 -0700

Carlo Marcelo Arenas Belón  <[email-masked]> writes:

> diff --git a/git-compat-util.h b/git-compat-util.h
> index 58fd813bd01..3c9883934f6 100644
> --- a/git-compat-util.h
> +++ b/git-compat-util.h
> @@ -437,12 +437,50 @@ static inline int git_offset_1st_component(const char *path)
>  #endif
>  
>  #ifndef is_path_owned_by_current_user
> +
> +#ifdef __TANDEM
> +#define ROOT_UID 65535
> +#else
> +#define ROOT_UID 0
> +#endif
> +
> +/*
> + * this helper function overrides a ROOT_UID with the one provided by
> + * an environment variable, do not use unless the original user is
> + * root
> + */
> +static inline void extract_id_from_env(const char *env, uid_t *id)
> +{
> +	const char *real_uid = getenv(env);
> +
> +	/* discard any empty values */
> +	if (real_uid && *real_uid) {
> +		char *endptr;
> +		unsigned long env_id;
> +		int saved_errno = errno;
> +
> +		errno = 0;
> +		env_id = strtoul(real_uid, &endptr, 10);
> +		if (!errno && !*endptr && env_id <= (uid_t)-1)
> +			*id = env_id;

So we refrain from touching *id when we cannot read from SUDO_UID;
let's make sure that the caller is prepared for that ...

> +		errno = saved_errno;
> +	}
> +}
> +
>  static inline int is_path_owned_by_current_uid(const char *path)
>  {
>  	struct stat st;
> +	uid_t euid;
> +
>  	if (lstat(path, &st))
>  		return 0;
> -	return st.st_uid == geteuid();
> +
> +	euid = geteuid();
> +	if (euid == ROOT_UID)
> +		extract_id_from_env("SUDO_UID", &euid);

... and it is.  euid is set to the real thing, and the tweak done by
the helper function may overwrite it only when the helper computed
a value without an error.

> +	return st.st_uid == euid;

OK.  Looking good.

Will queue.

>  }
>  
>  #define is_path_owned_by_current_user is_path_owned_by_current_uid