|
Message-ID: <20190625225201.GJ17978@ZenIV.linux.org.uk> Date: Tue, 25 Jun 2019 23:52:01 +0100 From: Al Viro <viro@...iv.linux.org.uk> To: Mickaël Salaün <mic@...ikod.net> Cc: linux-kernel@...r.kernel.org, Aleksa Sarai <cyphar@...har.com>, Alexei Starovoitov <ast@...nel.org>, Andrew Morton <akpm@...ux-foundation.org>, Andy Lutomirski <luto@...capital.net>, Arnaldo Carvalho de Melo <acme@...nel.org>, Casey Schaufler <casey@...aufler-ca.com>, Daniel Borkmann <daniel@...earbox.net>, David Drysdale <drysdale@...gle.com>, "David S . Miller" <davem@...emloft.net>, "Eric W . Biederman" <ebiederm@...ssion.com>, James Morris <jmorris@...ei.org>, Jann Horn <jann@...jh.net>, John Johansen <john.johansen@...onical.com>, Jonathan Corbet <corbet@....net>, Kees Cook <keescook@...omium.org>, Michael Kerrisk <mtk.manpages@...il.com>, Mickaël Salaün <mickael.salaun@....gouv.fr>, Paul Moore <paul@...l-moore.com>, Sargun Dhillon <sargun@...gun.me>, "Serge E . Hallyn" <serge@...lyn.com>, Shuah Khan <shuah@...nel.org>, Stephen Smalley <sds@...ho.nsa.gov>, Tejun Heo <tj@...nel.org>, Tetsuo Handa <penguin-kernel@...ove.sakura.ne.jp>, Thomas Graf <tgraf@...g.ch>, Tycho Andersen <tycho@...ho.ws>, Will Drewry <wad@...omium.org>, kernel-hardening@...ts.openwall.com, linux-api@...r.kernel.org, linux-fsdevel@...r.kernel.org, linux-security-module@...r.kernel.org, netdev@...r.kernel.org Subject: Re: [PATCH bpf-next v9 05/10] bpf,landlock: Add a new map type: inode On Tue, Jun 25, 2019 at 11:52:34PM +0200, Mickaël Salaün wrote: > +/* must call iput(inode) after this call */ > +static struct inode *inode_from_fd(int ufd, bool check_access) > +{ > + struct inode *ret; > + struct fd f; > + int deny; > + > + f = fdget(ufd); > + if (unlikely(!f.file || !file_inode(f.file))) { > + ret = ERR_PTR(-EBADF); > + goto put_fd; > + } Just when does one get a NULL file_inode()? The reason I'm asking is that arseloads of code would break if one managed to create such a beast... Incidentally, that should be return ERR_PTR(-EBADF); fdput() is wrong there. > + } > + /* check if the FD is tied to a mount point */ > + /* TODO: add this check when called from an eBPF program too */ > + if (unlikely(!f.file->f_path.mnt Again, the same question - when the hell can that happen? If you are sitting on an exploitable roothole, do share it... || f.file->f_path.mnt->mnt_flags & > + MNT_INTERNAL)) { > + ret = ERR_PTR(-EINVAL); > + goto put_fd; What does it have to do with mountpoints, anyway? > +/* called from syscall */ > +static int sys_inode_map_delete_elem(struct bpf_map *map, struct inode *key) > +{ > + struct inode_array *array = container_of(map, struct inode_array, map); > + struct inode *inode; > + int i; > + > + WARN_ON_ONCE(!rcu_read_lock_held()); > + for (i = 0; i < array->map.max_entries; i++) { > + if (array->elems[i].inode == key) { > + inode = xchg(&array->elems[i].inode, NULL); > + array->nb_entries--; Umm... Is that intended to be atomic in any sense? > + iput(inode); > + return 0; > + } > + } > + return -ENOENT; > +} > + > +/* called from syscall */ > +int bpf_inode_map_delete_elem(struct bpf_map *map, int *key) > +{ > + struct inode *inode; > + int err; > + > + inode = inode_from_fd(*key, false); > + if (IS_ERR(inode)) > + return PTR_ERR(inode); > + err = sys_inode_map_delete_elem(map, inode); > + iput(inode); > + return err; > +} Wait a sec... So we have those beasties that can have long-term references to arbitrary inodes stuck in them? What will happen if you get umount(2) called while such a thing exists?
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.