Replace checkPermBits error-return with hasPermBits bool

- hasPermBits uses a 4-entry mask array indexed by mode&3 to select
  the required permission bits: OREAD→4, OWRITE→2, ORDWR→6, OEXEC→1
- Zero branches, zero error paths — returns bits&mask == mask
- open() uses OR semantics: checks owner, group, world independently;
  any tier granting access is sufficient
- checkPerm removed entirely; permission logic is pure boolean math
This commit is contained in:
Ollie Agent 2026-08-02 15:55:25 +02:00
parent 325ad224be
commit 0b4daf016a
1 changed files with 19 additions and 31 deletions

View File

@ -144,35 +144,11 @@ func fileOwnerGroup(root *fs.Tree, path string) (uid, gid string) {
return "ollie", "agent" return "ollie", "agent"
} }
func checkPerm(uname string, mode uint8, uid string, perm uint32, inGroup bool) error { var permMask = [4]uint32{4, 2, 6, 1} // OREAD, OWRITE, ORDWR, OEXEC
var bits uint32
if uname == uid { func hasPermBits(mode uint8, bits uint32) bool {
bits = (perm >> 6) & 7 m := permMask[mode&3]
} else if inGroup { return bits&m == m
bits = (perm >> 3) & 7
} else {
bits = perm & 7
}
omode := mode & 3
switch omode {
case plan9.OREAD:
if bits&4 == 0 {
return fmt.Errorf("permission denied")
}
case plan9.OWRITE:
if bits&2 == 0 {
return fmt.Errorf("permission denied")
}
case plan9.ORDWR:
if bits&6 != 6 {
return fmt.Errorf("permission denied")
}
case plan9.OEXEC:
if bits&1 == 0 {
return fmt.Errorf("permission denied")
}
}
return nil
} }
const readTimeout = 10 * time.Second const readTimeout = 10 * time.Second
@ -413,8 +389,20 @@ func (s *Server) open(cs *connState, fc *plan9.Fcall) *plan9.Fcall {
return errFcall(fc, "bad fid") return errFcall(fc, "bad fid")
} }
uid, gid := fileOwnerGroup(s.rootTree, f.path) uid, gid := fileOwnerGroup(s.rootTree, f.path)
if err := checkPerm(cs.uname, fc.Mode, uid, uint32(makeStat(s.rootTree, f.path).Mode)&0777, s.InGroup(gid, cs.uname)); err != nil { perm := uint32(makeStat(s.rootTree, f.path).Mode) & 0777
return errFcall(fc, err.Error())
allowed := false
if cs.uname == uid {
allowed = hasPermBits(fc.Mode, perm>>6)
}
if !allowed && s.InGroup(gid, cs.uname) {
allowed = hasPermBits(fc.Mode, perm>>3)
}
if !allowed {
allowed = hasPermBits(fc.Mode, perm)
}
if !allowed {
return errFcall(fc, "permission denied")
} }
f.mode = fc.Mode f.mode = fc.Mode
return &plan9.Fcall{Type: plan9.Ropen, Tag: fc.Tag, Qid: f.qid} return &plan9.Fcall{Type: plan9.Ropen, Tag: fc.Tag, Qid: f.qid}