linux/fs/namei.c/permission()

本文介绍了一个名为permission()的函数,该函数用于检查当前进程对指定文件的读、写及执行权限。文章详细解释了如何根据文件的所有者、所属组及当前进程的有效用户ID来确定这些权限。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*
 * permission()
 *
 * is used to check for read/write/execute permissions on a file.
 * I don't know if we should look at just the euid or both euid and
 * uid, but that should be easily changed.
 */
// permission()函数用来检验当前进程对inode指向的文件是否有mask标示的权限
static int permission(struct m_inode * inode,int mask)
{
// 取出inode的i_mode,这表明了imode指向的文件本身的读写权限。
int mode = inode->i_mode;


/* special case: not even root can read/write a deleted file */
// inode->i_dev存在(i节点有对应的设备),并且inode->i_nlinks=0
// (即文件没有被引用),则表明这个文件是一个被删除了的文件。即使是
// 超级用户root也没有操作已删除文件的权限,因此return 0
if (inode->i_dev && !inode->i_nlinks)
return 0;
// 首先明白euid的含义。euid是进程task_struct中的一个short字段。一般
// 一个进程的euid等于运行这个进程的用户的uid。(同样地egid等于运行
// 这个进程的用户的gid),这样这个进程就有了运行进程的用户的权限设置了。
// 其次明白inode->i_uid的含义。i_uid用来标示inode指向的文件的uid,即这个
// 文件的宿主的uid。同样地,i_gid表明文件宿主所在的group的gid
// 当前进程的euid == inode->i_uid,表明运行进程的用户和该文件的宿主用户
// 是同一用户。此时inode文件在被自己的宿主使用,因此应该查三组权限位中的
// U(SUGO:即超级用户,宿主,宿主group,others中的U)
else if (current->euid==inode->i_uid)
// mode>>6,将U所在的三位移到了最底三位。
mode >>= 6;
// 若操作inode文件的用户不是文件宿主,但是是宿主group内的成员,则适用G权限位
else if (current->egid==inode->i_gid)
// mode>>3将G移到了最低3bit
mode >>= 3;
// 这里两个else if却没有最后的else,其实相当于是有个default的,default就是
// 对mode不做处理。因为default的情况对应着O权限位(即others),刚好是mode的
// 最低3bit,所以不用做什么处理。
// mode & 0007取出了mode的最低三位,再位与mask后,若等于mask说明mode表示的权限
// 包含mask,即当前进程有mask表示的操作权限,返回1.若不等则返回0.
// suser()宏用来判断当前进程的宿主是否是超级用户root(current->euid == 0)
// 超级用户对于所有文件具有操作权限,所以直接返回1.
if (((mode & mask & 0007) == mask) || suser())
return 1;
return 0;
}
static struct file *path_openat(struct nameidata *nd, const struct open_flags *op, unsigned flags) { struct file *file; int error; file = alloc_empty_file(op->open_flag, current_cred()); if (IS_ERR(file)) return file; if (unlikely(file->f_flags & __O_TMPFILE)) { error = do_tmpfile(nd, flags, op, file); } else if (unlikely(file->f_flags & O_PATH)) { error = do_o_path(nd, flags, file); } else { const char *s = path_init(nd, flags); while (!(error = link_path_walk(s, nd)) && (s = open_last_lookups(nd, file, op)) != NULL) ; if (!error) error = do_open(nd, file, op); terminate_walk(nd); } if (likely(!error)) { if (likely(file->f_mode & FMODE_OPENED)) return file; WARN_ON(1); error = -EINVAL; } fput(file); if (error == -EOPENSTALE) { if (flags & LOOKUP_RCU) error = -ECHILD; else error = -ESTALE; } return ERR_PTR(error); } 分析这段异常 == 异常报告v2.3(仅供参考) == 报告解读: MediaTek On-Line> Quick Start> NE/KE分析报告解读> KE分析报告 详细描述: path_openat()从错误地址(0xFFFFFFFFE27A3C70)读数据,请结合崩溃进程调用栈检查相关代码 平台 : MT6769V/CZ (0A8C28C8,EBA795BE) 版本 : alps-vf-mp-v0.mp1.tc16sp-pr2unknownRMX3910export_11_15.0.0.800/user build 异常时间: 541.036193秒, Sun Jun 8 15:12:55 WITA 2025 == 平台信息 == -- CPU 0 1 2 3 [4] 5 6 7 -- L opp: 0( 918mV, 1800MHz, 0C) 539.948857s B opp: 15( 650mV, 850MHz, 0C) 541.036187s CCI opp: 6( 762mV, 856MHz, 0C) 541.034279s -- LPDDR4(3600,8G)|Storage -- vcore dvfs opp: [-140462620.179732]12(700mV, 1534MHz) 已热重启: 1次 -- Low Power -- SPM last pc: 0xa8e == CPU信息 == 崩溃CPU信息: CPU4: Thread-7, pid: 5479, 优先级: 120 本地调用栈: vmlinux __d_entry_type(dentry=0xFFFFFFFFE27A3C70) </proc/self/cwd/kernel-6.6/include/linux/dcache.h:395> vmlinux d_can_lookup(dentry=0xFFFFFFFFE27A3C70) </proc/self/cwd/kernel-6.6/include/linux/dcache.h:410> vmlinux d_is_dir(dentry=0xFFFFFFFFE27A3C70) </proc/self/cwd/kernel-6.6/include/linux/dcache.h:420> vmlinux do_open(nd=0xFFFFFFC0940E3C70, file=0xFFFFFF801F75C500, op=0xFFFFFFC0940E3DA0) + 224 </proc/self/cwd/kernel-6.6/fs/namei.c:3610> vmlinux path_openat(nd=0xFFFFFFC0940E3D60, op=0xFFFFFFC0940E3DA0, flags=2483960812) + 2340 </proc/self/cwd/kernel-6.6/fs/namei.c:3791> vmlinux do_filp_open(op=0xFFFFFFC0940E3DC0) + 180 </proc/self/cwd/kernel-6.6/fs/namei.c:3818> vmlinux do_sys_openat2(how=0xFFFFFFC0940E3E10) + 128 </proc/self/cwd/kernel-6.6/fs/open.c:1442> vmlinux do_sys_open() + 56 </proc/self/cwd/kernel-6.6/fs/open.c:1457> vmlinux __do_sys_openat() + 56 </proc/self/cwd/kernel-6.6/fs/open.c:1473> vmlinux __se_sys_openat() + 56 </proc/self/cwd/kernel-6.6/fs/open.c:1468> vmlinux __arm64_sys_openat() + 108 </proc/self/cwd/kernel-6.6/fs/open.c:1468> vmlinux __invoke_syscall() + 48 </proc/self/cwd/kernel-6.6/arch/arm64/kernel/syscall.c:37> vmlinux invoke_syscall() + 84 </proc/self/cwd/kernel-6.6/arch/arm64/kernel/syscall.c:51> vmlinux el0_svc_common(sc_nr=463) + 124 </proc/self/cwd/kernel-6.6/arch/arm64/kernel/syscall.c:136> vmlinux do_el0_svc() + 24 </proc/self/cwd/kernel-6.6/arch/arm64/kernel/syscall.c:155> vmlinux el0_svc() + 52 </proc/self/cwd/kernel-6.6/arch/arm64/kernel/entry-common.c:683> vmlinux el0t_64_sync_handler() + 100 </proc/self/cwd/kernel-6.6/arch/arm64/kernel/entry-common.c:701> vmlinux 0xFFFFFFE609491584() </proc/self/cwd/kernel-6.6/arch/arm64/kernel/entry.S:525> == 栈结束 == 对应汇编指令: 行号 地址 指令 提示 /proc/self/cwd/kernel-6.6/arch/arm64/include/asm/current.h FFFFFFE6098332FC: MOV X21, X0 ; path_openat()参数 1可能有问题 /proc/self/cwd/kernel-6.6/fs/namei.c 3787: FFFFFFE6098333FC: B FFFFFFE609833B0C 3599: FFFFFFE609833B0C: /proc/self/cwd/kernel-6.6/include/linux/audit.h 0 : FFFFFFE609833B40: B FFFFFFE609833B60 /proc/self/cwd/kernel-6.6/fs/namei.c 3606: FFFFFFE609833B60: 3607: FFFFFFE609833B6C: TBNZ W24, #6, FFFFFFE609833BD0 0 : FFFFFFE609833BD0: 3608: FFFFFFE609833BDC: TBNZ W8, #4, FFFFFFE609833BE8 3610: FFFFFFE609833BE8: LDR X8, [X21, #0x8] ; 0xFFFFFFFFE27A3C70 <- [0xFFFFFFC0940E3C78] /proc/self/cwd/kernel-6.6/include/linux/dcache.h 395 : FFFFFFE609833BEC: LDR W9, [X8] ; 进程停止在这里 /proc/self/cwd/kernel-6.6/fs/namei.c 3818: FFFFFFE609833204: MOV X0, SP ; R31:0xFFFFFFC0940E3D60 FFFFFFE609833218: BL path_openat() 当时的寄存器值: X0: FFFFFF802D2DDDC0, X1: 0000000000000001, X2: 0000000000000000, X3: 000000000000000B X4: FFFFFFFE01CDA460, X5: FFFFFFE6069AC7B8, X6: 00747365745F6473, X7: 00747365745F6473 X8: FFFFFFFFE27A3C70, X9: FFFFFFFF00000000, X10: 0000000300000000, X11: 0000000300000000 X12: 0000000200000000, X13: 00000000684537D0, X14: FFFFFFE60B59A658, X15: 0000000000000328 X16: 000000006155CDD4, X17: 000000006155CDD4, X18: FFFFFFC091915048, X19: FFFFFF801F75C500 X20: 0000000000000000, X21: FFFFFFC0940E3C70, X22: FFFFFFC0940E3DA0, X23: FFFFFFE60B66BE00 X24: 00000000000200C2, X25: 0000000000000040, X26: 00000000000200C2, X27: FFFFFFC0940E3BF0 X28: FFFFFF802D2DDDC0, X29: FFFFFFC0940E3C10, X30: FFFFFFE609833B08, SP: FFFFFFC0940E3BC0 PC: FFFFFFE609833BEC
最新发布
06-13
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

朱有鹏老师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值