(t *kernel.Task, dirfd int32, pathAddr hostarch.Addr, mode uint32, flags int32)
| 159 | } |
| 160 | |
| 161 | func accessAt(t *kernel.Task, dirfd int32, pathAddr hostarch.Addr, mode uint32, flags int32) error { |
| 162 | const rOK = 4 |
| 163 | const wOK = 2 |
| 164 | const xOK = 1 |
| 165 | |
| 166 | // Sanity check the mode. |
| 167 | if mode&^(rOK|wOK|xOK) != 0 { |
| 168 | return linuxerr.EINVAL |
| 169 | } |
| 170 | |
| 171 | // faccessat2(2) isn't documented as supporting AT_EMPTY_PATH, but it does. |
| 172 | if flags&^(linux.AT_EACCESS|linux.AT_SYMLINK_NOFOLLOW|linux.AT_EMPTY_PATH) != 0 { |
| 173 | return linuxerr.EINVAL |
| 174 | } |
| 175 | |
| 176 | path, err := copyInPath(t, pathAddr) |
| 177 | if err != nil { |
| 178 | return err |
| 179 | } |
| 180 | tpop, err := getTaskPathOperation(t, dirfd, path, shouldAllowEmptyPath(flags&linux.AT_EMPTY_PATH != 0), shouldFollowFinalSymlink(flags&linux.AT_SYMLINK_NOFOLLOW == 0)) |
| 181 | if err != nil { |
| 182 | return err |
| 183 | } |
| 184 | defer tpop.Release(t) |
| 185 | |
| 186 | creds := t.Credentials() |
| 187 | if flags&linux.AT_EACCESS == 0 { |
| 188 | // access(2) and faccessat(2) check permissions using real |
| 189 | // UID/GID, not effective UID/GID. |
| 190 | // |
| 191 | // "access() needs to use the real uid/gid, not the effective |
| 192 | // uid/gid. We do this by temporarily clearing all FS-related |
| 193 | // capabilities and switching the fsuid/fsgid around to the |
| 194 | // real ones." -fs/open.c:faccessat |
| 195 | creds = creds.Fork() |
| 196 | creds.EffectiveKUID = creds.RealKUID |
| 197 | creds.EffectiveKGID = creds.RealKGID |
| 198 | if creds.EffectiveKUID.In(creds.UserNamespace) == auth.RootUID { |
| 199 | creds.EffectiveCaps = creds.PermittedCaps |
| 200 | } else { |
| 201 | creds.EffectiveCaps = 0 |
| 202 | } |
| 203 | } |
| 204 | |
| 205 | return t.Kernel().VFS().AccessAt(t, creds, vfs.AccessTypes(mode), &tpop.pop) |
| 206 | } |
| 207 | |
| 208 | // Ioctl implements Linux syscall ioctl(2). |
| 209 | func Ioctl(t *kernel.Task, sysno uintptr, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { |
no test coverage detected
searching dependent graphs…