Skip to content

Commit c9582eb

Browse files
ebiedermMiklos Szeredi
authored andcommitted
fuse: Fail all requests with invalid uids or gids
Upon a cursory examinination the uid and gid of a fuse request are necessary for correct operation. Failing a fuse request where those values are not reliable seems a straight forward and reliable means of ensuring that fuse requests with bad data are not sent or processed. In most cases the vfs will avoid actions it suspects will cause an inode write back of an inode with an invalid uid or gid. But that does not map precisely to what fuse is doing, so test for this and solve this at the fuse level as well. Performing this work in fuse_req_init_context is cheap as the code is already performing the translation here and only needs to check the result of the translation to see if things are not representable in a form the fuse server can handle. [SzM] Don't zero the context for the nofail case, just keep using the munging version (makes sense for debugging and doesn't hurt). Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
1 parent dbf107b commit c9582eb

File tree

1 file changed

+13
-9
lines changed

1 file changed

+13
-9
lines changed

fs/fuse/dev.c

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -112,13 +112,6 @@ static void __fuse_put_request(struct fuse_req *req)
112112
refcount_dec(&req->count);
113113
}
114114

115-
static void fuse_req_init_context(struct fuse_conn *fc, struct fuse_req *req)
116-
{
117-
req->in.h.uid = from_kuid_munged(&init_user_ns, current_fsuid());
118-
req->in.h.gid = from_kgid_munged(&init_user_ns, current_fsgid());
119-
req->in.h.pid = pid_nr_ns(task_pid(current), fc->pid_ns);
120-
}
121-
122115
void fuse_set_initialized(struct fuse_conn *fc)
123116
{
124117
/* Make sure stores before this are seen on another CPU */
@@ -163,11 +156,19 @@ static struct fuse_req *__fuse_get_req(struct fuse_conn *fc, unsigned npages,
163156
goto out;
164157
}
165158

166-
fuse_req_init_context(fc, req);
159+
req->in.h.uid = from_kuid(&init_user_ns, current_fsuid());
160+
req->in.h.gid = from_kgid(&init_user_ns, current_fsgid());
161+
req->in.h.pid = pid_nr_ns(task_pid(current), fc->pid_ns);
162+
167163
__set_bit(FR_WAITING, &req->flags);
168164
if (for_background)
169165
__set_bit(FR_BACKGROUND, &req->flags);
170166

167+
if (unlikely(req->in.h.uid == ((uid_t)-1) ||
168+
req->in.h.gid == ((gid_t)-1))) {
169+
fuse_put_request(fc, req);
170+
return ERR_PTR(-EOVERFLOW);
171+
}
171172
return req;
172173

173174
out:
@@ -256,7 +257,10 @@ struct fuse_req *fuse_get_req_nofail_nopages(struct fuse_conn *fc,
256257
if (!req)
257258
req = get_reserved_req(fc, file);
258259

259-
fuse_req_init_context(fc, req);
260+
req->in.h.uid = from_kuid_munged(&init_user_ns, current_fsuid());
261+
req->in.h.gid = from_kgid_munged(&init_user_ns, current_fsgid());
262+
req->in.h.pid = pid_nr_ns(task_pid(current), fc->pid_ns);
263+
260264
__set_bit(FR_WAITING, &req->flags);
261265
__clear_bit(FR_BACKGROUND, &req->flags);
262266
return req;

0 commit comments

Comments
 (0)