2026/10/27 7:59:17

新建的文件为什么是 644:umask 减掉了哪几位

新建的文件为什么是 644:umask 减掉了哪几位 授权与合规声明本文全部操作对象均为自建隔离靶场本机容器或隔离虚拟机涉及安全测试的环节必须以取得合法授权为前提。未经授权的渗透测试违反《中华人民共和国网络安全法》与《刑法》相关条款须承担相应法律责任。本文只讲环境配置、版本对照与靶场隔离不含任何攻击步骤、利用载荷与绕过手法请勿将文中环境指向任何非自有系统。一、没设过的权限是从哪来的1.1 一个上传目录的现场靶场里有个上传目录部署时用普通账号把代码和目录一起拷上去跑起来之后上传接口一直报写入失败。第一反应是查权限。ls -ld看目录drwxr-xr-x属主是部署账号。再看目录里已有的文件清一色-rw-r--r--属主也是部署账号。而服务进程跑在另一个账号下对644的文件没有写权限对755的目录也没有写权限——755只给了「读」和「进入」没给「新建」。到这一步问题其实已经清楚了目录的属主不对服务进程不是属主落在 other 那一档只有r-x。修法是把属主或属组调对再按需给组写权限。但更值得追问的是另一件事。这个目录从建出来到现在没有人执行过chmod部署脚本里也没有。那么644和755这两个数字到底是谁定的1.2 权限不是被谁设过是创建那一刻算出来的多数人对权限的印象是「设出来的」要什么权限就chmod成什么。这个印象在修改已有文件时成立在新建时完全不成立。新建一个文件或目录权限是当场算出来的有三个参与者。第一个是调用方给的起始 mode。open()创建普通文件时通常传0666mkdir()建目录时通常传0777。这两个数字本身已经是「收着写」的结果0666里没有 x因为新建的普通文件默认不该可执行0777是目录的满值三位全开。第二个是进程的文件模式创建掩码file mode creation mask也就是 umask。它是进程级的属性跟着进程走也被子进程继承。第三个是内核按一条固定规则把前两者合起来算出最终权限。chmod改的是第三条的结果改不动前两条。所以「没人chmod过权限却是 644」这件事一点也不奇怪根本没轮到chmod出场。1.3 三个数字的来路把常见的几个新建动作摆在一起规律就出来了。新建什么谁在建起始 mode常见掩码结果普通文件open()、creat()、shell 的touch0666022644rw-r--r--目录mkdir()、mkdir -p0777022755rwxr-xr-x命名管道mkfifo()、mkfifo0666022644prw-r--r--这张表里「常见掩码」这一列是唯一会变的一列。起始 mode 由程序写死结果由掩码决定。同一台机器上两个不同的服务各自建出来的目录权限不一样差别通常就在这一列。要想复现现场先把这三样东西读出来。⚠️代码待验证# 路径与账号名按各自部署替换ls-ld/srv/www/uploadls-l/srv/www/uploadidwww-dataps-ouser-p$(pgrep-fnginx: worker|head-1)四行分别回答四个问题目录权限和属主是谁、里面已有文件的权限是什么、服务账号属于哪些组、服务进程实际以谁的身份在跑。这四行里有任何一行是猜的后面的结论都不作数。本章可以带走的一句新建时的权限是「起始 mode」被掩码清位算出来的不是谁设的chmod只改结果不改这条算式。二、umask 的语义置 1 的位被清掉2.1 POSIX 的那一句关于 umask 的语义POSIX 只有一句话但足够定案「Bit positions that are set in cmask are cleared in the mode of the created file.」这句话出自 POSIX.1-2017 的umask()描述段。逐字读在 cmask 里被 set置 1的位会在创建出来的文件的 mode 里被 cleared清掉。主语是 cmask也就是调用方传进来的掩码动作是清除受影响的位是「创建出来的文件的 mode」。所以umask 022的意思不是「给 group 和 other 设成r-x」而是「把 group 的 w 位和 other 的 w 位清掉」。这两句话在 022 这一组值上恰好指向同一个结果但它们是两回事换一组值就分道扬镳了。举个能立刻分辨的例子。起始 mode 是0666掩码022清掉两个 w剩644。起始 mode 是0644掩码还是022那两个 w 本来就不在清等于没清结果仍是644。如果 umask 是「赋权」0644起手就该被拉高成别的样子它没有。它只会做减法。这个区分不是文字游戏。把它当成「赋权」的人会自然推出两个错误结论一是以为umask 000等于「给所有人全部权限」其实它只是「什么都不清」最终拿到多少还得看起始 mode二是以为「换个小一点的 umask 就能把权限加上去」而实际上掩码只能让结果变小或不变永远变不大。2.2 用位图看清 022 到底做了什么九位上掩码里的 1 表示「这一位我不要」0 表示「这一位我不动」。位八进制权值022的这一位含义user r04000不动user w02000不动user x01000不动group r00400不动group w00201清掉group x00100不动other r00040不动other w00021清掉other x00010不动022 展开成二进制是三组000 010 0101 正好落在 group w 和 other w 两位上。user 那三位全是 0所以 022 对属主权限一点影响都没有——这就是为什么umask 022之后属主拿到的还是rwx或rw-。这张表还能顺手解释一个常见困惑为什么 022 下新建的目录是755而不是744。因为掩码只清 w不清 x而0777起手的目录三位 x 都在清完 w 之后 x 原样保留。顺着这张表往下推077、027、007这些值分别清哪几位也就一目了然了。077清掉 group 与 other 的全部六位027清 group 的 w 和 other 的三位007只清 other 的三位。2.3 特殊位S_ISVTX被忽略其余不归 POSIX 管截至 2026-10-26POSIX 的umask()页面已经更新到 Issue 8IEEE Std 1003.1-2024的措辞句子本身有微调把「Bit positions」改成了「Permission bit positions」「Permission bit positions that are set in cmask are cleared in the mode of the created file.」同一版还补了一句关于特殊位的处理「Only the file permission bits of cmask (see sys/stat.h) shall be used; the S_ISVTX bit shall be ignored, and the meaning of the other bits is implementation-defined.」这句话要按字面读。S_ISVTX这一位在 cmask 里是被忽略的除了它之外的其他非权限位语义是implementation-defined由实现自定。返回值那一侧也补了一句返回的旧掩码里S_ISVTX位是清零的。由此得出一个很实用的边界不要指望用 umask 去设 setuid、setgid 或 sticky 这类位。它不表达这些位。POSIX 只保证「九个权限位会被清」对特殊位要么明确忽略要么交给实现自定——这不是一条能写进部署脚本的规则。本章可以带走的一句umask 只会清位不会给位它管的是九个权限位特殊位不在其中。三、生效范围哪些调用受它管3.1 一份清单出自 POSIXPOSIX 没有含糊其辞它直接列了清单「The file mode creation mask of the process is used to turn off permission bits in the mode argument supplied during calls to the following functions: open(), openat(), creat(), mkdir(), mkdirat(), mkfifo(), and mkfifoat()」后面还另列了 XSI 选做部分的mknod()、mknodat()以及消息队列与信号量选做部分的mq_open()、sem_open()。函数干什么起始 mode 常见值open()/openat()带O_CREAT时创建普通文件0666creat()创建或截断一个文件0666mkdir()/mkdirat()创建目录0777mkfifo()/mkfifoat()创建命名管道0666mknod()/mknodat()XSI创建设备节点等特殊文件视类型而定mq_open()/sem_open()可选POSIX 消息队列、信号量视实现而定清单是穷举式的这一点很重要。不在清单里的操作不受 umask 约束。最典型的对照是chmod它改的是已经存在的 inode这时候掩码早就退场了改成什么就是什么不会再被清一遍。「改了chmod却不生效」这类现象原因在别处不在 umask本篇不展开只把边界划清umask 只在创建那一刻起作用之后再也不参与。清单还有一个容易漏掉的推论。mkdir -p一次建出多层目录时每一层都是在创建那一刻各自算一遍掩码算完就定了如果某一层已经存在那一层根本不参与计算——既不重建也不顺手改权限。所以「用mkdir -p补齐目录结构」这件事结果取决于每一层是新是旧不能假设最终状态整齐划一。3.2 open() 的原文与掩码的补集做按位与清单只说了「哪些函数受影响」具体怎么算要看open()的描述「the access permission bits (see sys/stat.h) of the file mode shall be set to the value of the argument following the oflag argument taken as type mode_t modified as follows: a bitwise AND is performed on the file-mode bits and the corresponding bits in the complement of the process’ file mode creation mask. Thus, all bits in the file mode whose corresponding bit in the file mode creation mask is set are cleared.」三个动作按顺序取 mode 参数里的权限位取掩码的补集两者按位与。「补集」这个词在二进制上就是逐位取反1 变 00 变 1。掩码022的补集在那九位上就是「除了 group w 和 other w 之外全开」。拿 mode 去和它按位与效果就是掩码里为 1 的位置被抹掉。后半句是第一句的白话版「Thus, all bits in the file mode whose corresponding bit in the file mode creation mask is set are cleared.」——mode 里那些「掩码对应位为 1」的位全被清掉。两句话说的是同一件事方向都是清不是给。0666 ~022这个写法就是这句话的直译。~是补集是按位与。3.3 mkdir() 没有豁免有人以为目录是特殊的比如「目录必须有 x所以 umask 对目录不生效」。mkdir()的描述把这条路堵死了「The file permission bits of the new directory shall be initialized from mode. These file permission bits of the mode argument shall be modified by the process’ file creation mask.」从 mode 初始化再被掩码修改。两句和open()一个套路没有「目录除外」这一条。所以777 ~022 755与666 ~022 644是同一个规则的两个实例区别只在起始 mode。目录确实需要 x 才能进入但那是目录搜索权限的要求不是 umask 加上去的——umask 在这里只是没把 x 清掉而已。这两件事经常被混成一句「umask 保证目录可进入」那是错的umask 077出来的目录是700属主能进别人进不去umask 一点都没打算「保证可进入」。本章可以带走的一句受 umask 约束的是一份明确的函数清单清单外的操作不受影响目录和文件走同一条规则只是起始 mode 不同。四、0666 ~022 0644这条等式就写在原文里4.1 man-pages 自己算了一遍上面那条等式不是我推的Linux man-pages 的umask(2)自己写了一遍还带上前提「The typical default value for the process umask is S_IWGRP | S_IWOTH (octal 022). In the usual case where the mode argument to open(2) is specified as: S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH (octal 0666) when creating a new file, the permissions on the resulting file will be: S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH (because 0666 ~022 0644; i.e., rw-r–r–).」这段话里有三处需要咬住。第一处是typical default。原文说的是「典型的默认值」不是「规定的默认值」。所以正确的说法是「常见默认 022」不是「Linux 规定 022」。这个区别有实际后果容器镜像、systemd 单元、某些服务的启动脚本都可能把掩码改成别的值而你如果相信「规定就是 022」就会在一次排查里绕远路。至于某个发行版的登录 shell 究竟从哪个文件读到 022本篇不给结论——不同发行版、不同 shell 的配置来源不一样这一点需要查各自文档本条待验证。第二处是括号里的because 0666 ~022 0644。这是原文里的等式可以照抄也可以当作验算的锚点。第三处是结尾的i.e., rw-r--r--。原文把八进制和符号写法并排放在一起等于替你把「数字 → 位 → 可读形式」这条链走完了一遍。4.2 目录从 0777 起算同一条规则换个起始 mode 就是目录的答案777 ~022 755。为什么目录起始是0777而不是0666因为目录的 x 位不是「执行」是「进入/搜索」没有它连目录里的文件名都列不出来。所以目录的满值是三位全开再由掩码去清。把两组起始 mode 和两组掩码交叉起来四个结果一次看全起始 mode掩码结果符号形式典型场景0666022644rw-r--r--普通文件常见默认0666077600rw-------私钥、凭据文件0777022755rwxr-xr-x站点目录、可执行目录0777077700rwx------只给属主用的私有目录这张表的用法是反过来查先看结果不对再问「起始 mode 是多少、掩码是多少」两个变量里改哪一个答案不一样。改起始 mode 要动代码或命令参数改掩码只需在创建前设一次。再补一格用来验算 7.1 那张场景表777 ~027 750。022 到 027 看着只差一位实际把 other 的 r 和 x 也一起清掉了于是 other 那一档从r-x变成---目录从755掉到750。这种「只差一点点」的对照比背一堆数字管用。4.3 一个容易被忽略的前提掩码只影响「位」不影响类型ls -l第一列有十个字符第一位是类型-普通文件、d目录、p管道后九位才是权限。umask 只作用于后九位。这意味着两件事。一是「umask 能把文件变成目录」这种想法不成立类型由调用的函数决定跟掩码无关。二是判断一个文件的权限先看类型位再看九位权限别把d当成权限的一部分读进去。本章可以带走的一句0666 ~022 0644是 man-pages 原文里的等式777 ~022 755是同一条规则换了个起始 mode「022」是典型默认值不是谁的规定。五、本机实测022 与 077 两组对照下面三段输出是 2026-10-26 在 macOSDarwin 27.0.0arm64上原样跑出来的没有做任何修饰。5.1 先读当前值数字与符号互为补集$umask022 $umask-Surwx,grx,orx这两行放在一起看是最省事的一次观念纠正。umask不带参数打印的是被清掉的位022也就是 group w 和 other w。umask -S打印的是允许的权限urwx,grx,orx。两者互为补集——022里为 1 的两位在-S的输出里正好缺失grx没有 worx没有 w022里为 0 的位在-S里全都出现了。所以022从来不是「权限值 022」它是「要清掉的那几位的编号」。把它当成权限值去读会得出「022 表示属主什么都没有」这种荒唐结论。5.2 022 下新建文件 644目录 755$touch/tmp/t_umask_testls-l/tmp/t_umask_test -rw-r--r--1wzk wheel0Oct2606:13 /tmp/t_umask_test $mkdir/tmp/d_umask_testls-ld/tmp/d_umask_test drwxr-xr-x2wzk wheel64Oct2606:13 /tmp/d_umask_test-rw-r--r--就是644drwxr-xr-x就是755与第四章那两条等式逐位对得上666 ~022 644、777 ~022 755。输出里那个需要说明一句它是 macOS 的扩展属性标记表示这个文件带有附加属性与权限无关不要读成权限符号。在别家的ls上可能完全不出现。5.3 077 下新建600 与 700然后显式恢复这一段落在一个括号里跑因为括号会开一个子 shell改完不影响外层第六章会讲为什么这一点很关键。$(umask 077;umask;umask-S;touch/tmp/t_umask_077;mkdir/tmp/d_umask_077;ls-l/tmp/t_umask_077;ls-ld/tmp/d_umask_077)077urwx,g,o-rw-------1wzk wheel0Oct2606:13 /tmp/t_umask_077 drwx------2wzk wheel64Oct2606:13 /tmp/d_umask_077 $umask022;umask022四处值得对照。第一umask -S在 077 下显示成urwx,g,ogroup 和 other 后面是空的不是g---。这个空和 5.1 的grx摆在一起就能直观看出 077 清得比 022 狠得多。第二文件是-rw-------即600对上666 ~077 600目录是drwx------即700对上777 ~077 700。第三整个括号里的改动没有漏到外层——否则最后那行umask会打出 077。第四最后一步是显式执行umask 022恢复。这一步在真机上必须做不能省。掩码是进程级状态077留在当前 shell 里不会自己回去一旦忘了恢复这个终端后面建的每个文件都会是600而且不报错只在某天发现同事读不了文件时才暴露。四行输出对照下来的结论只有一句起始 mode 不变只动掩码九位权限就整体跟着动。文件从644掉到600目录从755掉到700umask -S从grx,orx掉到g,o三处变化指向同一个原因。这就是为什么「默认权限」这件事的开关在掩码上而不在代码里。完整的掩码取值对照表这份资料把 000 到 077 常见取值对应的文件/目录结果、以及每种取值清掉了哪几位做成一页可查的表和本章两组实测一一对应。放在资料包里扫码即可获取六、shell 里的 umask 与系统调用不是一回事6.1 两个对象两层作用域日常说的「umask」其实指两样东西作用域不同。一样是 shell 的umaskPOSIX 把它定义成一个工具作用对象是 shell 环境「The umask utility shall set the file mode creation mask of the current shell execution environment (see Shell Execution Environment) to the value specified by the mask operand.」紧接着一句说明它的效果「This mask shall affect the initial value of the file permission bits of subsequently created files.」另一样是umask()这个系统调用作用对象是进程「The umask() function shall set the file mode creation mask of the process to cmask and return the previous value of the mask.」一个改的是「shell 执行环境」一个改的是「进程」。二者的关系是shell 自己也是一个进程你在 shell 里敲umask 027它最终就是通过系统调用把这个进程的掩码改掉但这个改动只活在这个 shell 进程以及它之后 fork 出来的子进程里shell 一退出就没了。对比项shell 的umaskumask()系统调用是什么POSIX 定义的命令/内建内核提供的接口作用对象当前 shell 执行环境调用它的那个进程生效范围该 shell 及其后续子进程该进程及其子进程生命周期shell 退出即消失进程退出即消失怎么查询umask不带参数返回值是旧掩码影响谁之后由该 shell 创建的文件之后由该进程创建的文件表里最后两行是排查时最常用的你想知道「现在是多少」在 shell 里敲umask就行你想知道「某个服务建出来的文件会是多少」得去看那个服务进程自己的掩码而不是你终端里的那个。这一点经常被忽略。登进机器umask打出022就以为「系统是 022」。可服务不是从这个终端启动的它由 init 系统或容器运行时拉起掩码取决于那条启动路径上的设置。你在终端里看到的 022只代表你这个 shell。那么服务进程的掩码究竟从哪来这是本篇明确不回答的一处。不同发行版、不同 init 系统、不同容器运行时注入掩码的位置各不相同有的写在单元配置里有的由运行时默认值决定有的压根没人设、只是继承了父进程。本条待验证需要查各自的官方文档。能做的是把「查」这件事变成动作拿到服务进程的 PID读它自己的掩码而不是读你终端里的那个值。6.2 加括号子 shell 改完不回头POSIX 专门为这件事写了一段还给了三个例子「If umask is called in a subshell or separate utility execution environment, such as one of the following:(umask 002)/nohup umask .../find . -exec umask ... \;it shall not affect the file mode creation mask of the caller’s environment.」括号、nohup、find -exec三种写法三个场景结论一样改的是那个执行环境自己的掩码调用者的不动。本机验证过一次输出很短但足够说明问题$umask022 $(umask 002;umask)002 $umask022中间那行是子 shell 里的值前后两行是外层的值。子 shell 里确实变成了002退出之后外层还是022。这个特性的实用价值在部署脚本里需要临时放宽或收紧掩码时把相关几行包进一对括号就不必在末尾写「记得改回来」。用括号圈定作用域比用「记得恢复」这种口头约定可靠。但如果改动是写在脚本主体里、后面还有别的步骤依赖它就必须显式恢复——第五章 5.3 那个umask 022就是这种情况。6.3 不带参数是查询带参数才是设置umask的两种用法POSIX 都写了。设置是前面引过的那句查询是另一句「If the mask operand is not specified, the umask utility shall write to standard output the value of the file mode creation mask of the invoking process.」注意这里的主语是「invoking process」——打印的是调用它的那个进程的掩码。在 shell 里那个进程就是当前 shell所以看起来像「查询当前值」。这个细节在写脚本时要留意脚本里执行umask拿到的是脚本进程的掩码而它又是从父进程继承来的。还有一个常见误解值得点破把umask写进.bashrc或某个启动脚本就以为「全系统都改了」。它只改了读到这个文件的那个 shell。同理容器里在 Dockerfile 里写一行umask 027如果没有配合SHELL或后续的RUN串联那行改动也只活在那一个RUN层里。本章可以带走的一句umask命令改的是 shell 执行环境umask()改的是进程括号能圈住作用域但圈不住「以为改了全系统」这种误解。七、按场景设值给到具体数字7.1 三个场景三组值讲完机制落到取值。下面这四组建议按「谁能读、谁能写」来定不按「哪个数字看起来顺眼」来定。场景建议 umask文件 / 目录结果为什么是这组站点静态目录、可执行目录022644/755内容要被任意账号读写只留给属主上传目录属主是服务账号组内另一个服务只读027640/750组能读能进other 一律不给共享协作目录同组多人要写007660/770组内可写other 完全隔离私钥、凭据、token、备份文件077600/700只有属主能碰组和 other 全清第二行那个027要说明一下相对 022它多清的是 other 的三位027等于022加上005所以文件变成640、目录变成750other 那一档彻底消失。group 那三位一位没动640的组照样可读。要连组一起关掉得往上走到077而不是在 022 和 027 之间找折中。这类差值很容易记混最稳的办法是对着 2.2 那张位图逐个核。上传目录还有一层常被漏看目录能进不等于能写。750的目录组内账号可以cd进去、可以ls但要往里面新建文件需要的是目录本身的 w 位而不是里面文件的权限。判断「能不能上传」看的是目录那九位不是文件那九位。这条和 umask 无关但排查时几乎总会一起出现。第三行有个坑必须划清界限。很多团队想要的是共享目录最终呈现2775组内多人可写新建的文件自动归到同一个组。这里的2775有一位是 setgid那个前导2它的作用是「目录里新建的东西继承目录的属组」。这个2不是 umask 给的。umask 007只能把权限位清成775umask表达不了 setgid —— 第二章引过 POSIX 那句特殊位要么被忽略、要么implementation-defined。想拿到2775得在umask 007之外另行给目录设 setgid两步是两件事不能合并成一句「把 umask 设成 2775」。还有一点umask只能影响新建的东西。目录上已经存在的文件不会因为改了掩码而变这一点和「改配置要重启才生效」是同一类认知——作用点在过去还是将来决定了你要不要回头补一遍。7.2 两条边界ACL 会接管777不能当兜底第一条边界是 ACL。man-pages 写得很明确「Alternatively, if the parent directory has a default ACL (see acl(5)), the umask is ignored, the default ACL is inherited, the permission bits are set based on the inherited ACL, and permission bits absent in the mode argument are turned off.」父目录设了默认 ACL 时umask 会被忽略权限改由继承来的 ACL 决定。这是另一套机制本篇只点到这里ACL 的具体写法不展开。它的实际含义是如果你排查半天下发现「改了 umask 但新建文件的权限没变」先去看父目录有没有默认 ACL别在掩码上反复试。第二条边界是chmod 777。这里必须把话说死不要用777兜底。理由有两个都能落回原文。其一umask 的语义是「把不想给的位清掉」这是0666 ~022那条等式的出发点777等于把这份收窄一次性作废前面所有的取值讨论都白做。其二对目录而言777意味着任何账号都能在里面新建、改名、替换文件——上传目录一旦是这个权限前面 1.1 那个「服务账号写不进去」的问题会瞬间反转成另一个更难收场的问题。权限不够时的正确动作有三个按顺序试查属主和属组对不对、查父目录有没有 ACL、按最小权限给到组。三个都不是777。7.3 一次核对写成命令顺序把上面这些落成动作就是下面这个顺序。命令按各自环境替换路径。⚠️代码待验证# 1. 读当前掩码数字与符号各看一遍umaskumask-S# 2. 看父目录有没有默认 ACL有则掩码不生效ls-ld/srv/www# 3. 在受控作用域里按目标值建目录再核对结果(umask 027;mkdir-p/srv/www/upload/new;touch/srv/www/upload/new/.keep)ls-ld/srv/www/upload/newls-l/srv/www/upload/new/.keep第 2 步最容易被跳过也最容易白干一场。第 3 步用括号圈住跑完外层不受影响如果这段要写进部署脚本、后面还有依赖就把括号去掉并在末尾补一行显式恢复到站点统一值。本章可以带走的一句取值按「谁能读、谁能写」定不按数字顺眼定2775里那位 setgid 不是 umask 给的权限不够时先查属主和 ACL777不在选项里。完整的权限自查清单这份资料把本文七个章节的判断点压缩成一页顺序清单——先读掩码、再看起始 mode、再看父目录 ACL、最后核对结果附常见取值的预期输出。放在资料包里扫码即可获取附表 A本文引用事实与官方出处对照表序号事实出处核验日期本文位置1掩码语义cmask 里置 1 的位在创建出的文件 mode 里被清掉POSIX.1-2017umask()UMASK-032026-10-26第二章 2.12Issue 8 措辞改为 Permission bit positions语义不变POSIX.1-2024umask()UMASK-042026-10-26第二章 2.33S_ISVTX在 cmask 里被忽略其余非权限位 implementation-definedPOSIX.1-2024umask()UMASK-042026-10-26第二章 2.34返回的旧掩码中S_ISVTX位为清零POSIX.1-2024umask()UMASK-042026-10-26第二章 2.35umask()设置进程掩码并返回旧值只用权限位POSIX.1-2017umask()UMASK-012026-10-26第六章 6.16受影响的函数清单open/openat/creat/mkdir/mkdirat/mkfifo/mkfifoatPOSIX.1-2017umask()UMASK-022026-10-26第三章 3.17XSI 另列mknod()/mknodat()可选部分含mq_open()/sem_open()POSIX.1-2017umask()UMASK-022026-10-26第三章 3.18open()mode 的权限位与掩码补集做按位与掩码为 1 的位被清POSIX.1-2017open()UMASK-052026-10-26第三章 3.29mkdir()权限位从 mode 初始化再被掩码修改无豁免POSIX.1-2017mkdir()UMASK-062026-10-26第三章 3.310shell 的umask作用于 current shell execution environmentPOSIX.1-2017umask工具UMASK-072026-10-26第六章 6.111掩码影响之后创建文件的初始权限位POSIX.1-2017umask工具UMASK-072026-10-26第六章 6.112在子 shell、nohup、find -exec里调用不影响调用者环境POSIX.1-2017umask工具UMASK-082026-10-26第六章 6.213不带 mask 参数时打印 invoking process 的掩码值POSIX.1-2017umask工具UMASK-092026-10-26第六章 6.314典型默认值是S_IWGRP与S_IWOTH即八进制 022Linux man-pagesumask(2)UMASK-112026-10-26第四章 4.1150666 ~022 0644即rw-r--r--Linux man-pagesumask(2)UMASK-132026-10-26第四章 4.116父目录有 default ACL 时掩码被忽略权限由继承 ACL 决定Linux man-pagesumask(2)UMASK-142026-10-26第七章 7.217本机实测umask022 与umask -S的urwx,grx,orx本机实测UMASK-172026-10-26第五章 5.118本机实测022 下 touch 得 644、mkdir 得 755本机实测UMASK-182026-10-26第五章 5.219本机实测077 下得 600 与 700umask -S显示g,o本机实测UMASK-192026-10-26第五章 5.320本机实测括号内改 002 不影响外层之后显式恢复 022本机实测UMASK-08 行为验证2026-10-26第六章 6.221某发行版登录 shell 的掩码由哪个文件决定待验证正文仅写需查各自文档未取得发行版手册UMASK-122026-10-26第四章 4.1附表 B术语速查表术语一句话解释umask文件模式创建掩码进程级属性创建文件时用来清位起始 mode调用方传给open()/mkdir()的权限值文件常用 0666目录常用 0777清位掩码为 1 的位置在结果的 mode 里被置 0不会把位设成 1补集逐位取反掩码 022 的补集在那九位上是「除两个 w 之外全开」起始 mode 与掩码的运算按位与写作0666 ~022S_ISVTX特殊位之一POSIX 明确它在 cmask 里被忽略特殊位setuid、setgid、sticky 一类不属于 umask 的表达范围shell execution environmentshell 的执行环境umask命令作用的对象子 shell括号等方式开出的执行环境改动不外泄default ACL父目录上设定的默认访问控制会使 umask 被忽略最小权限只给完成工作所必需的那几位多一位都不给写在最后这篇用到的资料写这篇文章时我把一台机器上的 022 和 077 两组掩码各跑了一遍对着ls -l的十位字符逐位核到等式上顺手也整理了几份配套的东西靶场环境对照表DVWA、upload-labs 在 Windows / macOS / Linux 三平台的可行性与推荐路径Web 安全学习路线图从基础打牢到安全管理四个阶段各学什么常用靶场清单每个靶场练什么、适合哪个阶段资料是我自己整理的放在下面这个码上扫码即可获取添加时备注「靶场」优先通过。拿到之后建议先看环境对照表那一份把要动手的环境先对齐再回来对权限这一节会顺很多。