X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=sha1_file.c;h=8bebbb255f762fc36f165b87023d8cc37732968a;hb=36de72aa9dc3b7daf8cf2770c840f39bb0d2ae70;hp=d451a94efed7d36d55cf1b77324eaf55e0d50d69;hpb=c10d63451883f67c37622d2a21b2fc93be2f90c9;p=git.git diff --git a/sha1_file.c b/sha1_file.c index d451a94e..8bebbb25 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -48,6 +48,29 @@ int get_sha1_hex(const char *hex, unsigned char *sha1) return 0; } +int adjust_shared_perm(const char *path) +{ + struct stat st; + int mode; + + if (!shared_repository) + return 0; + if (lstat(path, &st) < 0) + return -1; + mode = st.st_mode; + if (mode & S_IRUSR) + mode |= S_IRGRP; + if (mode & S_IWUSR) + mode |= S_IWGRP; + if (mode & S_IXUSR) + mode |= S_IXGRP; + if (S_ISDIR(mode)) + mode |= S_ISGID; + if (chmod(path, mode) < 0) + return -2; + return 0; +} + int safe_create_leading_directories(char *path) { char *pos = path; @@ -59,11 +82,16 @@ int safe_create_leading_directories(char *path) if (!pos) break; *pos = 0; - if (mkdir(path, 0777) < 0) + if (mkdir(path, 0777) < 0) { if (errno != EEXIST) { *pos = '/'; return -1; } + } + else if (adjust_shared_perm(path)) { + *pos = '/'; + return -2; + } *pos++ = '/'; } return 0; @@ -321,12 +349,16 @@ struct packed_git *packed_git; static int check_packed_git_idx(const char *path, unsigned long *idx_size_, void **idx_map_) { + SHA_CTX ctx; + unsigned char sha1[20]; void *idx_map; unsigned int *index; unsigned long idx_size; int nr, i; - int fd = open(path, O_RDONLY); + int fd; struct stat st; + + fd = open(path, O_RDONLY); if (fd < 0) return -1; if (fstat(fd, &st)) { @@ -364,6 +396,16 @@ static int check_packed_git_idx(const char *path, unsigned long *idx_size_, if (idx_size != 4*256 + nr * 24 + 20 + 20) return error("wrong index file size"); + /* + * File checksum. + */ + SHA1_Init(&ctx); + SHA1_Update(&ctx, idx_map, idx_size-20); + SHA1_Final(sha1, &ctx); + + if (memcmp(sha1, idx_map + idx_size - 20, 20)) + return error("index checksum mismatch"); + return 0; } @@ -1241,6 +1283,8 @@ static int link_temp_to_file(const char *tmpfile, char *filename) if (dir) { *dir = 0; mkdir(filename, 0777); + if (adjust_shared_perm(filename)) + return -2; *dir = '/'; if (!link(tmpfile, filename)) return 0;