Skip to content

Commit 03a39a9

Browse files
committed
Merge branch 'jc/shared-literally'
* jc/shared-literally: t1301: loosen test for forced modes set_shared_perm(): sometimes we know what the final mode bits should look like move_temp_to_file(): do not forget to chmod() in "Coda hack" codepath Move chmod(foo, 0444) into move_temp_to_file() "core.sharedrepository = 0mode" should set, not loosen
2 parents ccc852c + 1b89eaa commit 03a39a9

File tree

10 files changed

+97
-38
lines changed

10 files changed

+97
-38
lines changed

builtin-init-db.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,8 @@ static int create_default_files(const char *template_path)
194194

195195
git_config(git_default_config, NULL);
196196
is_bare_repository_cfg = init_is_bare_repository;
197+
198+
/* reading existing config may have overwrote it */
197199
if (init_shared_repository != -1)
198200
shared_repository = init_shared_repository;
199201

@@ -312,12 +314,15 @@ int init_db(const char *template_dir, unsigned int flags)
312314
* and compatibility values for PERM_GROUP and
313315
* PERM_EVERYBODY.
314316
*/
315-
if (shared_repository == PERM_GROUP)
317+
if (shared_repository < 0)
318+
/* force to the mode value */
319+
sprintf(buf, "0%o", -shared_repository);
320+
else if (shared_repository == PERM_GROUP)
316321
sprintf(buf, "%d", OLD_PERM_GROUP);
317322
else if (shared_repository == PERM_EVERYBODY)
318323
sprintf(buf, "%d", OLD_PERM_EVERYBODY);
319324
else
320-
sprintf(buf, "0%o", shared_repository);
325+
die("oops");
321326
git_config_set("core.sharedrepository", buf);
322327
git_config_set("receive.denyNonFastforwards", "true");
323328
}
@@ -397,6 +402,9 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
397402
usage(init_db_usage);
398403
}
399404

405+
if (init_shared_repository != -1)
406+
shared_repository = init_shared_repository;
407+
400408
/*
401409
* GIT_WORK_TREE makes sense only in conjunction with GIT_DIR
402410
* without --bare. Catch the error early.

cache.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,8 @@ enum sharedrepo {
623623
PERM_EVERYBODY = 0664,
624624
};
625625
int git_config_perm(const char *var, const char *value);
626-
int adjust_shared_perm(const char *path);
626+
int set_shared_perm(const char *path, int mode);
627+
#define adjust_shared_perm(path) set_shared_perm((path), 0)
627628
int safe_create_leading_directories(char *path);
628629
int safe_create_leading_directories_const(const char *path);
629630
char *enter_repo(char *path, int strict);

fast-import.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -903,9 +903,6 @@ static char *keep_pack(char *curr_index_name)
903903
static const char *keep_msg = "fast-import";
904904
int keep_fd;
905905

906-
chmod(pack_data->pack_name, 0444);
907-
chmod(curr_index_name, 0444);
908-
909906
keep_fd = odb_pack_keep(name, sizeof(name), pack_data->sha1);
910907
if (keep_fd < 0)
911908
die("cannot create keep file");

http-push.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -748,7 +748,6 @@ static void finish_request(struct transfer_request *request)
748748
aborted = 1;
749749
}
750750
} else if (request->state == RUN_FETCH_LOOSE) {
751-
fchmod(request->local_fileno, 0444);
752751
close(request->local_fileno); request->local_fileno = -1;
753752

754753
if (request->curl_result != CURLE_OK &&

http-walker.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,6 @@ static void finish_object_request(struct object_request *obj_req)
231231
{
232232
struct stat st;
233233

234-
fchmod(obj_req->local, 0444);
235234
close(obj_req->local); obj_req->local = -1;
236235

237236
if (obj_req->http_code == 416) {

index-pack.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -823,8 +823,7 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
823823
}
824824
if (move_temp_to_file(curr_pack_name, final_pack_name))
825825
die("cannot store pack file");
826-
}
827-
if (from_stdin)
826+
} else if (from_stdin)
828827
chmod(final_pack_name, 0444);
829828

830829
if (final_index_name != curr_index_name) {
@@ -835,8 +834,8 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
835834
}
836835
if (move_temp_to_file(curr_index_name, final_index_name))
837836
die("cannot store index file");
838-
}
839-
chmod(final_index_name, 0444);
837+
} else
838+
chmod(final_index_name, 0444);
840839

841840
if (!from_stdin) {
842841
printf("%s\n", sha1_to_hex(sha1));

path.c

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -311,36 +311,49 @@ char *enter_repo(char *path, int strict)
311311
return NULL;
312312
}
313313

314-
int adjust_shared_perm(const char *path)
314+
int set_shared_perm(const char *path, int mode)
315315
{
316316
struct stat st;
317-
int mode;
317+
int tweak, shared, orig_mode;
318318

319-
if (!shared_repository)
319+
if (!shared_repository) {
320+
if (mode)
321+
return chmod(path, mode & ~S_IFMT);
320322
return 0;
321-
if (lstat(path, &st) < 0)
322-
return -1;
323-
mode = st.st_mode;
324-
325-
if (shared_repository) {
326-
int tweak = shared_repository;
327-
if (!(mode & S_IWUSR))
328-
tweak &= ~0222;
329-
mode |= tweak;
330-
} else {
331-
/* Preserve old PERM_UMASK behaviour */
332-
if (mode & S_IWUSR)
333-
mode |= S_IWGRP;
334323
}
324+
if (!mode) {
325+
if (lstat(path, &st) < 0)
326+
return -1;
327+
mode = st.st_mode;
328+
orig_mode = mode;
329+
} else
330+
orig_mode = 0;
331+
if (shared_repository < 0)
332+
shared = -shared_repository;
333+
else
334+
shared = shared_repository;
335+
tweak = shared;
336+
337+
if (!(mode & S_IWUSR))
338+
tweak &= ~0222;
339+
if (mode & S_IXUSR)
340+
/* Copy read bits to execute bits */
341+
tweak |= (tweak & 0444) >> 2;
342+
if (shared_repository < 0)
343+
mode = (mode & ~0777) | tweak;
344+
else
345+
mode |= tweak;
335346

336347
if (S_ISDIR(mode)) {
337-
mode |= FORCE_DIR_SET_GID;
338-
339348
/* Copy read bits to execute bits */
340-
mode |= (shared_repository & 0444) >> 2;
349+
mode |= (shared & 0444) >> 2;
350+
mode |= FORCE_DIR_SET_GID;
341351
}
342352

343-
if ((mode & st.st_mode) != mode && chmod(path, mode) < 0)
353+
if (((shared_repository < 0
354+
? (orig_mode & (FORCE_DIR_SET_GID | 0777))
355+
: (orig_mode & mode)) != mode) &&
356+
chmod(path, (mode & ~S_IFMT)) < 0)
344357
return -2;
345358
return 0;
346359
}

setup.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ int git_config_perm(const char *var, const char *value)
434434

435435
/*
436436
* Treat values 0, 1 and 2 as compatibility cases, otherwise it is
437-
* a chmod value.
437+
* a chmod value to restrict to.
438438
*/
439439
switch (i) {
440440
case PERM_UMASK: /* 0 */
@@ -456,7 +456,7 @@ int git_config_perm(const char *var, const char *value)
456456
* Mask filemode value. Others can not get write permission.
457457
* x flags for directories are handled separately.
458458
*/
459-
return i & 0666;
459+
return -(i & 0666);
460460
}
461461

462462
int check_repository_format_version(const char *var, const char *value, void *cb)

sha1_file.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2216,11 +2216,15 @@ static void write_sha1_file_prepare(const void *buf, unsigned long len,
22162216
}
22172217

22182218
/*
2219-
* Move the just written object into its final resting place
2219+
* Move the just written object into its final resting place.
2220+
* NEEDSWORK: this should be renamed to finalize_temp_file() as
2221+
* "moving" is only a part of what it does, when no patch between
2222+
* master to pu changes the call sites of this function.
22202223
*/
22212224
int move_temp_to_file(const char *tmpfile, const char *filename)
22222225
{
22232226
int ret = 0;
2227+
22242228
if (link(tmpfile, filename))
22252229
ret = errno;
22262230

@@ -2232,12 +2236,12 @@ int move_temp_to_file(const char *tmpfile, const char *filename)
22322236
*
22332237
* The same holds for FAT formatted media.
22342238
*
2235-
* When this succeeds, we just return 0. We have nothing
2239+
* When this succeeds, we just return. We have nothing
22362240
* left to unlink.
22372241
*/
22382242
if (ret && ret != EEXIST) {
22392243
if (!rename(tmpfile, filename))
2240-
return 0;
2244+
goto out;
22412245
ret = errno;
22422246
}
22432247
unlink(tmpfile);
@@ -2248,6 +2252,9 @@ int move_temp_to_file(const char *tmpfile, const char *filename)
22482252
/* FIXME!!! Collision check here ? */
22492253
}
22502254

2255+
out:
2256+
if (set_shared_perm(filename, (S_IFREG|0444)))
2257+
return error("unable to set permission to '%s'", filename);
22512258
return 0;
22522259
}
22532260

@@ -2272,7 +2279,6 @@ static void close_sha1_file(int fd)
22722279
{
22732280
if (fsync_object_files)
22742281
fsync_or_die(fd, "sha1 file");
2275-
fchmod(fd, 0444);
22762282
if (close(fd) != 0)
22772283
die("error when closing sha1 file (%s)", strerror(errno));
22782284
}

t/t1301-shared-repo.sh

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,4 +126,41 @@ test_expect_success POSIXPERM 'git reflog expire honors core.sharedRepository' '
126126
esac
127127
'
128128

129+
test_expect_success 'forced modes' '
130+
mkdir -p templates/hooks &&
131+
echo update-server-info >templates/hooks/post-update &&
132+
chmod +x templates/hooks/post-update &&
133+
echo : >random-file &&
134+
mkdir new &&
135+
(
136+
cd new &&
137+
umask 002 &&
138+
git init --shared=0660 --template=../templates &&
139+
>frotz &&
140+
git add frotz &&
141+
git commit -a -m initial &&
142+
git repack
143+
) &&
144+
find new/.git -print |
145+
xargs ls -ld >actual &&
146+
147+
# Everything must be unaccessible to others
148+
test -z "$(sed -n -e "/^.......---/d" actual)" &&
149+
150+
# All directories must have either 2770 or 770
151+
test -z "$(sed -n -e "/^drwxrw[sx]---/d" -e "/^d/p" actual)" &&
152+
153+
# post-update hook must be 0770
154+
test -z "$(sed -n -e "/post-update/{
155+
/^-rwxrwx---/d
156+
p
157+
}" actual)" &&
158+
159+
# All files inside objects must be 0440
160+
test -z "$(sed -n -e "/objects\//{
161+
/^d/d
162+
/^-r--r-----/d
163+
}" actual)"
164+
'
165+
129166
test_done

0 commit comments

Comments
 (0)