LAMP服务器中PHP上传文件权限异常问题求助
首先要明确:fileperms()返回的是包含文件类型、特殊权限位的完整文件模式,不是单纯的文件权限位。你需要用fileperms($file) & 0777来掩码掉高位,才能得到真正的权限值(比如你预期的0664)。
针对你遇到的情况,成因主要有这几点:
临时文件的安全默认权限:
PHP处理上传时,会在临时目录创建权限为0600的临时文件(对应你看到的十进制33152=八进制0100600),这是安全设计——只有PHP进程所有者能读写,防止其他用户窃取上传内容。umask的权限掩码作用:
调用chmod($filename, 0664)时,系统会先应用当前PHP进程的umask值过滤权限位。比如如果umask是0022,实际生效的权限会是0664 & ~0022 = 0644;只有当umask是0002时,才能得到预期的0664。可以用echo umask();查看当前进程的umask值。目标目录的setgid位继承:
如果你的上传目标目录设置了setgid位(比如权限为2775),移动到该目录的文件会继承目录的组ID,同时setgid位会被保留到文件上,这会让文件的完整模式出现额外的特殊位(比如八进制0102664),导致十进制值看起来异常,但实际权限位还是符合预期的。SELinux的强制规则:
如果服务器开启了SELinux,可能会给上传文件添加特定的安全上下文,虽然这不会直接改变fileperms()返回的权限位,但如果SELinux规则限制了文件的访问权限,可能会让你误以为权限设置异常。可以用ls -Z命令查看文件的SELinux上下文状态。
内容的提问来源于stack exchange,提问作者mikekehrli

