On Wed, 24 Jan 2024 at 12:15, Kees Cook <keescook@xxxxxxxxxxxx> wrote: > > Hmpf, and frustratingly Ubuntu (and Debian) still builds with > CONFIG_USELIB, even though it was reported[2] to them almost 4 years ago. Well, we could just remove the __FMODE_EXEC from uselib. It's kind of wrong anyway. Unlike a real execve(), where the target executable actually takes control and you can't actually control it (except with ptrace, of course), 'uselib()' really is just a wrapper around a special mmap. And you can see it in the "acc_mode" flags: uselib already requires MAY_READ for that reason. So you cannot uselib() a non-readable file, unlike execve(). So I think just removing __FMODE_EXEC would just do the RightThing(tm), and changes nothing for any sane situation. In fact, I don't think __FMODE_EXEC really ever did anything for the uselib() case, so removing it *really* shouldn't matter, and only fix the new AppArmor / Tomoyo use. Of course, as you say, not having CONFIG_USELIB enabled at all is the _truly_ sane thing, but the only thing that used the FMODE_EXEC bit were landlock and some special-case nfs stuff. And at least the nfs stuff was about "don't require read permissions for exec", which was already wrong for the uselib() case as per above. So I think the simple oneliner is literally just --- a/fs/exec.c +++ b/fs/exec.c @@ -128,7 +128,7 @@ SYSCALL_DEFINE1(uselib, const char __user *, library) struct filename *tmp = getname(library); int error = PTR_ERR(tmp); static const struct open_flags uselib_flags = { - .open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC, + .open_flag = O_LARGEFILE | O_RDONLY, .acc_mode = MAY_READ | MAY_EXEC, .intent = LOOKUP_OPEN, .lookup_flags = LOOKUP_FOLLOW, but I obviously have nothing that uses uselib(). I don't see how it really *could* break anything, though, exactly because of that .acc_mode = MAY_READ | MAY_EXEC, that means that the *regular* permission checks already require the file to be readable. Never mind any LSM checks that might be confused. Linus