stsp wrote: > 27.01.2025 12:10, Ondrej Mosnacek пишет: > > Hello, > > > > It looks like the commit in $SUBJ may have introduced an unintended > > change in behavior. According to the commit message, the intent was to > > require just one of {user, group} to match instead of both, which > > sounds reasonable, but the commit also changes the behavior for when > > neither of tun->owner and tun->group is set. Before the commit the > > access was always allowed, while after the commit CAP_NET_ADMIN is > > required in this case. > > > > I'm asking because the tun_tap subtest of selinux-testuite [1] started > > to fail after this commit (it assumed CAP_NET_ADMIN was not needed), > > so I'm trying to figure out if we need to change the test or if it > > needs to be fixed in the kernel. > > > > Thanks, > > > > [1] https://github.com/SELinuxProject/selinux-testsuite/ > > > Hi, IMHO having the persistent > TAP device inaccessible by anyone > but the CAP_NET_ADMIN is rather > useless, so the compatibility should > be restored on the kernel side. > I'd raise the questions about adding > the CAP_NET_ADMIN checks into > TUNSETOWNER and/or TUNSETPERSIST, > but this particular change to TUNSETIFF, > at least on my side, was unintentional. > > Sorry about that. :( Thanks for the report Ondrej. Agreed that we need to reinstate this. I suggest this explicit extra branch after the more likely cases: @@ -585,6 +585,9 @@ static inline bool tun_capable(struct tun_struct *tun) return 1; if (gid_valid(tun->group) && in_egroup_p(tun->group)) return 1; + if (!uid_valid(tun->owner) && !gid_valid(tun->group)) + return 1; + return 0; } The intent clearly has always been to allow access if owner and group are not explicitly set. It's easy to see when group support was added in commit 8c644623fe7e ("[NET]: Allow group ownership of TUN/TAP devices."), and the even simpler check before that: /* Check permissions */ - if (tun->owner != -1 && - current->euid != tun->owner && !capable(CAP_NET_ADMIN)) + if (((tun->owner != -1 && + current->euid != tun->owner) || + (tun->group != -1 && + current->egid != tun->group)) && + !capable(CAP_NET_ADMIN)) return -EPERM;