diff mbox series

[(urgent)] vfs: fix uninitialized uid/gid in chown_common()

Message ID 3411f396-a41e-76cb-7836-941fbade81dc@I-love.SAKURA.ne.jp (mailing list archive)
State New, archived
Headers show
Series [(urgent)] vfs: fix uninitialized uid/gid in chown_common() | expand

Commit Message

Tetsuo Handa Sept. 19, 2022, 11:05 a.m. UTC
syzbot is reporting uninit-value in tomoyo_path_chown() [1], for
chown_common() is by error passing uninitialized newattrs.ia_vfsuid to
security_path_chown() via from_vfsuid() when user == -1 is passed.
We must initialize newattrs.ia_vfs{u,g}id fields in order to make
from_vfs{u,g}id() work.

Link: https://syzkaller.appspot.com/bug?extid=541e21dcc32c4046cba9 [1]
Reported-by: syzbot <syzbot+541e21dcc32c4046cba9@syzkaller.appspotmail.com>
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
---
 fs/open.c | 2 ++
 1 file changed, 2 insertions(+)

Comments

Christian Brauner Sept. 19, 2022, 3:12 p.m. UTC | #1
On Mon, Sep 19, 2022 at 08:05:12PM +0900, Tetsuo Handa wrote:
> syzbot is reporting uninit-value in tomoyo_path_chown() [1], for
> chown_common() is by error passing uninitialized newattrs.ia_vfsuid to
> security_path_chown() via from_vfsuid() when user == -1 is passed.
> We must initialize newattrs.ia_vfs{u,g}id fields in order to make
> from_vfs{u,g}id() work.
> 
> Link: https://syzkaller.appspot.com/bug?extid=541e21dcc32c4046cba9 [1]
> Reported-by: syzbot <syzbot+541e21dcc32c4046cba9@syzkaller.appspotmail.com>
> Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
> ---

Odd that we didn't get any of the reports. Thanks for relying this.
I'll massage this a tiny bit, apply and will test with syzbot.
Christian Brauner Sept. 19, 2022, 3:14 p.m. UTC | #2
On Mon, Sep 19, 2022 at 05:12:25PM +0200, Christian Brauner wrote:
> On Mon, Sep 19, 2022 at 08:05:12PM +0900, Tetsuo Handa wrote:
> > syzbot is reporting uninit-value in tomoyo_path_chown() [1], for
> > chown_common() is by error passing uninitialized newattrs.ia_vfsuid to
> > security_path_chown() via from_vfsuid() when user == -1 is passed.
> > We must initialize newattrs.ia_vfs{u,g}id fields in order to make
> > from_vfs{u,g}id() work.
> > 
> > Link: https://syzkaller.appspot.com/bug?extid=541e21dcc32c4046cba9 [1]
> > Reported-by: syzbot <syzbot+541e21dcc32c4046cba9@syzkaller.appspotmail.com>
> > Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
> > ---
> 
> Odd that we didn't get any of the reports. Thanks for relying this.
> I'll massage this a tiny bit, apply and will test with syzbot.

Fyi, Seth.
Serge E. Hallyn Sept. 19, 2022, 11:41 p.m. UTC | #3
On Mon, Sep 19, 2022 at 05:14:14PM +0200, Christian Brauner wrote:
> On Mon, Sep 19, 2022 at 05:12:25PM +0200, Christian Brauner wrote:
> > On Mon, Sep 19, 2022 at 08:05:12PM +0900, Tetsuo Handa wrote:
> > > syzbot is reporting uninit-value in tomoyo_path_chown() [1], for
> > > chown_common() is by error passing uninitialized newattrs.ia_vfsuid to
> > > security_path_chown() via from_vfsuid() when user == -1 is passed.
> > > We must initialize newattrs.ia_vfs{u,g}id fields in order to make
> > > from_vfs{u,g}id() work.
> > > 
> > > Link: https://syzkaller.appspot.com/bug?extid=541e21dcc32c4046cba9 [1]
> > > Reported-by: syzbot <syzbot+541e21dcc32c4046cba9@syzkaller.appspotmail.com>
> > > Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
> > > ---
> > 
> > Odd that we didn't get any of the reports. Thanks for relying this.
> > I'll massage this a tiny bit, apply and will test with syzbot.
> 
> Fyi, Seth.

Because the modules are ignoring ia_valid & ATTR_XID?
Seth Forshee (DigitalOcean) Sept. 20, 2022, 12:25 a.m. UTC | #4
On Mon, Sep 19, 2022 at 06:41:02PM -0500, Serge E. Hallyn wrote:
> On Mon, Sep 19, 2022 at 05:14:14PM +0200, Christian Brauner wrote:
> > On Mon, Sep 19, 2022 at 05:12:25PM +0200, Christian Brauner wrote:
> > > On Mon, Sep 19, 2022 at 08:05:12PM +0900, Tetsuo Handa wrote:
> > > > syzbot is reporting uninit-value in tomoyo_path_chown() [1], for
> > > > chown_common() is by error passing uninitialized newattrs.ia_vfsuid to
> > > > security_path_chown() via from_vfsuid() when user == -1 is passed.
> > > > We must initialize newattrs.ia_vfs{u,g}id fields in order to make
> > > > from_vfs{u,g}id() work.
> > > > 
> > > > Link: https://syzkaller.appspot.com/bug?extid=541e21dcc32c4046cba9 [1]
> > > > Reported-by: syzbot <syzbot+541e21dcc32c4046cba9@syzkaller.appspotmail.com>
> > > > Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
> > > > ---
> > > 
> > > Odd that we didn't get any of the reports. Thanks for relying this.
> > > I'll massage this a tiny bit, apply and will test with syzbot.
> > 
> > Fyi, Seth.
> 
> Because the modules are ignoring ia_valid & ATTR_XID?

security_path_chown() takes ids as arguments, not struct iattr.

  int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid)

The ones being passed are now taken from iattr and thus potentially not
initialized. Even if we change it to only call security_path_chown()
when one of ATTR_{U,G}ID is set the other might not be set, so
initializing iattr.ia_vfs{u,g}id makes sense to me and should match the
old behavior of passing invalid ids in this situation.

What I don't understand is why security_path_chown() is even necessary
when we also have security_inode_setattr(), which also gets called
during chown and gets the full iattr struct. Maybe there's a good
reason, but at first glance it seems like it could do any checks that
security_path_chown() is doing.

Seth
Seth Forshee (DigitalOcean) Sept. 20, 2022, 12:29 a.m. UTC | #5
On Mon, Sep 19, 2022 at 07:25:39PM -0500, Seth Forshee wrote:
> On Mon, Sep 19, 2022 at 06:41:02PM -0500, Serge E. Hallyn wrote:
> > On Mon, Sep 19, 2022 at 05:14:14PM +0200, Christian Brauner wrote:
> > > On Mon, Sep 19, 2022 at 05:12:25PM +0200, Christian Brauner wrote:
> > > > On Mon, Sep 19, 2022 at 08:05:12PM +0900, Tetsuo Handa wrote:
> > > > > syzbot is reporting uninit-value in tomoyo_path_chown() [1], for
> > > > > chown_common() is by error passing uninitialized newattrs.ia_vfsuid to
> > > > > security_path_chown() via from_vfsuid() when user == -1 is passed.
> > > > > We must initialize newattrs.ia_vfs{u,g}id fields in order to make
> > > > > from_vfs{u,g}id() work.
> > > > > 
> > > > > Link: https://syzkaller.appspot.com/bug?extid=541e21dcc32c4046cba9 [1]
> > > > > Reported-by: syzbot <syzbot+541e21dcc32c4046cba9@syzkaller.appspotmail.com>
> > > > > Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
> > > > > ---
> > > > 
> > > > Odd that we didn't get any of the reports. Thanks for relying this.
> > > > I'll massage this a tiny bit, apply and will test with syzbot.
> > > 
> > > Fyi, Seth.
> > 
> > Because the modules are ignoring ia_valid & ATTR_XID?
> 
> security_path_chown() takes ids as arguments, not struct iattr.
> 
>   int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid)
> 
> The ones being passed are now taken from iattr and thus potentially not
> initialized. Even if we change it to only call security_path_chown()
> when one of ATTR_{U,G}ID is set the other might not be set, so
> initializing iattr.ia_vfs{u,g}id makes sense to me and should match the
> old behavior of passing invalid ids in this situation.
> 
> What I don't understand is why security_path_chown() is even necessary
> when we also have security_inode_setattr(), which also gets called
> during chown and gets the full iattr struct. Maybe there's a good
> reason, but at first glance it seems like it could do any checks that
> security_path_chown() is doing.

Maybe the important difference is that one takes the path as an argument
and the other only takes the dentry? I guess that might be it, though it
still feels kind of redundant.
Tetsuo Handa Sept. 20, 2022, 12:45 a.m. UTC | #6
On 2022/09/20 9:29, Seth Forshee wrote:
>>>>> Odd that we didn't get any of the reports. Thanks for relying this.
>>>>> I'll massage this a tiny bit, apply and will test with syzbot.

Since KMSAN is not yet upstreamed, uninit-value reports can come only after bugs
reached upstream kernels. Also, only LSMs which implement security_path_chown()
hook and checks uid/gid values (i.e. TOMOYO) would catch this bug.

>>>>
>>>> Fyi, Seth.
>>>
>>> Because the modules are ignoring ia_valid & ATTR_XID?
>>
>> security_path_chown() takes ids as arguments, not struct iattr.
>>
>>   int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid)
>>
>> The ones being passed are now taken from iattr and thus potentially not
>> initialized. Even if we change it to only call security_path_chown()
>> when one of ATTR_{U,G}ID is set the other might not be set, so
>> initializing iattr.ia_vfs{u,g}id makes sense to me and should match the
>> old behavior of passing invalid ids in this situation.
>>
>> What I don't understand is why security_path_chown() is even necessary
>> when we also have security_inode_setattr(), which also gets called
>> during chown and gets the full iattr struct. Maybe there's a good
>> reason, but at first glance it seems like it could do any checks that
>> security_path_chown() is doing.
> 
> Maybe the important difference is that one takes the path as an argument
> and the other only takes the dentry? I guess that might be it, though it
> still feels kind of redundant.

security_path_*() hooks are used by LSMs which check absolute pathnames.
Thus, these hooks are not redundant.
diff mbox series

Patch

diff --git a/fs/open.c b/fs/open.c
index 8a813fa5ca56..0550efb7b53a 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -709,6 +709,8 @@  int chown_common(const struct path *path, uid_t user, gid_t group)
 	kuid_t uid;
 	kgid_t gid;
 
+	newattrs.ia_vfsuid = VFSUIDT_INIT(KUIDT_INIT(-1));
+	newattrs.ia_vfsgid = VFSGIDT_INIT(KGIDT_INIT(-1));
 	uid = make_kuid(current_user_ns(), user);
 	gid = make_kgid(current_user_ns(), group);