1. Yes and no. Ideally we would have a aa_query function that accepted an open file descriptor. That isn't available right now but should be down the road.
access(2) is more racey, IMO, because unprivileged attackers can modify file permissions and fool programs doing the access() -> open() dance. Passing a path to aa_query_label() is not entirely susceptible to the TOCTOU conditions known with access(2) because only a privileged user can load AppArmor profiles.
2. symlinks are a problem with this interface since the kernel isn't actually walking the path. Instead, the kernel is just using the path string passed to it in order to look up the set of allowed permissions.
This means that you'll need to fully resolve a symlink target and pass it to aa_query_label(). That also opens up the chance of another race condition. If the symlink file is user controllable, an attacker might make the symlink point to an innocent path, let a trusted helper resolve the innocent path and call aa_query_label(), and then win the race to adjust the symlink to point to a malicious path before the trusted helper calls open().
If the paths that you're performing queries on are not user controllable, I think you should be safe using aa_query_label(). If they are user controllable, you'll probably need to wait until we have an interface that accepts an open fd.
1. Yes and no. Ideally we would have a aa_query function that accepted an open file descriptor. That isn't available right now but should be down the road.
access(2) is more racey, IMO, because unprivileged attackers can modify file permissions and fool programs doing the access() -> open() dance. Passing a path to aa_query_label() is not entirely susceptible to the TOCTOU conditions known with access(2) because only a privileged user can load AppArmor profiles.
2. symlinks are a problem with this interface since the kernel isn't actually walking the path. Instead, the kernel is just using the path string passed to it in order to look up the set of allowed permissions.
This means that you'll need to fully resolve a symlink target and pass it to aa_query_label(). That also opens up the chance of another race condition. If the symlink file is user controllable, an attacker might make the symlink point to an innocent path, let a trusted helper resolve the innocent path and call aa_query_label(), and then win the race to adjust the symlink to point to a malicious path before the trusted helper calls open().
If the paths that you're performing queries on are not user controllable, I think you should be safe using aa_query_label(). If they are user controllable, you'll probably need to wait until we have an interface that accepts an open fd.