Skip to content

Commit 6290ce4

Browse files
committed
parse: Take umask into account in parse_mode()
POSIX 2024 clarified that find(1) is meant to work exactly like chmod(1) here, so for modes like +rw,-x with no "who" specified, apply the umask. Link: https://www.austingroupbugs.net/view.php?id=1392
1 parent b8a008d commit 6290ce4

File tree

7 files changed

+43
-10
lines changed

7 files changed

+43
-10
lines changed

src/ctx.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ struct bfs_ctx *bfs_ctx_new(void) {
5252

5353
trie_init(&ctx->files);
5454

55+
ctx->umask = umask(0);
56+
umask(ctx->umask);
57+
5558
if (getrlimit(RLIMIT_NOFILE, &ctx->orig_nofile) != 0) {
5659
goto fail;
5760
}

src/ctx.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "trie.h"
1717
#include <stddef.h>
1818
#include <sys/resource.h>
19+
#include <sys/types.h>
1920
#include <time.h>
2021

2122
struct CFILE;
@@ -98,6 +99,9 @@ struct bfs_ctx {
9899
/** The number of files owned by the context. */
99100
int nfiles;
100101

102+
/** The current file creation mask. */
103+
mode_t umask;
104+
101105
/** The initial RLIMIT_NOFILE limits. */
102106
struct rlimit orig_nofile;
103107
/** The current RLIMIT_NOFILE limits. */

src/parse.c

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1901,6 +1901,8 @@ static int parse_mode(const struct bfs_parser *parser, const char *mode, struct
19011901
return 0;
19021902
}
19031903

1904+
mode_t umask = parser->ctx->umask;
1905+
19041906
expr->file_mode = 0;
19051907
expr->dir_mode = 0;
19061908

@@ -1938,6 +1940,7 @@ static int parse_mode(const struct bfs_parser *parser, const char *mode, struct
19381940
} op uninit(MODE_EQUALS);
19391941

19401942
mode_t who uninit(0);
1943+
mode_t mask uninit(0);
19411944
mode_t file_change uninit(0);
19421945
mode_t dir_change uninit(0);
19431946

@@ -1946,6 +1949,7 @@ static int parse_mode(const struct bfs_parser *parser, const char *mode, struct
19461949
switch (state) {
19471950
case MODE_CLAUSE:
19481951
who = 0;
1952+
mask = 0777;
19491953
state = MODE_WHO;
19501954
fallthru;
19511955

@@ -1989,6 +1993,9 @@ static int parse_mode(const struct bfs_parser *parser, const char *mode, struct
19891993
case MODE_ACTION:
19901994
if (who == 0) {
19911995
who = 0777;
1996+
mask = who & ~umask;
1997+
} else {
1998+
mask = who;
19921999
}
19932000

19942001
switch (*i) {
@@ -2048,27 +2055,27 @@ static int parse_mode(const struct bfs_parser *parser, const char *mode, struct
20482055
}
20492056

20502057
file_change |= (file_change << 6) | (file_change << 3);
2051-
file_change &= who;
2058+
file_change &= mask;
20522059
dir_change |= (dir_change << 6) | (dir_change << 3);
2053-
dir_change &= who;
2060+
dir_change &= mask;
20542061
state = MODE_ACTION_APPLY;
20552062
break;
20562063

20572064
case MODE_PERM:
20582065
switch (*i) {
20592066
case 'r':
2060-
file_change |= who & 0444;
2061-
dir_change |= who & 0444;
2067+
file_change |= mask & 0444;
2068+
dir_change |= mask & 0444;
20622069
break;
20632070
case 'w':
2064-
file_change |= who & 0222;
2065-
dir_change |= who & 0222;
2071+
file_change |= mask & 0222;
2072+
dir_change |= mask & 0222;
20662073
break;
20672074
case 'x':
2068-
file_change |= who & 0111;
2075+
file_change |= mask & 0111;
20692076
fallthru;
20702077
case 'X':
2071-
dir_change |= who & 0111;
2078+
dir_change |= mask & 0111;
20722079
break;
20732080
case 's':
20742081
if (who & 0700) {
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1-
perms/drwxrwxrwx
2-
perms/frwxrwxrwx
1+
perms
2+
perms/drwxr-xr-x
3+
perms/frwxr-xr-x
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,7 @@
1+
perms
2+
perms/drwxr-xr-x
3+
perms/drwxrwxr-x
14
perms/drwxrwxrwx
5+
perms/frwxr-xr-x
6+
perms/frwxrwxr-x
27
perms/frwxrwxrwx
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
perms/drwxrwxr-x
2+
perms/drwxrwxrwx
3+
perms/f-w--w----
4+
perms/f-w--w--w-
5+
perms/f-wx-wx--x
6+
perms/f-wx-wx-wx
7+
perms/frw-rw-r--
8+
perms/frw-rw-rw-
9+
perms/frwxrwxr-x
10+
perms/frwxrwxrwx
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Test for https://www.austingroupbugs.net/view.php?id=1392
2+
umask 002
3+
bfs_diff perms -perm -+w

0 commit comments

Comments
 (0)