@@ -433,12 +433,68 @@ static inline int git_offset_1st_component(const char *path)
433433#endif
434434
435435#ifndef is_path_owned_by_current_user
436+
437+ #ifdef __TANDEM
438+ #define ROOT_UID 65535
439+ #else
440+ #define ROOT_UID 0
441+ #endif
442+
443+ /*
444+ * Do not use this function when
445+ * (1) geteuid() did not say we are running as 'root', or
446+ * (2) using this function will compromise the system.
447+ *
448+ * PORTABILITY WARNING:
449+ * This code assumes uid_t is unsigned because that is what sudo does.
450+ * If your uid_t type is signed and all your ids are positive then it
451+ * should all work fine.
452+ * If your version of sudo uses negative values for uid_t or it is
453+ * buggy and return an overflowed value in SUDO_UID, then git might
454+ * fail to grant access to your repository properly or even mistakenly
455+ * grant access to someone else.
456+ * In the unlikely scenario this happened to you, and that is how you
457+ * got to this message, we would like to know about it; so sent us an
458+ * email to [email protected] indicating which platform you are 459+ * using and which version of sudo, so we can improve this logic and
460+ * maybe provide you with a patch that would prevent this issue again
461+ * in the future.
462+ */
463+ static inline void extract_id_from_env (const char * env , uid_t * id )
464+ {
465+ const char * real_uid = getenv (env );
466+
467+ /* discard anything empty to avoid a more complex check below */
468+ if (real_uid && * real_uid ) {
469+ char * endptr = NULL ;
470+ unsigned long env_id ;
471+
472+ errno = 0 ;
473+ /* silent overflow errors could trigger a bug here */
474+ env_id = strtoul (real_uid , & endptr , 10 );
475+ if (!* endptr && !errno )
476+ * id = env_id ;
477+ }
478+ }
479+
436480static inline int is_path_owned_by_current_uid (const char * path )
437481{
438482 struct stat st ;
483+ uid_t euid ;
484+
439485 if (lstat (path , & st ))
440486 return 0 ;
441- return st .st_uid == geteuid ();
487+
488+ euid = geteuid ();
489+ if (euid == ROOT_UID )
490+ {
491+ if (st .st_uid == ROOT_UID )
492+ return 1 ;
493+ else
494+ extract_id_from_env ("SUDO_UID" , & euid );
495+ }
496+
497+ return st .st_uid == euid ;
442498}
443499
444500#define is_path_owned_by_current_user is_path_owned_by_current_uid
0 commit comments