diff options
Diffstat (limited to 'fs')
75 files changed, 773 insertions, 500 deletions
diff --git a/fs/9p/fid.c b/fs/9p/fid.c index da8eefbe830d..afd4724b2d92 100644 --- a/fs/9p/fid.c +++ b/fs/9p/fid.c | |||
@@ -74,19 +74,20 @@ int v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid) | |||
74 | * | 74 | * |
75 | */ | 75 | */ |
76 | 76 | ||
77 | static struct p9_fid *v9fs_fid_find(struct dentry *dentry, u32 uid, int any) | 77 | static struct p9_fid *v9fs_fid_find(struct dentry *dentry, kuid_t uid, int any) |
78 | { | 78 | { |
79 | struct v9fs_dentry *dent; | 79 | struct v9fs_dentry *dent; |
80 | struct p9_fid *fid, *ret; | 80 | struct p9_fid *fid, *ret; |
81 | 81 | ||
82 | p9_debug(P9_DEBUG_VFS, " dentry: %s (%p) uid %d any %d\n", | 82 | p9_debug(P9_DEBUG_VFS, " dentry: %s (%p) uid %d any %d\n", |
83 | dentry->d_name.name, dentry, uid, any); | 83 | dentry->d_name.name, dentry, from_kuid(&init_user_ns, uid), |
84 | any); | ||
84 | dent = (struct v9fs_dentry *) dentry->d_fsdata; | 85 | dent = (struct v9fs_dentry *) dentry->d_fsdata; |
85 | ret = NULL; | 86 | ret = NULL; |
86 | if (dent) { | 87 | if (dent) { |
87 | spin_lock(&dent->lock); | 88 | spin_lock(&dent->lock); |
88 | list_for_each_entry(fid, &dent->fidlist, dlist) { | 89 | list_for_each_entry(fid, &dent->fidlist, dlist) { |
89 | if (any || fid->uid == uid) { | 90 | if (any || uid_eq(fid->uid, uid)) { |
90 | ret = fid; | 91 | ret = fid; |
91 | break; | 92 | break; |
92 | } | 93 | } |
@@ -126,7 +127,7 @@ err_out: | |||
126 | } | 127 | } |
127 | 128 | ||
128 | static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry, | 129 | static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry, |
129 | uid_t uid, int any) | 130 | kuid_t uid, int any) |
130 | { | 131 | { |
131 | struct dentry *ds; | 132 | struct dentry *ds; |
132 | char **wnames, *uname; | 133 | char **wnames, *uname; |
@@ -233,7 +234,7 @@ err_out: | |||
233 | 234 | ||
234 | struct p9_fid *v9fs_fid_lookup(struct dentry *dentry) | 235 | struct p9_fid *v9fs_fid_lookup(struct dentry *dentry) |
235 | { | 236 | { |
236 | uid_t uid; | 237 | kuid_t uid; |
237 | int any, access; | 238 | int any, access; |
238 | struct v9fs_session_info *v9ses; | 239 | struct v9fs_session_info *v9ses; |
239 | 240 | ||
@@ -253,7 +254,7 @@ struct p9_fid *v9fs_fid_lookup(struct dentry *dentry) | |||
253 | break; | 254 | break; |
254 | 255 | ||
255 | default: | 256 | default: |
256 | uid = ~0; | 257 | uid = INVALID_UID; |
257 | any = 0; | 258 | any = 0; |
258 | break; | 259 | break; |
259 | } | 260 | } |
@@ -272,7 +273,7 @@ struct p9_fid *v9fs_fid_clone(struct dentry *dentry) | |||
272 | return ret; | 273 | return ret; |
273 | } | 274 | } |
274 | 275 | ||
275 | static struct p9_fid *v9fs_fid_clone_with_uid(struct dentry *dentry, uid_t uid) | 276 | static struct p9_fid *v9fs_fid_clone_with_uid(struct dentry *dentry, kuid_t uid) |
276 | { | 277 | { |
277 | struct p9_fid *fid, *ret; | 278 | struct p9_fid *fid, *ret; |
278 | 279 | ||
@@ -289,7 +290,7 @@ struct p9_fid *v9fs_writeback_fid(struct dentry *dentry) | |||
289 | int err; | 290 | int err; |
290 | struct p9_fid *fid; | 291 | struct p9_fid *fid; |
291 | 292 | ||
292 | fid = v9fs_fid_clone_with_uid(dentry, 0); | 293 | fid = v9fs_fid_clone_with_uid(dentry, GLOBAL_ROOT_UID); |
293 | if (IS_ERR(fid)) | 294 | if (IS_ERR(fid)) |
294 | goto error_out; | 295 | goto error_out; |
295 | /* | 296 | /* |
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index d934f04e7736..58e6cbce4156 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c | |||
@@ -161,7 +161,13 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts) | |||
161 | ret = r; | 161 | ret = r; |
162 | continue; | 162 | continue; |
163 | } | 163 | } |
164 | v9ses->dfltuid = option; | 164 | v9ses->dfltuid = make_kuid(current_user_ns(), option); |
165 | if (!uid_valid(v9ses->dfltuid)) { | ||
166 | p9_debug(P9_DEBUG_ERROR, | ||
167 | "uid field, but not a uid?\n"); | ||
168 | ret = -EINVAL; | ||
169 | continue; | ||
170 | } | ||
165 | break; | 171 | break; |
166 | case Opt_dfltgid: | 172 | case Opt_dfltgid: |
167 | r = match_int(&args[0], &option); | 173 | r = match_int(&args[0], &option); |
@@ -171,7 +177,13 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts) | |||
171 | ret = r; | 177 | ret = r; |
172 | continue; | 178 | continue; |
173 | } | 179 | } |
174 | v9ses->dfltgid = option; | 180 | v9ses->dfltgid = make_kgid(current_user_ns(), option); |
181 | if (!gid_valid(v9ses->dfltgid)) { | ||
182 | p9_debug(P9_DEBUG_ERROR, | ||
183 | "gid field, but not a gid?\n"); | ||
184 | ret = -EINVAL; | ||
185 | continue; | ||
186 | } | ||
175 | break; | 187 | break; |
176 | case Opt_afid: | 188 | case Opt_afid: |
177 | r = match_int(&args[0], &option); | 189 | r = match_int(&args[0], &option); |
@@ -248,8 +260,9 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts) | |||
248 | else if (strcmp(s, "client") == 0) { | 260 | else if (strcmp(s, "client") == 0) { |
249 | v9ses->flags |= V9FS_ACCESS_CLIENT; | 261 | v9ses->flags |= V9FS_ACCESS_CLIENT; |
250 | } else { | 262 | } else { |
263 | uid_t uid; | ||
251 | v9ses->flags |= V9FS_ACCESS_SINGLE; | 264 | v9ses->flags |= V9FS_ACCESS_SINGLE; |
252 | v9ses->uid = simple_strtoul(s, &e, 10); | 265 | uid = simple_strtoul(s, &e, 10); |
253 | if (*e != '\0') { | 266 | if (*e != '\0') { |
254 | ret = -EINVAL; | 267 | ret = -EINVAL; |
255 | pr_info("Unknown access argument %s\n", | 268 | pr_info("Unknown access argument %s\n", |
@@ -257,6 +270,13 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts) | |||
257 | kfree(s); | 270 | kfree(s); |
258 | goto free_and_return; | 271 | goto free_and_return; |
259 | } | 272 | } |
273 | v9ses->uid = make_kuid(current_user_ns(), uid); | ||
274 | if (!uid_valid(v9ses->uid)) { | ||
275 | ret = -EINVAL; | ||
276 | pr_info("Uknown uid %s\n", s); | ||
277 | kfree(s); | ||
278 | goto free_and_return; | ||
279 | } | ||
260 | } | 280 | } |
261 | 281 | ||
262 | kfree(s); | 282 | kfree(s); |
@@ -319,7 +339,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, | |||
319 | list_add(&v9ses->slist, &v9fs_sessionlist); | 339 | list_add(&v9ses->slist, &v9fs_sessionlist); |
320 | spin_unlock(&v9fs_sessionlist_lock); | 340 | spin_unlock(&v9fs_sessionlist_lock); |
321 | 341 | ||
322 | v9ses->uid = ~0; | 342 | v9ses->uid = INVALID_UID; |
323 | v9ses->dfltuid = V9FS_DEFUID; | 343 | v9ses->dfltuid = V9FS_DEFUID; |
324 | v9ses->dfltgid = V9FS_DEFGID; | 344 | v9ses->dfltgid = V9FS_DEFGID; |
325 | 345 | ||
@@ -364,7 +384,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, | |||
364 | 384 | ||
365 | v9ses->flags &= ~V9FS_ACCESS_MASK; | 385 | v9ses->flags &= ~V9FS_ACCESS_MASK; |
366 | v9ses->flags |= V9FS_ACCESS_ANY; | 386 | v9ses->flags |= V9FS_ACCESS_ANY; |
367 | v9ses->uid = ~0; | 387 | v9ses->uid = INVALID_UID; |
368 | } | 388 | } |
369 | if (!v9fs_proto_dotl(v9ses) || | 389 | if (!v9fs_proto_dotl(v9ses) || |
370 | !((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_CLIENT)) { | 390 | !((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_CLIENT)) { |
@@ -375,7 +395,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, | |||
375 | v9ses->flags &= ~V9FS_ACL_MASK; | 395 | v9ses->flags &= ~V9FS_ACL_MASK; |
376 | } | 396 | } |
377 | 397 | ||
378 | fid = p9_client_attach(v9ses->clnt, NULL, v9ses->uname, ~0, | 398 | fid = p9_client_attach(v9ses->clnt, NULL, v9ses->uname, INVALID_UID, |
379 | v9ses->aname); | 399 | v9ses->aname); |
380 | if (IS_ERR(fid)) { | 400 | if (IS_ERR(fid)) { |
381 | retval = PTR_ERR(fid); | 401 | retval = PTR_ERR(fid); |
@@ -387,7 +407,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, | |||
387 | if ((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_SINGLE) | 407 | if ((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_SINGLE) |
388 | fid->uid = v9ses->uid; | 408 | fid->uid = v9ses->uid; |
389 | else | 409 | else |
390 | fid->uid = ~0; | 410 | fid->uid = INVALID_UID; |
391 | 411 | ||
392 | #ifdef CONFIG_9P_FSCACHE | 412 | #ifdef CONFIG_9P_FSCACHE |
393 | /* register the session for caching */ | 413 | /* register the session for caching */ |
diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h index 34c59f14a1c9..a8e127c89627 100644 --- a/fs/9p/v9fs.h +++ b/fs/9p/v9fs.h | |||
@@ -109,9 +109,9 @@ struct v9fs_session_info { | |||
109 | char *uname; /* user name to mount as */ | 109 | char *uname; /* user name to mount as */ |
110 | char *aname; /* name of remote hierarchy being mounted */ | 110 | char *aname; /* name of remote hierarchy being mounted */ |
111 | unsigned int maxdata; /* max data for client interface */ | 111 | unsigned int maxdata; /* max data for client interface */ |
112 | unsigned int dfltuid; /* default uid/muid for legacy support */ | 112 | kuid_t dfltuid; /* default uid/muid for legacy support */ |
113 | unsigned int dfltgid; /* default gid for legacy support */ | 113 | kgid_t dfltgid; /* default gid for legacy support */ |
114 | u32 uid; /* if ACCESS_SINGLE, the uid that has access */ | 114 | kuid_t uid; /* if ACCESS_SINGLE, the uid that has access */ |
115 | struct p9_client *clnt; /* 9p client */ | 115 | struct p9_client *clnt; /* 9p client */ |
116 | struct list_head slist; /* list of sessions registered with v9fs */ | 116 | struct list_head slist; /* list of sessions registered with v9fs */ |
117 | struct backing_dev_info bdi; | 117 | struct backing_dev_info bdi; |
@@ -165,8 +165,8 @@ extern struct inode *v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses, | |||
165 | #define V9FS_PORT 564 | 165 | #define V9FS_PORT 564 |
166 | #define V9FS_DEFUSER "nobody" | 166 | #define V9FS_DEFUSER "nobody" |
167 | #define V9FS_DEFANAME "" | 167 | #define V9FS_DEFANAME "" |
168 | #define V9FS_DEFUID (-2) | 168 | #define V9FS_DEFUID KUIDT_INIT(-2) |
169 | #define V9FS_DEFGID (-2) | 169 | #define V9FS_DEFGID KGIDT_INIT(-2) |
170 | 170 | ||
171 | static inline struct v9fs_session_info *v9fs_inode2v9ses(struct inode *inode) | 171 | static inline struct v9fs_session_info *v9fs_inode2v9ses(struct inode *inode) |
172 | { | 172 | { |
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 57d017ac68e4..b5340c829de1 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
@@ -225,9 +225,9 @@ v9fs_blank_wstat(struct p9_wstat *wstat) | |||
225 | wstat->uid = NULL; | 225 | wstat->uid = NULL; |
226 | wstat->gid = NULL; | 226 | wstat->gid = NULL; |
227 | wstat->muid = NULL; | 227 | wstat->muid = NULL; |
228 | wstat->n_uid = ~0; | 228 | wstat->n_uid = INVALID_UID; |
229 | wstat->n_gid = ~0; | 229 | wstat->n_gid = INVALID_GID; |
230 | wstat->n_muid = ~0; | 230 | wstat->n_muid = INVALID_UID; |
231 | wstat->extension = NULL; | 231 | wstat->extension = NULL; |
232 | } | 232 | } |
233 | 233 | ||
diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c index 8d24ad66dfb8..07f409288d1b 100644 --- a/fs/9p/vfs_inode_dotl.c +++ b/fs/9p/vfs_inode_dotl.c | |||
@@ -57,7 +57,7 @@ v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, umode_t omode, | |||
57 | * group of the new file system object. | 57 | * group of the new file system object. |
58 | */ | 58 | */ |
59 | 59 | ||
60 | static gid_t v9fs_get_fsgid_for_create(struct inode *dir_inode) | 60 | static kgid_t v9fs_get_fsgid_for_create(struct inode *dir_inode) |
61 | { | 61 | { |
62 | BUG_ON(dir_inode == NULL); | 62 | BUG_ON(dir_inode == NULL); |
63 | 63 | ||
@@ -245,7 +245,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry, | |||
245 | int *opened) | 245 | int *opened) |
246 | { | 246 | { |
247 | int err = 0; | 247 | int err = 0; |
248 | gid_t gid; | 248 | kgid_t gid; |
249 | umode_t mode; | 249 | umode_t mode; |
250 | char *name = NULL; | 250 | char *name = NULL; |
251 | struct p9_qid qid; | 251 | struct p9_qid qid; |
@@ -396,7 +396,7 @@ static int v9fs_vfs_mkdir_dotl(struct inode *dir, | |||
396 | int err; | 396 | int err; |
397 | struct v9fs_session_info *v9ses; | 397 | struct v9fs_session_info *v9ses; |
398 | struct p9_fid *fid = NULL, *dfid = NULL; | 398 | struct p9_fid *fid = NULL, *dfid = NULL; |
399 | gid_t gid; | 399 | kgid_t gid; |
400 | char *name; | 400 | char *name; |
401 | umode_t mode; | 401 | umode_t mode; |
402 | struct inode *inode; | 402 | struct inode *inode; |
@@ -697,7 +697,7 @@ v9fs_vfs_symlink_dotl(struct inode *dir, struct dentry *dentry, | |||
697 | const char *symname) | 697 | const char *symname) |
698 | { | 698 | { |
699 | int err; | 699 | int err; |
700 | gid_t gid; | 700 | kgid_t gid; |
701 | char *name; | 701 | char *name; |
702 | struct p9_qid qid; | 702 | struct p9_qid qid; |
703 | struct inode *inode; | 703 | struct inode *inode; |
@@ -837,7 +837,7 @@ v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, umode_t omode, | |||
837 | dev_t rdev) | 837 | dev_t rdev) |
838 | { | 838 | { |
839 | int err; | 839 | int err; |
840 | gid_t gid; | 840 | kgid_t gid; |
841 | char *name; | 841 | char *name; |
842 | umode_t mode; | 842 | umode_t mode; |
843 | struct v9fs_session_info *v9ses; | 843 | struct v9fs_session_info *v9ses; |
diff --git a/fs/afs/afs.h b/fs/afs/afs.h index c548aa346f0d..3c462ff6db63 100644 --- a/fs/afs/afs.h +++ b/fs/afs/afs.h | |||
@@ -119,8 +119,8 @@ struct afs_file_status { | |||
119 | u64 size; /* file size */ | 119 | u64 size; /* file size */ |
120 | afs_dataversion_t data_version; /* current data version */ | 120 | afs_dataversion_t data_version; /* current data version */ |
121 | u32 author; /* author ID */ | 121 | u32 author; /* author ID */ |
122 | u32 owner; /* owner ID */ | 122 | kuid_t owner; /* owner ID */ |
123 | u32 group; /* group ID */ | 123 | kgid_t group; /* group ID */ |
124 | afs_access_t caller_access; /* access rights for authenticated caller */ | 124 | afs_access_t caller_access; /* access rights for authenticated caller */ |
125 | afs_access_t anon_access; /* access rights for unauthenticated caller */ | 125 | afs_access_t anon_access; /* access rights for unauthenticated caller */ |
126 | umode_t mode; /* UNIX mode */ | 126 | umode_t mode; /* UNIX mode */ |
@@ -133,13 +133,6 @@ struct afs_file_status { | |||
133 | /* | 133 | /* |
134 | * AFS file status change request | 134 | * AFS file status change request |
135 | */ | 135 | */ |
136 | struct afs_store_status { | ||
137 | u32 mask; /* which bits of the struct are set */ | ||
138 | u32 mtime_client; /* last time client changed data */ | ||
139 | u32 owner; /* owner ID */ | ||
140 | u32 group; /* group ID */ | ||
141 | umode_t mode; /* UNIX mode */ | ||
142 | }; | ||
143 | 136 | ||
144 | #define AFS_SET_MTIME 0x01 /* set the mtime */ | 137 | #define AFS_SET_MTIME 0x01 /* set the mtime */ |
145 | #define AFS_SET_OWNER 0x02 /* set the owner ID */ | 138 | #define AFS_SET_OWNER 0x02 /* set the owner ID */ |
diff --git a/fs/afs/fsclient.c b/fs/afs/fsclient.c index b960ff05ea0b..c2e930ec2888 100644 --- a/fs/afs/fsclient.c +++ b/fs/afs/fsclient.c | |||
@@ -42,6 +42,8 @@ static void xdr_decode_AFSFetchStatus(const __be32 **_bp, | |||
42 | umode_t mode; | 42 | umode_t mode; |
43 | u64 data_version, size; | 43 | u64 data_version, size; |
44 | u32 changed = 0; /* becomes non-zero if ctime-type changes seen */ | 44 | u32 changed = 0; /* becomes non-zero if ctime-type changes seen */ |
45 | kuid_t owner; | ||
46 | kgid_t group; | ||
45 | 47 | ||
46 | #define EXTRACT(DST) \ | 48 | #define EXTRACT(DST) \ |
47 | do { \ | 49 | do { \ |
@@ -56,7 +58,9 @@ static void xdr_decode_AFSFetchStatus(const __be32 **_bp, | |||
56 | size = ntohl(*bp++); | 58 | size = ntohl(*bp++); |
57 | data_version = ntohl(*bp++); | 59 | data_version = ntohl(*bp++); |
58 | EXTRACT(status->author); | 60 | EXTRACT(status->author); |
59 | EXTRACT(status->owner); | 61 | owner = make_kuid(&init_user_ns, ntohl(*bp++)); |
62 | changed |= !uid_eq(owner, status->owner); | ||
63 | status->owner = owner; | ||
60 | EXTRACT(status->caller_access); /* call ticket dependent */ | 64 | EXTRACT(status->caller_access); /* call ticket dependent */ |
61 | EXTRACT(status->anon_access); | 65 | EXTRACT(status->anon_access); |
62 | EXTRACT(status->mode); | 66 | EXTRACT(status->mode); |
@@ -65,7 +69,9 @@ static void xdr_decode_AFSFetchStatus(const __be32 **_bp, | |||
65 | bp++; /* seg size */ | 69 | bp++; /* seg size */ |
66 | status->mtime_client = ntohl(*bp++); | 70 | status->mtime_client = ntohl(*bp++); |
67 | status->mtime_server = ntohl(*bp++); | 71 | status->mtime_server = ntohl(*bp++); |
68 | EXTRACT(status->group); | 72 | group = make_kgid(&init_user_ns, ntohl(*bp++)); |
73 | changed |= !gid_eq(group, status->group); | ||
74 | status->group = group; | ||
69 | bp++; /* sync counter */ | 75 | bp++; /* sync counter */ |
70 | data_version |= (u64) ntohl(*bp++) << 32; | 76 | data_version |= (u64) ntohl(*bp++) << 32; |
71 | EXTRACT(status->lock_count); | 77 | EXTRACT(status->lock_count); |
@@ -181,12 +187,12 @@ static void xdr_encode_AFS_StoreStatus(__be32 **_bp, struct iattr *attr) | |||
181 | 187 | ||
182 | if (attr->ia_valid & ATTR_UID) { | 188 | if (attr->ia_valid & ATTR_UID) { |
183 | mask |= AFS_SET_OWNER; | 189 | mask |= AFS_SET_OWNER; |
184 | owner = attr->ia_uid; | 190 | owner = from_kuid(&init_user_ns, attr->ia_uid); |
185 | } | 191 | } |
186 | 192 | ||
187 | if (attr->ia_valid & ATTR_GID) { | 193 | if (attr->ia_valid & ATTR_GID) { |
188 | mask |= AFS_SET_GROUP; | 194 | mask |= AFS_SET_GROUP; |
189 | group = attr->ia_gid; | 195 | group = from_kgid(&init_user_ns, attr->ia_gid); |
190 | } | 196 | } |
191 | 197 | ||
192 | if (attr->ia_valid & ATTR_MODE) { | 198 | if (attr->ia_valid & ATTR_MODE) { |
diff --git a/fs/afs/inode.c b/fs/afs/inode.c index 95cffd38239f..789bc253b5f6 100644 --- a/fs/afs/inode.c +++ b/fs/afs/inode.c | |||
@@ -69,7 +69,7 @@ static int afs_inode_map_status(struct afs_vnode *vnode, struct key *key) | |||
69 | 69 | ||
70 | set_nlink(inode, vnode->status.nlink); | 70 | set_nlink(inode, vnode->status.nlink); |
71 | inode->i_uid = vnode->status.owner; | 71 | inode->i_uid = vnode->status.owner; |
72 | inode->i_gid = 0; | 72 | inode->i_gid = GLOBAL_ROOT_GID; |
73 | inode->i_size = vnode->status.size; | 73 | inode->i_size = vnode->status.size; |
74 | inode->i_ctime.tv_sec = vnode->status.mtime_server; | 74 | inode->i_ctime.tv_sec = vnode->status.mtime_server; |
75 | inode->i_ctime.tv_nsec = 0; | 75 | inode->i_ctime.tv_nsec = 0; |
@@ -175,8 +175,8 @@ struct inode *afs_iget_autocell(struct inode *dir, const char *dev_name, | |||
175 | inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO; | 175 | inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO; |
176 | inode->i_op = &afs_autocell_inode_operations; | 176 | inode->i_op = &afs_autocell_inode_operations; |
177 | set_nlink(inode, 2); | 177 | set_nlink(inode, 2); |
178 | inode->i_uid = 0; | 178 | inode->i_uid = GLOBAL_ROOT_UID; |
179 | inode->i_gid = 0; | 179 | inode->i_gid = GLOBAL_ROOT_GID; |
180 | inode->i_ctime.tv_sec = get_seconds(); | 180 | inode->i_ctime.tv_sec = get_seconds(); |
181 | inode->i_ctime.tv_nsec = 0; | 181 | inode->i_ctime.tv_nsec = 0; |
182 | inode->i_atime = inode->i_mtime = inode->i_ctime; | 182 | inode->i_atime = inode->i_mtime = inode->i_ctime; |
diff --git a/fs/afs/super.c b/fs/afs/super.c index 43165009428d..7c31ec399575 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c | |||
@@ -24,6 +24,8 @@ | |||
24 | #include <linux/parser.h> | 24 | #include <linux/parser.h> |
25 | #include <linux/statfs.h> | 25 | #include <linux/statfs.h> |
26 | #include <linux/sched.h> | 26 | #include <linux/sched.h> |
27 | #include <linux/nsproxy.h> | ||
28 | #include <net/net_namespace.h> | ||
27 | #include "internal.h" | 29 | #include "internal.h" |
28 | 30 | ||
29 | #define AFS_FS_MAGIC 0x6B414653 /* 'kAFS' */ | 31 | #define AFS_FS_MAGIC 0x6B414653 /* 'kAFS' */ |
@@ -363,6 +365,10 @@ static struct dentry *afs_mount(struct file_system_type *fs_type, | |||
363 | 365 | ||
364 | memset(¶ms, 0, sizeof(params)); | 366 | memset(¶ms, 0, sizeof(params)); |
365 | 367 | ||
368 | ret = -EINVAL; | ||
369 | if (current->nsproxy->net_ns != &init_net) | ||
370 | goto error; | ||
371 | |||
366 | /* parse the options and device name */ | 372 | /* parse the options and device name */ |
367 | if (options) { | 373 | if (options) { |
368 | ret = afs_parse_options(¶ms, options, &dev_name); | 374 | ret = afs_parse_options(¶ms, options, &dev_name); |
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index a1d9bb30c1bf..ae2be696eb5b 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c | |||
@@ -930,7 +930,7 @@ static int send_cap_msg(struct ceph_mds_session *session, | |||
930 | u64 size, u64 max_size, | 930 | u64 size, u64 max_size, |
931 | struct timespec *mtime, struct timespec *atime, | 931 | struct timespec *mtime, struct timespec *atime, |
932 | u64 time_warp_seq, | 932 | u64 time_warp_seq, |
933 | uid_t uid, gid_t gid, umode_t mode, | 933 | kuid_t uid, kgid_t gid, umode_t mode, |
934 | u64 xattr_version, | 934 | u64 xattr_version, |
935 | struct ceph_buffer *xattrs_buf, | 935 | struct ceph_buffer *xattrs_buf, |
936 | u64 follows) | 936 | u64 follows) |
@@ -974,8 +974,8 @@ static int send_cap_msg(struct ceph_mds_session *session, | |||
974 | ceph_encode_timespec(&fc->atime, atime); | 974 | ceph_encode_timespec(&fc->atime, atime); |
975 | fc->time_warp_seq = cpu_to_le32(time_warp_seq); | 975 | fc->time_warp_seq = cpu_to_le32(time_warp_seq); |
976 | 976 | ||
977 | fc->uid = cpu_to_le32(uid); | 977 | fc->uid = cpu_to_le32(from_kuid(&init_user_ns, uid)); |
978 | fc->gid = cpu_to_le32(gid); | 978 | fc->gid = cpu_to_le32(from_kgid(&init_user_ns, gid)); |
979 | fc->mode = cpu_to_le32(mode); | 979 | fc->mode = cpu_to_le32(mode); |
980 | 980 | ||
981 | fc->xattr_version = cpu_to_le64(xattr_version); | 981 | fc->xattr_version = cpu_to_le64(xattr_version); |
@@ -1081,8 +1081,8 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap, | |||
1081 | struct timespec mtime, atime; | 1081 | struct timespec mtime, atime; |
1082 | int wake = 0; | 1082 | int wake = 0; |
1083 | umode_t mode; | 1083 | umode_t mode; |
1084 | uid_t uid; | 1084 | kuid_t uid; |
1085 | gid_t gid; | 1085 | kgid_t gid; |
1086 | struct ceph_mds_session *session; | 1086 | struct ceph_mds_session *session; |
1087 | u64 xattr_version = 0; | 1087 | u64 xattr_version = 0; |
1088 | struct ceph_buffer *xattr_blob = NULL; | 1088 | struct ceph_buffer *xattr_blob = NULL; |
@@ -2359,10 +2359,11 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant, | |||
2359 | 2359 | ||
2360 | if ((issued & CEPH_CAP_AUTH_EXCL) == 0) { | 2360 | if ((issued & CEPH_CAP_AUTH_EXCL) == 0) { |
2361 | inode->i_mode = le32_to_cpu(grant->mode); | 2361 | inode->i_mode = le32_to_cpu(grant->mode); |
2362 | inode->i_uid = le32_to_cpu(grant->uid); | 2362 | inode->i_uid = make_kuid(&init_user_ns, le32_to_cpu(grant->uid)); |
2363 | inode->i_gid = le32_to_cpu(grant->gid); | 2363 | inode->i_gid = make_kgid(&init_user_ns, le32_to_cpu(grant->gid)); |
2364 | dout("%p mode 0%o uid.gid %d.%d\n", inode, inode->i_mode, | 2364 | dout("%p mode 0%o uid.gid %d.%d\n", inode, inode->i_mode, |
2365 | inode->i_uid, inode->i_gid); | 2365 | from_kuid(&init_user_ns, inode->i_uid), |
2366 | from_kgid(&init_user_ns, inode->i_gid)); | ||
2366 | } | 2367 | } |
2367 | 2368 | ||
2368 | if ((issued & CEPH_CAP_LINK_EXCL) == 0) | 2369 | if ((issued & CEPH_CAP_LINK_EXCL) == 0) |
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 2971eaa65cdc..d45895f4a04d 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c | |||
@@ -612,10 +612,11 @@ static int fill_inode(struct inode *inode, | |||
612 | 612 | ||
613 | if ((issued & CEPH_CAP_AUTH_EXCL) == 0) { | 613 | if ((issued & CEPH_CAP_AUTH_EXCL) == 0) { |
614 | inode->i_mode = le32_to_cpu(info->mode); | 614 | inode->i_mode = le32_to_cpu(info->mode); |
615 | inode->i_uid = le32_to_cpu(info->uid); | 615 | inode->i_uid = make_kuid(&init_user_ns, le32_to_cpu(info->uid)); |
616 | inode->i_gid = le32_to_cpu(info->gid); | 616 | inode->i_gid = make_kgid(&init_user_ns, le32_to_cpu(info->gid)); |
617 | dout("%p mode 0%o uid.gid %d.%d\n", inode, inode->i_mode, | 617 | dout("%p mode 0%o uid.gid %d.%d\n", inode, inode->i_mode, |
618 | inode->i_uid, inode->i_gid); | 618 | from_kuid(&init_user_ns, inode->i_uid), |
619 | from_kgid(&init_user_ns, inode->i_gid)); | ||
619 | } | 620 | } |
620 | 621 | ||
621 | if ((issued & CEPH_CAP_LINK_EXCL) == 0) | 622 | if ((issued & CEPH_CAP_LINK_EXCL) == 0) |
@@ -1565,26 +1566,30 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr) | |||
1565 | 1566 | ||
1566 | if (ia_valid & ATTR_UID) { | 1567 | if (ia_valid & ATTR_UID) { |
1567 | dout("setattr %p uid %d -> %d\n", inode, | 1568 | dout("setattr %p uid %d -> %d\n", inode, |
1568 | inode->i_uid, attr->ia_uid); | 1569 | from_kuid(&init_user_ns, inode->i_uid), |
1570 | from_kuid(&init_user_ns, attr->ia_uid)); | ||
1569 | if (issued & CEPH_CAP_AUTH_EXCL) { | 1571 | if (issued & CEPH_CAP_AUTH_EXCL) { |
1570 | inode->i_uid = attr->ia_uid; | 1572 | inode->i_uid = attr->ia_uid; |
1571 | dirtied |= CEPH_CAP_AUTH_EXCL; | 1573 | dirtied |= CEPH_CAP_AUTH_EXCL; |
1572 | } else if ((issued & CEPH_CAP_AUTH_SHARED) == 0 || | 1574 | } else if ((issued & CEPH_CAP_AUTH_SHARED) == 0 || |
1573 | attr->ia_uid != inode->i_uid) { | 1575 | !uid_eq(attr->ia_uid, inode->i_uid)) { |
1574 | req->r_args.setattr.uid = cpu_to_le32(attr->ia_uid); | 1576 | req->r_args.setattr.uid = cpu_to_le32( |
1577 | from_kuid(&init_user_ns, attr->ia_uid)); | ||
1575 | mask |= CEPH_SETATTR_UID; | 1578 | mask |= CEPH_SETATTR_UID; |
1576 | release |= CEPH_CAP_AUTH_SHARED; | 1579 | release |= CEPH_CAP_AUTH_SHARED; |
1577 | } | 1580 | } |
1578 | } | 1581 | } |
1579 | if (ia_valid & ATTR_GID) { | 1582 | if (ia_valid & ATTR_GID) { |
1580 | dout("setattr %p gid %d -> %d\n", inode, | 1583 | dout("setattr %p gid %d -> %d\n", inode, |
1581 | inode->i_gid, attr->ia_gid); | 1584 | from_kgid(&init_user_ns, inode->i_gid), |
1585 | from_kgid(&init_user_ns, attr->ia_gid)); | ||
1582 | if (issued & CEPH_CAP_AUTH_EXCL) { | 1586 | if (issued & CEPH_CAP_AUTH_EXCL) { |
1583 | inode->i_gid = attr->ia_gid; | 1587 | inode->i_gid = attr->ia_gid; |
1584 | dirtied |= CEPH_CAP_AUTH_EXCL; | 1588 | dirtied |= CEPH_CAP_AUTH_EXCL; |
1585 | } else if ((issued & CEPH_CAP_AUTH_SHARED) == 0 || | 1589 | } else if ((issued & CEPH_CAP_AUTH_SHARED) == 0 || |
1586 | attr->ia_gid != inode->i_gid) { | 1590 | !gid_eq(attr->ia_gid, inode->i_gid)) { |
1587 | req->r_args.setattr.gid = cpu_to_le32(attr->ia_gid); | 1591 | req->r_args.setattr.gid = cpu_to_le32( |
1592 | from_kgid(&init_user_ns, attr->ia_gid)); | ||
1588 | mask |= CEPH_SETATTR_GID; | 1593 | mask |= CEPH_SETATTR_GID; |
1589 | release |= CEPH_CAP_AUTH_SHARED; | 1594 | release |= CEPH_CAP_AUTH_SHARED; |
1590 | } | 1595 | } |
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 9165eb8309eb..7a3dfe0a9a80 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c | |||
@@ -1658,8 +1658,8 @@ static struct ceph_msg *create_request_message(struct ceph_mds_client *mdsc, | |||
1658 | 1658 | ||
1659 | head->mdsmap_epoch = cpu_to_le32(mdsc->mdsmap->m_epoch); | 1659 | head->mdsmap_epoch = cpu_to_le32(mdsc->mdsmap->m_epoch); |
1660 | head->op = cpu_to_le32(req->r_op); | 1660 | head->op = cpu_to_le32(req->r_op); |
1661 | head->caller_uid = cpu_to_le32(req->r_uid); | 1661 | head->caller_uid = cpu_to_le32(from_kuid(&init_user_ns, req->r_uid)); |
1662 | head->caller_gid = cpu_to_le32(req->r_gid); | 1662 | head->caller_gid = cpu_to_le32(from_kgid(&init_user_ns, req->r_gid)); |
1663 | head->args = req->r_args; | 1663 | head->args = req->r_args; |
1664 | 1664 | ||
1665 | ceph_encode_filepath(&p, end, ino1, path1); | 1665 | ceph_encode_filepath(&p, end, ino1, path1); |
diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h index dd26846dd71d..ff4188bf6199 100644 --- a/fs/ceph/mds_client.h +++ b/fs/ceph/mds_client.h | |||
@@ -184,8 +184,8 @@ struct ceph_mds_request { | |||
184 | 184 | ||
185 | union ceph_mds_request_args r_args; | 185 | union ceph_mds_request_args r_args; |
186 | int r_fmode; /* file mode, if expecting cap */ | 186 | int r_fmode; /* file mode, if expecting cap */ |
187 | uid_t r_uid; | 187 | kuid_t r_uid; |
188 | gid_t r_gid; | 188 | kgid_t r_gid; |
189 | 189 | ||
190 | /* for choosing which mds to send this request to */ | 190 | /* for choosing which mds to send this request to */ |
191 | int r_direct_mode; | 191 | int r_direct_mode; |
diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 66ebe720e40d..f053bbd1886f 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h | |||
@@ -138,8 +138,8 @@ struct ceph_cap_snap { | |||
138 | struct ceph_snap_context *context; | 138 | struct ceph_snap_context *context; |
139 | 139 | ||
140 | umode_t mode; | 140 | umode_t mode; |
141 | uid_t uid; | 141 | kuid_t uid; |
142 | gid_t gid; | 142 | kgid_t gid; |
143 | 143 | ||
144 | struct ceph_buffer *xattr_blob; | 144 | struct ceph_buffer *xattr_blob; |
145 | u64 xattr_version; | 145 | u64 xattr_version; |
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h index c865bfdfe819..37e4a72a7d1c 100644 --- a/fs/cifs/cifs_fs_sb.h +++ b/fs/cifs/cifs_fs_sb.h | |||
@@ -55,10 +55,10 @@ struct cifs_sb_info { | |||
55 | unsigned int wsize; | 55 | unsigned int wsize; |
56 | unsigned long actimeo; /* attribute cache timeout (jiffies) */ | 56 | unsigned long actimeo; /* attribute cache timeout (jiffies) */ |
57 | atomic_t active; | 57 | atomic_t active; |
58 | uid_t mnt_uid; | 58 | kuid_t mnt_uid; |
59 | gid_t mnt_gid; | 59 | kgid_t mnt_gid; |
60 | uid_t mnt_backupuid; | 60 | kuid_t mnt_backupuid; |
61 | gid_t mnt_backupgid; | 61 | kgid_t mnt_backupgid; |
62 | umode_t mnt_file_mode; | 62 | umode_t mnt_file_mode; |
63 | umode_t mnt_dir_mode; | 63 | umode_t mnt_dir_mode; |
64 | unsigned int mnt_cifs_flags; | 64 | unsigned int mnt_cifs_flags; |
diff --git a/fs/cifs/cifs_spnego.c b/fs/cifs/cifs_spnego.c index 086f381d6489..10e774761299 100644 --- a/fs/cifs/cifs_spnego.c +++ b/fs/cifs/cifs_spnego.c | |||
@@ -149,10 +149,12 @@ cifs_get_spnego_key(struct cifs_ses *sesInfo) | |||
149 | goto out; | 149 | goto out; |
150 | 150 | ||
151 | dp = description + strlen(description); | 151 | dp = description + strlen(description); |
152 | sprintf(dp, ";uid=0x%x", sesInfo->linux_uid); | 152 | sprintf(dp, ";uid=0x%x", |
153 | from_kuid_munged(&init_user_ns, sesInfo->linux_uid)); | ||
153 | 154 | ||
154 | dp = description + strlen(description); | 155 | dp = description + strlen(description); |
155 | sprintf(dp, ";creduid=0x%x", sesInfo->cred_uid); | 156 | sprintf(dp, ";creduid=0x%x", |
157 | from_kuid_munged(&init_user_ns, sesInfo->cred_uid)); | ||
156 | 158 | ||
157 | if (sesInfo->user_name) { | 159 | if (sesInfo->user_name) { |
158 | dp = description + strlen(description); | 160 | dp = description + strlen(description); |
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index 5cbd00e74067..f1e3f25fe004 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c | |||
@@ -266,8 +266,8 @@ sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid, | |||
266 | struct key *sidkey; | 266 | struct key *sidkey; |
267 | char *sidstr; | 267 | char *sidstr; |
268 | const struct cred *saved_cred; | 268 | const struct cred *saved_cred; |
269 | uid_t fuid = cifs_sb->mnt_uid; | 269 | kuid_t fuid = cifs_sb->mnt_uid; |
270 | gid_t fgid = cifs_sb->mnt_gid; | 270 | kgid_t fgid = cifs_sb->mnt_gid; |
271 | 271 | ||
272 | /* | 272 | /* |
273 | * If we have too many subauthorities, then something is really wrong. | 273 | * If we have too many subauthorities, then something is really wrong. |
@@ -297,6 +297,7 @@ sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid, | |||
297 | * probably a safe assumption but might be better to check based on | 297 | * probably a safe assumption but might be better to check based on |
298 | * sidtype. | 298 | * sidtype. |
299 | */ | 299 | */ |
300 | BUILD_BUG_ON(sizeof(uid_t) != sizeof(gid_t)); | ||
300 | if (sidkey->datalen != sizeof(uid_t)) { | 301 | if (sidkey->datalen != sizeof(uid_t)) { |
301 | rc = -EIO; | 302 | rc = -EIO; |
302 | cFYI(1, "%s: Downcall contained malformed key " | 303 | cFYI(1, "%s: Downcall contained malformed key " |
@@ -305,10 +306,21 @@ sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid, | |||
305 | goto out_key_put; | 306 | goto out_key_put; |
306 | } | 307 | } |
307 | 308 | ||
308 | if (sidtype == SIDOWNER) | 309 | if (sidtype == SIDOWNER) { |
309 | memcpy(&fuid, &sidkey->payload.value, sizeof(uid_t)); | 310 | kuid_t uid; |
310 | else | 311 | uid_t id; |
311 | memcpy(&fgid, &sidkey->payload.value, sizeof(gid_t)); | 312 | memcpy(&id, &sidkey->payload.value, sizeof(uid_t)); |
313 | uid = make_kuid(&init_user_ns, id); | ||
314 | if (uid_valid(uid)) | ||
315 | fuid = uid; | ||
316 | } else { | ||
317 | kgid_t gid; | ||
318 | gid_t id; | ||
319 | memcpy(&id, &sidkey->payload.value, sizeof(gid_t)); | ||
320 | gid = make_kgid(&init_user_ns, id); | ||
321 | if (gid_valid(gid)) | ||
322 | fgid = gid; | ||
323 | } | ||
312 | 324 | ||
313 | out_key_put: | 325 | out_key_put: |
314 | key_put(sidkey); | 326 | key_put(sidkey); |
@@ -346,7 +358,8 @@ init_cifs_idmap(void) | |||
346 | if (!cred) | 358 | if (!cred) |
347 | return -ENOMEM; | 359 | return -ENOMEM; |
348 | 360 | ||
349 | keyring = keyring_alloc(".cifs_idmap", 0, 0, cred, | 361 | keyring = keyring_alloc(".cifs_idmap", |
362 | GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, | ||
350 | (KEY_POS_ALL & ~KEY_POS_SETATTR) | | 363 | (KEY_POS_ALL & ~KEY_POS_SETATTR) | |
351 | KEY_USR_VIEW | KEY_USR_READ, | 364 | KEY_USR_VIEW | KEY_USR_READ, |
352 | KEY_ALLOC_NOT_IN_QUOTA, NULL); | 365 | KEY_ALLOC_NOT_IN_QUOTA, NULL); |
@@ -774,7 +787,7 @@ static int parse_sec_desc(struct cifs_sb_info *cifs_sb, | |||
774 | 787 | ||
775 | /* Convert permission bits from mode to equivalent CIFS ACL */ | 788 | /* Convert permission bits from mode to equivalent CIFS ACL */ |
776 | static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, | 789 | static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, |
777 | __u32 secdesclen, __u64 nmode, uid_t uid, gid_t gid, int *aclflag) | 790 | __u32 secdesclen, __u64 nmode, kuid_t uid, kgid_t gid, int *aclflag) |
778 | { | 791 | { |
779 | int rc = 0; | 792 | int rc = 0; |
780 | __u32 dacloffset; | 793 | __u32 dacloffset; |
@@ -806,17 +819,19 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, | |||
806 | *aclflag = CIFS_ACL_DACL; | 819 | *aclflag = CIFS_ACL_DACL; |
807 | } else { | 820 | } else { |
808 | memcpy(pnntsd, pntsd, secdesclen); | 821 | memcpy(pnntsd, pntsd, secdesclen); |
809 | if (uid != NO_CHANGE_32) { /* chown */ | 822 | if (uid_valid(uid)) { /* chown */ |
823 | uid_t id; | ||
810 | owner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + | 824 | owner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + |
811 | le32_to_cpu(pnntsd->osidoffset)); | 825 | le32_to_cpu(pnntsd->osidoffset)); |
812 | nowner_sid_ptr = kmalloc(sizeof(struct cifs_sid), | 826 | nowner_sid_ptr = kmalloc(sizeof(struct cifs_sid), |
813 | GFP_KERNEL); | 827 | GFP_KERNEL); |
814 | if (!nowner_sid_ptr) | 828 | if (!nowner_sid_ptr) |
815 | return -ENOMEM; | 829 | return -ENOMEM; |
816 | rc = id_to_sid(uid, SIDOWNER, nowner_sid_ptr); | 830 | id = from_kuid(&init_user_ns, uid); |
831 | rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr); | ||
817 | if (rc) { | 832 | if (rc) { |
818 | cFYI(1, "%s: Mapping error %d for owner id %d", | 833 | cFYI(1, "%s: Mapping error %d for owner id %d", |
819 | __func__, rc, uid); | 834 | __func__, rc, id); |
820 | kfree(nowner_sid_ptr); | 835 | kfree(nowner_sid_ptr); |
821 | return rc; | 836 | return rc; |
822 | } | 837 | } |
@@ -824,17 +839,19 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, | |||
824 | kfree(nowner_sid_ptr); | 839 | kfree(nowner_sid_ptr); |
825 | *aclflag = CIFS_ACL_OWNER; | 840 | *aclflag = CIFS_ACL_OWNER; |
826 | } | 841 | } |
827 | if (gid != NO_CHANGE_32) { /* chgrp */ | 842 | if (gid_valid(gid)) { /* chgrp */ |
843 | gid_t id; | ||
828 | group_sid_ptr = (struct cifs_sid *)((char *)pnntsd + | 844 | group_sid_ptr = (struct cifs_sid *)((char *)pnntsd + |
829 | le32_to_cpu(pnntsd->gsidoffset)); | 845 | le32_to_cpu(pnntsd->gsidoffset)); |
830 | ngroup_sid_ptr = kmalloc(sizeof(struct cifs_sid), | 846 | ngroup_sid_ptr = kmalloc(sizeof(struct cifs_sid), |
831 | GFP_KERNEL); | 847 | GFP_KERNEL); |
832 | if (!ngroup_sid_ptr) | 848 | if (!ngroup_sid_ptr) |
833 | return -ENOMEM; | 849 | return -ENOMEM; |
834 | rc = id_to_sid(gid, SIDGROUP, ngroup_sid_ptr); | 850 | id = from_kgid(&init_user_ns, gid); |
851 | rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr); | ||
835 | if (rc) { | 852 | if (rc) { |
836 | cFYI(1, "%s: Mapping error %d for group id %d", | 853 | cFYI(1, "%s: Mapping error %d for group id %d", |
837 | __func__, rc, gid); | 854 | __func__, rc, id); |
838 | kfree(ngroup_sid_ptr); | 855 | kfree(ngroup_sid_ptr); |
839 | return rc; | 856 | return rc; |
840 | } | 857 | } |
@@ -1002,7 +1019,7 @@ cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr, | |||
1002 | /* Convert mode bits to an ACL so we can update the ACL on the server */ | 1019 | /* Convert mode bits to an ACL so we can update the ACL on the server */ |
1003 | int | 1020 | int |
1004 | id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode, | 1021 | id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode, |
1005 | uid_t uid, gid_t gid) | 1022 | kuid_t uid, kgid_t gid) |
1006 | { | 1023 | { |
1007 | int rc = 0; | 1024 | int rc = 0; |
1008 | int aclflag = CIFS_ACL_DACL; /* default flag to set */ | 1025 | int aclflag = CIFS_ACL_DACL; /* default flag to set */ |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index de7f9168a118..9be09b21b4e0 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -375,13 +375,15 @@ cifs_show_options(struct seq_file *s, struct dentry *root) | |||
375 | (int)(srcaddr->sa_family)); | 375 | (int)(srcaddr->sa_family)); |
376 | } | 376 | } |
377 | 377 | ||
378 | seq_printf(s, ",uid=%u", cifs_sb->mnt_uid); | 378 | seq_printf(s, ",uid=%u", |
379 | from_kuid_munged(&init_user_ns, cifs_sb->mnt_uid)); | ||
379 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) | 380 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) |
380 | seq_printf(s, ",forceuid"); | 381 | seq_printf(s, ",forceuid"); |
381 | else | 382 | else |
382 | seq_printf(s, ",noforceuid"); | 383 | seq_printf(s, ",noforceuid"); |
383 | 384 | ||
384 | seq_printf(s, ",gid=%u", cifs_sb->mnt_gid); | 385 | seq_printf(s, ",gid=%u", |
386 | from_kgid_munged(&init_user_ns, cifs_sb->mnt_gid)); | ||
385 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) | 387 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) |
386 | seq_printf(s, ",forcegid"); | 388 | seq_printf(s, ",forcegid"); |
387 | else | 389 | else |
@@ -436,9 +438,13 @@ cifs_show_options(struct seq_file *s, struct dentry *root) | |||
436 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) | 438 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) |
437 | seq_printf(s, ",noperm"); | 439 | seq_printf(s, ",noperm"); |
438 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPUID) | 440 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPUID) |
439 | seq_printf(s, ",backupuid=%u", cifs_sb->mnt_backupuid); | 441 | seq_printf(s, ",backupuid=%u", |
442 | from_kuid_munged(&init_user_ns, | ||
443 | cifs_sb->mnt_backupuid)); | ||
440 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPGID) | 444 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPGID) |
441 | seq_printf(s, ",backupgid=%u", cifs_sb->mnt_backupgid); | 445 | seq_printf(s, ",backupgid=%u", |
446 | from_kgid_munged(&init_user_ns, | ||
447 | cifs_sb->mnt_backupgid)); | ||
442 | 448 | ||
443 | seq_printf(s, ",rsize=%u", cifs_sb->rsize); | 449 | seq_printf(s, ",rsize=%u", cifs_sb->rsize); |
444 | seq_printf(s, ",wsize=%u", cifs_sb->wsize); | 450 | seq_printf(s, ",wsize=%u", cifs_sb->wsize); |
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index e6899cea1c35..4f07f6fbe494 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
@@ -400,11 +400,11 @@ struct smb_vol { | |||
400 | char *iocharset; /* local code page for mapping to and from Unicode */ | 400 | char *iocharset; /* local code page for mapping to and from Unicode */ |
401 | char source_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* clnt nb name */ | 401 | char source_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* clnt nb name */ |
402 | char target_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* srvr nb name */ | 402 | char target_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* srvr nb name */ |
403 | uid_t cred_uid; | 403 | kuid_t cred_uid; |
404 | uid_t linux_uid; | 404 | kuid_t linux_uid; |
405 | gid_t linux_gid; | 405 | kgid_t linux_gid; |
406 | uid_t backupuid; | 406 | kuid_t backupuid; |
407 | gid_t backupgid; | 407 | kgid_t backupgid; |
408 | umode_t file_mode; | 408 | umode_t file_mode; |
409 | umode_t dir_mode; | 409 | umode_t dir_mode; |
410 | unsigned secFlg; | 410 | unsigned secFlg; |
@@ -703,8 +703,8 @@ struct cifs_ses { | |||
703 | char *serverNOS; /* name of network operating system of server */ | 703 | char *serverNOS; /* name of network operating system of server */ |
704 | char *serverDomain; /* security realm of server */ | 704 | char *serverDomain; /* security realm of server */ |
705 | __u64 Suid; /* remote smb uid */ | 705 | __u64 Suid; /* remote smb uid */ |
706 | uid_t linux_uid; /* overriding owner of files on the mount */ | 706 | kuid_t linux_uid; /* overriding owner of files on the mount */ |
707 | uid_t cred_uid; /* owner of credentials */ | 707 | kuid_t cred_uid; /* owner of credentials */ |
708 | unsigned int capabilities; | 708 | unsigned int capabilities; |
709 | char serverName[SERVER_NAME_LEN_WITH_NULL * 2]; /* BB make bigger for | 709 | char serverName[SERVER_NAME_LEN_WITH_NULL * 2]; /* BB make bigger for |
710 | TCP names - will ipv6 and sctp addresses fit? */ | 710 | TCP names - will ipv6 and sctp addresses fit? */ |
@@ -838,7 +838,7 @@ struct cifs_tcon { | |||
838 | */ | 838 | */ |
839 | struct tcon_link { | 839 | struct tcon_link { |
840 | struct rb_node tl_rbnode; | 840 | struct rb_node tl_rbnode; |
841 | uid_t tl_uid; | 841 | kuid_t tl_uid; |
842 | unsigned long tl_flags; | 842 | unsigned long tl_flags; |
843 | #define TCON_LINK_MASTER 0 | 843 | #define TCON_LINK_MASTER 0 |
844 | #define TCON_LINK_PENDING 1 | 844 | #define TCON_LINK_PENDING 1 |
@@ -931,7 +931,7 @@ struct cifsFileInfo { | |||
931 | struct list_head tlist; /* pointer to next fid owned by tcon */ | 931 | struct list_head tlist; /* pointer to next fid owned by tcon */ |
932 | struct list_head flist; /* next fid (file instance) for this inode */ | 932 | struct list_head flist; /* next fid (file instance) for this inode */ |
933 | struct cifs_fid_locks *llist; /* brlocks held by this fid */ | 933 | struct cifs_fid_locks *llist; /* brlocks held by this fid */ |
934 | unsigned int uid; /* allows finding which FileInfo structure */ | 934 | kuid_t uid; /* allows finding which FileInfo structure */ |
935 | __u32 pid; /* process id who opened file */ | 935 | __u32 pid; /* process id who opened file */ |
936 | struct cifs_fid fid; /* file id from remote */ | 936 | struct cifs_fid fid; /* file id from remote */ |
937 | /* BB add lock scope info here if needed */ ; | 937 | /* BB add lock scope info here if needed */ ; |
@@ -1245,8 +1245,8 @@ struct cifs_fattr { | |||
1245 | u64 cf_eof; | 1245 | u64 cf_eof; |
1246 | u64 cf_bytes; | 1246 | u64 cf_bytes; |
1247 | u64 cf_createtime; | 1247 | u64 cf_createtime; |
1248 | uid_t cf_uid; | 1248 | kuid_t cf_uid; |
1249 | gid_t cf_gid; | 1249 | kgid_t cf_gid; |
1250 | umode_t cf_mode; | 1250 | umode_t cf_mode; |
1251 | dev_t cf_rdev; | 1251 | dev_t cf_rdev; |
1252 | unsigned int cf_nlink; | 1252 | unsigned int cf_nlink; |
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index b9d59a948a2c..e996ff6b26d1 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h | |||
@@ -277,7 +277,6 @@ | |||
277 | #define CIFS_NO_HANDLE 0xFFFF | 277 | #define CIFS_NO_HANDLE 0xFFFF |
278 | 278 | ||
279 | #define NO_CHANGE_64 0xFFFFFFFFFFFFFFFFULL | 279 | #define NO_CHANGE_64 0xFFFFFFFFFFFFFFFFULL |
280 | #define NO_CHANGE_32 0xFFFFFFFFUL | ||
281 | 280 | ||
282 | /* IPC$ in ASCII */ | 281 | /* IPC$ in ASCII */ |
283 | #define CIFS_IPC_RESOURCE "\x49\x50\x43\x24" | 282 | #define CIFS_IPC_RESOURCE "\x49\x50\x43\x24" |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 1988c1baa224..f450f0683ddd 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -46,7 +46,8 @@ extern void _free_xid(unsigned int); | |||
46 | ({ \ | 46 | ({ \ |
47 | unsigned int __xid = _get_xid(); \ | 47 | unsigned int __xid = _get_xid(); \ |
48 | cFYI(1, "CIFS VFS: in %s as Xid: %u with uid: %d", \ | 48 | cFYI(1, "CIFS VFS: in %s as Xid: %u with uid: %d", \ |
49 | __func__, __xid, current_fsuid()); \ | 49 | __func__, __xid, \ |
50 | from_kuid(&init_user_ns, current_fsuid())); \ | ||
50 | __xid; \ | 51 | __xid; \ |
51 | }) | 52 | }) |
52 | 53 | ||
@@ -161,7 +162,7 @@ extern int cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, | |||
161 | struct cifs_fattr *fattr, struct inode *inode, | 162 | struct cifs_fattr *fattr, struct inode *inode, |
162 | const char *path, const __u16 *pfid); | 163 | const char *path, const __u16 *pfid); |
163 | extern int id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64, | 164 | extern int id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64, |
164 | uid_t, gid_t); | 165 | kuid_t, kgid_t); |
165 | extern struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *, struct inode *, | 166 | extern struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *, struct inode *, |
166 | const char *, u32 *); | 167 | const char *, u32 *); |
167 | extern int set_cifs_acl(struct cifs_ntsd *, __u32, struct inode *, | 168 | extern int set_cifs_acl(struct cifs_ntsd *, __u32, struct inode *, |
@@ -304,8 +305,8 @@ struct cifs_unix_set_info_args { | |||
304 | __u64 atime; | 305 | __u64 atime; |
305 | __u64 mtime; | 306 | __u64 mtime; |
306 | __u64 mode; | 307 | __u64 mode; |
307 | __u64 uid; | 308 | kuid_t uid; |
308 | __u64 gid; | 309 | kgid_t gid; |
309 | dev_t device; | 310 | dev_t device; |
310 | }; | 311 | }; |
311 | 312 | ||
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 76d0d2998850..00e12f2d626b 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -5819,8 +5819,14 @@ static void | |||
5819 | cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset, | 5819 | cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset, |
5820 | const struct cifs_unix_set_info_args *args) | 5820 | const struct cifs_unix_set_info_args *args) |
5821 | { | 5821 | { |
5822 | u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64; | ||
5822 | u64 mode = args->mode; | 5823 | u64 mode = args->mode; |
5823 | 5824 | ||
5825 | if (uid_valid(args->uid)) | ||
5826 | uid = from_kuid(&init_user_ns, args->uid); | ||
5827 | if (gid_valid(args->gid)) | ||
5828 | gid = from_kgid(&init_user_ns, args->gid); | ||
5829 | |||
5824 | /* | 5830 | /* |
5825 | * Samba server ignores set of file size to zero due to bugs in some | 5831 | * Samba server ignores set of file size to zero due to bugs in some |
5826 | * older clients, but we should be precise - we use SetFileSize to | 5832 | * older clients, but we should be precise - we use SetFileSize to |
@@ -5833,8 +5839,8 @@ cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset, | |||
5833 | data_offset->LastStatusChange = cpu_to_le64(args->ctime); | 5839 | data_offset->LastStatusChange = cpu_to_le64(args->ctime); |
5834 | data_offset->LastAccessTime = cpu_to_le64(args->atime); | 5840 | data_offset->LastAccessTime = cpu_to_le64(args->atime); |
5835 | data_offset->LastModificationTime = cpu_to_le64(args->mtime); | 5841 | data_offset->LastModificationTime = cpu_to_le64(args->mtime); |
5836 | data_offset->Uid = cpu_to_le64(args->uid); | 5842 | data_offset->Uid = cpu_to_le64(uid); |
5837 | data_offset->Gid = cpu_to_le64(args->gid); | 5843 | data_offset->Gid = cpu_to_le64(gid); |
5838 | /* better to leave device as zero when it is */ | 5844 | /* better to leave device as zero when it is */ |
5839 | data_offset->DevMajor = cpu_to_le64(MAJOR(args->device)); | 5845 | data_offset->DevMajor = cpu_to_le64(MAJOR(args->device)); |
5840 | data_offset->DevMinor = cpu_to_le64(MINOR(args->device)); | 5846 | data_offset->DevMinor = cpu_to_le64(MINOR(args->device)); |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 12b3da39733b..4474a57f30ab 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -987,6 +987,41 @@ static int get_option_ul(substring_t args[], unsigned long *option) | |||
987 | return rc; | 987 | return rc; |
988 | } | 988 | } |
989 | 989 | ||
990 | static int get_option_uid(substring_t args[], kuid_t *result) | ||
991 | { | ||
992 | unsigned long value; | ||
993 | kuid_t uid; | ||
994 | int rc; | ||
995 | |||
996 | rc = get_option_ul(args, &value); | ||
997 | if (rc) | ||
998 | return rc; | ||
999 | |||
1000 | uid = make_kuid(current_user_ns(), value); | ||
1001 | if (!uid_valid(uid)) | ||
1002 | return -EINVAL; | ||
1003 | |||
1004 | *result = uid; | ||
1005 | return 0; | ||
1006 | } | ||
1007 | |||
1008 | static int get_option_gid(substring_t args[], kgid_t *result) | ||
1009 | { | ||
1010 | unsigned long value; | ||
1011 | kgid_t gid; | ||
1012 | int rc; | ||
1013 | |||
1014 | rc = get_option_ul(args, &value); | ||
1015 | if (rc) | ||
1016 | return rc; | ||
1017 | |||
1018 | gid = make_kgid(current_user_ns(), value); | ||
1019 | if (!gid_valid(gid)) | ||
1020 | return -EINVAL; | ||
1021 | |||
1022 | *result = gid; | ||
1023 | return 0; | ||
1024 | } | ||
990 | 1025 | ||
991 | static int cifs_parse_security_flavors(char *value, | 1026 | static int cifs_parse_security_flavors(char *value, |
992 | struct smb_vol *vol) | 1027 | struct smb_vol *vol) |
@@ -1424,47 +1459,42 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, | |||
1424 | 1459 | ||
1425 | /* Numeric Values */ | 1460 | /* Numeric Values */ |
1426 | case Opt_backupuid: | 1461 | case Opt_backupuid: |
1427 | if (get_option_ul(args, &option)) { | 1462 | if (get_option_uid(args, &vol->backupuid)) { |
1428 | cERROR(1, "%s: Invalid backupuid value", | 1463 | cERROR(1, "%s: Invalid backupuid value", |
1429 | __func__); | 1464 | __func__); |
1430 | goto cifs_parse_mount_err; | 1465 | goto cifs_parse_mount_err; |
1431 | } | 1466 | } |
1432 | vol->backupuid = option; | ||
1433 | vol->backupuid_specified = true; | 1467 | vol->backupuid_specified = true; |
1434 | break; | 1468 | break; |
1435 | case Opt_backupgid: | 1469 | case Opt_backupgid: |
1436 | if (get_option_ul(args, &option)) { | 1470 | if (get_option_gid(args, &vol->backupgid)) { |
1437 | cERROR(1, "%s: Invalid backupgid value", | 1471 | cERROR(1, "%s: Invalid backupgid value", |
1438 | __func__); | 1472 | __func__); |
1439 | goto cifs_parse_mount_err; | 1473 | goto cifs_parse_mount_err; |
1440 | } | 1474 | } |
1441 | vol->backupgid = option; | ||
1442 | vol->backupgid_specified = true; | 1475 | vol->backupgid_specified = true; |
1443 | break; | 1476 | break; |
1444 | case Opt_uid: | 1477 | case Opt_uid: |
1445 | if (get_option_ul(args, &option)) { | 1478 | if (get_option_uid(args, &vol->linux_uid)) { |
1446 | cERROR(1, "%s: Invalid uid value", | 1479 | cERROR(1, "%s: Invalid uid value", |
1447 | __func__); | 1480 | __func__); |
1448 | goto cifs_parse_mount_err; | 1481 | goto cifs_parse_mount_err; |
1449 | } | 1482 | } |
1450 | vol->linux_uid = option; | ||
1451 | uid_specified = true; | 1483 | uid_specified = true; |
1452 | break; | 1484 | break; |
1453 | case Opt_cruid: | 1485 | case Opt_cruid: |
1454 | if (get_option_ul(args, &option)) { | 1486 | if (get_option_uid(args, &vol->cred_uid)) { |
1455 | cERROR(1, "%s: Invalid cruid value", | 1487 | cERROR(1, "%s: Invalid cruid value", |
1456 | __func__); | 1488 | __func__); |
1457 | goto cifs_parse_mount_err; | 1489 | goto cifs_parse_mount_err; |
1458 | } | 1490 | } |
1459 | vol->cred_uid = option; | ||
1460 | break; | 1491 | break; |
1461 | case Opt_gid: | 1492 | case Opt_gid: |
1462 | if (get_option_ul(args, &option)) { | 1493 | if (get_option_gid(args, &vol->linux_gid)) { |
1463 | cERROR(1, "%s: Invalid gid value", | 1494 | cERROR(1, "%s: Invalid gid value", |
1464 | __func__); | 1495 | __func__); |
1465 | goto cifs_parse_mount_err; | 1496 | goto cifs_parse_mount_err; |
1466 | } | 1497 | } |
1467 | vol->linux_gid = option; | ||
1468 | gid_specified = true; | 1498 | gid_specified = true; |
1469 | break; | 1499 | break; |
1470 | case Opt_file_mode: | 1500 | case Opt_file_mode: |
@@ -2241,7 +2271,7 @@ static int match_session(struct cifs_ses *ses, struct smb_vol *vol) | |||
2241 | { | 2271 | { |
2242 | switch (ses->server->secType) { | 2272 | switch (ses->server->secType) { |
2243 | case Kerberos: | 2273 | case Kerberos: |
2244 | if (vol->cred_uid != ses->cred_uid) | 2274 | if (!uid_eq(vol->cred_uid, ses->cred_uid)) |
2245 | return 0; | 2275 | return 0; |
2246 | break; | 2276 | break; |
2247 | default: | 2277 | default: |
@@ -2713,7 +2743,7 @@ compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data) | |||
2713 | if (new->rsize && new->rsize < old->rsize) | 2743 | if (new->rsize && new->rsize < old->rsize) |
2714 | return 0; | 2744 | return 0; |
2715 | 2745 | ||
2716 | if (old->mnt_uid != new->mnt_uid || old->mnt_gid != new->mnt_gid) | 2746 | if (!uid_eq(old->mnt_uid, new->mnt_uid) || !gid_eq(old->mnt_gid, new->mnt_gid)) |
2717 | return 0; | 2747 | return 0; |
2718 | 2748 | ||
2719 | if (old->mnt_file_mode != new->mnt_file_mode || | 2749 | if (old->mnt_file_mode != new->mnt_file_mode || |
@@ -3919,7 +3949,7 @@ cifs_set_vol_auth(struct smb_vol *vol, struct cifs_ses *ses) | |||
3919 | } | 3949 | } |
3920 | 3950 | ||
3921 | static struct cifs_tcon * | 3951 | static struct cifs_tcon * |
3922 | cifs_construct_tcon(struct cifs_sb_info *cifs_sb, uid_t fsuid) | 3952 | cifs_construct_tcon(struct cifs_sb_info *cifs_sb, kuid_t fsuid) |
3923 | { | 3953 | { |
3924 | int rc; | 3954 | int rc; |
3925 | struct cifs_tcon *master_tcon = cifs_sb_master_tcon(cifs_sb); | 3955 | struct cifs_tcon *master_tcon = cifs_sb_master_tcon(cifs_sb); |
@@ -3989,7 +4019,7 @@ cifs_sb_tcon_pending_wait(void *unused) | |||
3989 | 4019 | ||
3990 | /* find and return a tlink with given uid */ | 4020 | /* find and return a tlink with given uid */ |
3991 | static struct tcon_link * | 4021 | static struct tcon_link * |
3992 | tlink_rb_search(struct rb_root *root, uid_t uid) | 4022 | tlink_rb_search(struct rb_root *root, kuid_t uid) |
3993 | { | 4023 | { |
3994 | struct rb_node *node = root->rb_node; | 4024 | struct rb_node *node = root->rb_node; |
3995 | struct tcon_link *tlink; | 4025 | struct tcon_link *tlink; |
@@ -3997,9 +4027,9 @@ tlink_rb_search(struct rb_root *root, uid_t uid) | |||
3997 | while (node) { | 4027 | while (node) { |
3998 | tlink = rb_entry(node, struct tcon_link, tl_rbnode); | 4028 | tlink = rb_entry(node, struct tcon_link, tl_rbnode); |
3999 | 4029 | ||
4000 | if (tlink->tl_uid > uid) | 4030 | if (uid_gt(tlink->tl_uid, uid)) |
4001 | node = node->rb_left; | 4031 | node = node->rb_left; |
4002 | else if (tlink->tl_uid < uid) | 4032 | else if (uid_lt(tlink->tl_uid, uid)) |
4003 | node = node->rb_right; | 4033 | node = node->rb_right; |
4004 | else | 4034 | else |
4005 | return tlink; | 4035 | return tlink; |
@@ -4018,7 +4048,7 @@ tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink) | |||
4018 | tlink = rb_entry(*new, struct tcon_link, tl_rbnode); | 4048 | tlink = rb_entry(*new, struct tcon_link, tl_rbnode); |
4019 | parent = *new; | 4049 | parent = *new; |
4020 | 4050 | ||
4021 | if (tlink->tl_uid > new_tlink->tl_uid) | 4051 | if (uid_gt(tlink->tl_uid, new_tlink->tl_uid)) |
4022 | new = &((*new)->rb_left); | 4052 | new = &((*new)->rb_left); |
4023 | else | 4053 | else |
4024 | new = &((*new)->rb_right); | 4054 | new = &((*new)->rb_right); |
@@ -4048,7 +4078,7 @@ struct tcon_link * | |||
4048 | cifs_sb_tlink(struct cifs_sb_info *cifs_sb) | 4078 | cifs_sb_tlink(struct cifs_sb_info *cifs_sb) |
4049 | { | 4079 | { |
4050 | int ret; | 4080 | int ret; |
4051 | uid_t fsuid = current_fsuid(); | 4081 | kuid_t fsuid = current_fsuid(); |
4052 | struct tcon_link *tlink, *newtlink; | 4082 | struct tcon_link *tlink, *newtlink; |
4053 | 4083 | ||
4054 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)) | 4084 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)) |
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 8719bbe0dcc3..1cd016217448 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -342,14 +342,14 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid, | |||
342 | 342 | ||
343 | *created |= FILE_CREATED; | 343 | *created |= FILE_CREATED; |
344 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { | 344 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { |
345 | args.uid = (__u64) current_fsuid(); | 345 | args.uid = current_fsuid(); |
346 | if (inode->i_mode & S_ISGID) | 346 | if (inode->i_mode & S_ISGID) |
347 | args.gid = (__u64) inode->i_gid; | 347 | args.gid = inode->i_gid; |
348 | else | 348 | else |
349 | args.gid = (__u64) current_fsgid(); | 349 | args.gid = current_fsgid(); |
350 | } else { | 350 | } else { |
351 | args.uid = NO_CHANGE_64; | 351 | args.uid = INVALID_UID; /* no change */ |
352 | args.gid = NO_CHANGE_64; | 352 | args.gid = INVALID_GID; /* no change */ |
353 | } | 353 | } |
354 | CIFSSMBUnixSetFileInfo(xid, tcon, &args, fid->netfid, | 354 | CIFSSMBUnixSetFileInfo(xid, tcon, &args, fid->netfid, |
355 | current->tgid); | 355 | current->tgid); |
@@ -588,11 +588,11 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, umode_t mode, | |||
588 | .device = device_number, | 588 | .device = device_number, |
589 | }; | 589 | }; |
590 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { | 590 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { |
591 | args.uid = (__u64) current_fsuid(); | 591 | args.uid = current_fsuid(); |
592 | args.gid = (__u64) current_fsgid(); | 592 | args.gid = current_fsgid(); |
593 | } else { | 593 | } else { |
594 | args.uid = NO_CHANGE_64; | 594 | args.uid = INVALID_UID; /* no change */ |
595 | args.gid = NO_CHANGE_64; | 595 | args.gid = INVALID_GID; /* no change */ |
596 | } | 596 | } |
597 | rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, &args, | 597 | rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, &args, |
598 | cifs_sb->local_nls, | 598 | cifs_sb->local_nls, |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 8ea6ca50a665..a8d8b589ee0e 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -515,8 +515,8 @@ int cifs_open(struct inode *inode, struct file *file) | |||
515 | */ | 515 | */ |
516 | struct cifs_unix_set_info_args args = { | 516 | struct cifs_unix_set_info_args args = { |
517 | .mode = inode->i_mode, | 517 | .mode = inode->i_mode, |
518 | .uid = NO_CHANGE_64, | 518 | .uid = INVALID_UID, /* no change */ |
519 | .gid = NO_CHANGE_64, | 519 | .gid = INVALID_GID, /* no change */ |
520 | .ctime = NO_CHANGE_64, | 520 | .ctime = NO_CHANGE_64, |
521 | .atime = NO_CHANGE_64, | 521 | .atime = NO_CHANGE_64, |
522 | .mtime = NO_CHANGE_64, | 522 | .mtime = NO_CHANGE_64, |
@@ -1693,7 +1693,7 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode, | |||
1693 | are always at the end of the list but since the first entry might | 1693 | are always at the end of the list but since the first entry might |
1694 | have a close pending, we go through the whole list */ | 1694 | have a close pending, we go through the whole list */ |
1695 | list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { | 1695 | list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { |
1696 | if (fsuid_only && open_file->uid != current_fsuid()) | 1696 | if (fsuid_only && !uid_eq(open_file->uid, current_fsuid())) |
1697 | continue; | 1697 | continue; |
1698 | if (OPEN_FMODE(open_file->f_flags) & FMODE_READ) { | 1698 | if (OPEN_FMODE(open_file->f_flags) & FMODE_READ) { |
1699 | if (!open_file->invalidHandle) { | 1699 | if (!open_file->invalidHandle) { |
@@ -1746,7 +1746,7 @@ refind_writable: | |||
1746 | list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { | 1746 | list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { |
1747 | if (!any_available && open_file->pid != current->tgid) | 1747 | if (!any_available && open_file->pid != current->tgid) |
1748 | continue; | 1748 | continue; |
1749 | if (fsuid_only && open_file->uid != current_fsuid()) | 1749 | if (fsuid_only && !uid_eq(open_file->uid, current_fsuid())) |
1750 | continue; | 1750 | continue; |
1751 | if (OPEN_FMODE(open_file->f_flags) & FMODE_WRITE) { | 1751 | if (OPEN_FMODE(open_file->f_flags) & FMODE_WRITE) { |
1752 | if (!open_file->invalidHandle) { | 1752 | if (!open_file->invalidHandle) { |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index ed6208ff85a7..9638233964fc 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -244,15 +244,25 @@ cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info, | |||
244 | break; | 244 | break; |
245 | } | 245 | } |
246 | 246 | ||
247 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) | 247 | fattr->cf_uid = cifs_sb->mnt_uid; |
248 | fattr->cf_uid = cifs_sb->mnt_uid; | 248 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)) { |
249 | else | 249 | u64 id = le64_to_cpu(info->Uid); |
250 | fattr->cf_uid = le64_to_cpu(info->Uid); | 250 | if (id < ((uid_t)-1)) { |
251 | 251 | kuid_t uid = make_kuid(&init_user_ns, id); | |
252 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) | 252 | if (uid_valid(uid)) |
253 | fattr->cf_gid = cifs_sb->mnt_gid; | 253 | fattr->cf_uid = uid; |
254 | else | 254 | } |
255 | fattr->cf_gid = le64_to_cpu(info->Gid); | 255 | } |
256 | |||
257 | fattr->cf_gid = cifs_sb->mnt_gid; | ||
258 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)) { | ||
259 | u64 id = le64_to_cpu(info->Gid); | ||
260 | if (id < ((gid_t)-1)) { | ||
261 | kgid_t gid = make_kgid(&init_user_ns, id); | ||
262 | if (gid_valid(gid)) | ||
263 | fattr->cf_gid = gid; | ||
264 | } | ||
265 | } | ||
256 | 266 | ||
257 | fattr->cf_nlink = le64_to_cpu(info->Nlinks); | 267 | fattr->cf_nlink = le64_to_cpu(info->Nlinks); |
258 | } | 268 | } |
@@ -1245,14 +1255,14 @@ cifs_mkdir_qinfo(struct inode *parent, struct dentry *dentry, umode_t mode, | |||
1245 | .device = 0, | 1255 | .device = 0, |
1246 | }; | 1256 | }; |
1247 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { | 1257 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { |
1248 | args.uid = (__u64)current_fsuid(); | 1258 | args.uid = current_fsuid(); |
1249 | if (parent->i_mode & S_ISGID) | 1259 | if (parent->i_mode & S_ISGID) |
1250 | args.gid = (__u64)parent->i_gid; | 1260 | args.gid = parent->i_gid; |
1251 | else | 1261 | else |
1252 | args.gid = (__u64)current_fsgid(); | 1262 | args.gid = current_fsgid(); |
1253 | } else { | 1263 | } else { |
1254 | args.uid = NO_CHANGE_64; | 1264 | args.uid = INVALID_UID; /* no change */ |
1255 | args.gid = NO_CHANGE_64; | 1265 | args.gid = INVALID_GID; /* no change */ |
1256 | } | 1266 | } |
1257 | CIFSSMBUnixSetPathInfo(xid, tcon, full_path, &args, | 1267 | CIFSSMBUnixSetPathInfo(xid, tcon, full_path, &args, |
1258 | cifs_sb->local_nls, | 1268 | cifs_sb->local_nls, |
@@ -2013,12 +2023,12 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs) | |||
2013 | if (attrs->ia_valid & ATTR_UID) | 2023 | if (attrs->ia_valid & ATTR_UID) |
2014 | args->uid = attrs->ia_uid; | 2024 | args->uid = attrs->ia_uid; |
2015 | else | 2025 | else |
2016 | args->uid = NO_CHANGE_64; | 2026 | args->uid = INVALID_UID; /* no change */ |
2017 | 2027 | ||
2018 | if (attrs->ia_valid & ATTR_GID) | 2028 | if (attrs->ia_valid & ATTR_GID) |
2019 | args->gid = attrs->ia_gid; | 2029 | args->gid = attrs->ia_gid; |
2020 | else | 2030 | else |
2021 | args->gid = NO_CHANGE_64; | 2031 | args->gid = INVALID_GID; /* no change */ |
2022 | 2032 | ||
2023 | if (attrs->ia_valid & ATTR_ATIME) | 2033 | if (attrs->ia_valid & ATTR_ATIME) |
2024 | args->atime = cifs_UnixTimeToNT(attrs->ia_atime); | 2034 | args->atime = cifs_UnixTimeToNT(attrs->ia_atime); |
@@ -2086,8 +2096,8 @@ static int | |||
2086 | cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) | 2096 | cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) |
2087 | { | 2097 | { |
2088 | unsigned int xid; | 2098 | unsigned int xid; |
2089 | uid_t uid = NO_CHANGE_32; | 2099 | kuid_t uid = INVALID_UID; |
2090 | gid_t gid = NO_CHANGE_32; | 2100 | kgid_t gid = INVALID_GID; |
2091 | struct inode *inode = direntry->d_inode; | 2101 | struct inode *inode = direntry->d_inode; |
2092 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); | 2102 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
2093 | struct cifsInodeInfo *cifsInode = CIFS_I(inode); | 2103 | struct cifsInodeInfo *cifsInode = CIFS_I(inode); |
@@ -2146,7 +2156,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) | |||
2146 | 2156 | ||
2147 | #ifdef CONFIG_CIFS_ACL | 2157 | #ifdef CONFIG_CIFS_ACL |
2148 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { | 2158 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { |
2149 | if (uid != NO_CHANGE_32 || gid != NO_CHANGE_32) { | 2159 | if (uid_valid(uid) || gid_valid(gid)) { |
2150 | rc = id_mode_to_cifs_acl(inode, full_path, NO_CHANGE_64, | 2160 | rc = id_mode_to_cifs_acl(inode, full_path, NO_CHANGE_64, |
2151 | uid, gid); | 2161 | uid, gid); |
2152 | if (rc) { | 2162 | if (rc) { |
@@ -2170,7 +2180,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) | |||
2170 | #ifdef CONFIG_CIFS_ACL | 2180 | #ifdef CONFIG_CIFS_ACL |
2171 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { | 2181 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { |
2172 | rc = id_mode_to_cifs_acl(inode, full_path, mode, | 2182 | rc = id_mode_to_cifs_acl(inode, full_path, mode, |
2173 | NO_CHANGE_32, NO_CHANGE_32); | 2183 | INVALID_UID, INVALID_GID); |
2174 | if (rc) { | 2184 | if (rc) { |
2175 | cFYI(1, "%s: Setting ACL failed with error: %d", | 2185 | cFYI(1, "%s: Setting ACL failed with error: %d", |
2176 | __func__, rc); | 2186 | __func__, rc); |
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 3a00c0d0cead..1b15bf839f37 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c | |||
@@ -569,7 +569,7 @@ bool | |||
569 | backup_cred(struct cifs_sb_info *cifs_sb) | 569 | backup_cred(struct cifs_sb_info *cifs_sb) |
570 | { | 570 | { |
571 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPUID) { | 571 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPUID) { |
572 | if (cifs_sb->mnt_backupuid == current_fsuid()) | 572 | if (uid_eq(cifs_sb->mnt_backupuid, current_fsuid())) |
573 | return true; | 573 | return true; |
574 | } | 574 | } |
575 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPGID) { | 575 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPGID) { |
diff --git a/fs/coda/cache.c b/fs/coda/cache.c index 958ae0e0ff8c..1da168c61d35 100644 --- a/fs/coda/cache.c +++ b/fs/coda/cache.c | |||
@@ -33,7 +33,7 @@ void coda_cache_enter(struct inode *inode, int mask) | |||
33 | 33 | ||
34 | spin_lock(&cii->c_lock); | 34 | spin_lock(&cii->c_lock); |
35 | cii->c_cached_epoch = atomic_read(&permission_epoch); | 35 | cii->c_cached_epoch = atomic_read(&permission_epoch); |
36 | if (cii->c_uid != current_fsuid()) { | 36 | if (!uid_eq(cii->c_uid, current_fsuid())) { |
37 | cii->c_uid = current_fsuid(); | 37 | cii->c_uid = current_fsuid(); |
38 | cii->c_cached_perm = mask; | 38 | cii->c_cached_perm = mask; |
39 | } else | 39 | } else |
@@ -65,7 +65,7 @@ int coda_cache_check(struct inode *inode, int mask) | |||
65 | 65 | ||
66 | spin_lock(&cii->c_lock); | 66 | spin_lock(&cii->c_lock); |
67 | hit = (mask & cii->c_cached_perm) == mask && | 67 | hit = (mask & cii->c_cached_perm) == mask && |
68 | cii->c_uid == current_fsuid() && | 68 | uid_eq(cii->c_uid, current_fsuid()) && |
69 | cii->c_cached_epoch == atomic_read(&permission_epoch); | 69 | cii->c_cached_epoch == atomic_read(&permission_epoch); |
70 | spin_unlock(&cii->c_lock); | 70 | spin_unlock(&cii->c_lock); |
71 | 71 | ||
diff --git a/fs/coda/coda_fs_i.h b/fs/coda/coda_fs_i.h index b24fdfd8a3f0..c64075213218 100644 --- a/fs/coda/coda_fs_i.h +++ b/fs/coda/coda_fs_i.h | |||
@@ -25,7 +25,7 @@ struct coda_inode_info { | |||
25 | u_short c_flags; /* flags (see below) */ | 25 | u_short c_flags; /* flags (see below) */ |
26 | unsigned int c_mapcount; /* nr of times this inode is mapped */ | 26 | unsigned int c_mapcount; /* nr of times this inode is mapped */ |
27 | unsigned int c_cached_epoch; /* epoch for cached permissions */ | 27 | unsigned int c_cached_epoch; /* epoch for cached permissions */ |
28 | vuid_t c_uid; /* fsuid for cached permissions */ | 28 | kuid_t c_uid; /* fsuid for cached permissions */ |
29 | unsigned int c_cached_perm; /* cached access permissions */ | 29 | unsigned int c_cached_perm; /* cached access permissions */ |
30 | spinlock_t c_lock; | 30 | spinlock_t c_lock; |
31 | struct inode vfs_inode; | 31 | struct inode vfs_inode; |
diff --git a/fs/coda/coda_linux.c b/fs/coda/coda_linux.c index 854ace712685..2849f41e72a2 100644 --- a/fs/coda/coda_linux.c +++ b/fs/coda/coda_linux.c | |||
@@ -100,9 +100,9 @@ void coda_vattr_to_iattr(struct inode *inode, struct coda_vattr *attr) | |||
100 | if (attr->va_mode != (u_short) -1) | 100 | if (attr->va_mode != (u_short) -1) |
101 | inode->i_mode = attr->va_mode | inode_type; | 101 | inode->i_mode = attr->va_mode | inode_type; |
102 | if (attr->va_uid != -1) | 102 | if (attr->va_uid != -1) |
103 | inode->i_uid = (uid_t) attr->va_uid; | 103 | inode->i_uid = make_kuid(&init_user_ns, (uid_t) attr->va_uid); |
104 | if (attr->va_gid != -1) | 104 | if (attr->va_gid != -1) |
105 | inode->i_gid = (gid_t) attr->va_gid; | 105 | inode->i_gid = make_kgid(&init_user_ns, (gid_t) attr->va_gid); |
106 | if (attr->va_nlink != -1) | 106 | if (attr->va_nlink != -1) |
107 | set_nlink(inode, attr->va_nlink); | 107 | set_nlink(inode, attr->va_nlink); |
108 | if (attr->va_size != -1) | 108 | if (attr->va_size != -1) |
@@ -171,10 +171,10 @@ void coda_iattr_to_vattr(struct iattr *iattr, struct coda_vattr *vattr) | |||
171 | vattr->va_mode = iattr->ia_mode; | 171 | vattr->va_mode = iattr->ia_mode; |
172 | } | 172 | } |
173 | if ( valid & ATTR_UID ) { | 173 | if ( valid & ATTR_UID ) { |
174 | vattr->va_uid = (vuid_t) iattr->ia_uid; | 174 | vattr->va_uid = (vuid_t) from_kuid(&init_user_ns, iattr->ia_uid); |
175 | } | 175 | } |
176 | if ( valid & ATTR_GID ) { | 176 | if ( valid & ATTR_GID ) { |
177 | vattr->va_gid = (vgid_t) iattr->ia_gid; | 177 | vattr->va_gid = (vgid_t) from_kgid(&init_user_ns, iattr->ia_gid); |
178 | } | 178 | } |
179 | if ( valid & ATTR_SIZE ) { | 179 | if ( valid & ATTR_SIZE ) { |
180 | vattr->va_size = iattr->ia_size; | 180 | vattr->va_size = iattr->ia_size; |
diff --git a/fs/coda/inode.c b/fs/coda/inode.c index be2aa4909487..cf674e9179a3 100644 --- a/fs/coda/inode.c +++ b/fs/coda/inode.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/file.h> | 20 | #include <linux/file.h> |
21 | #include <linux/vfs.h> | 21 | #include <linux/vfs.h> |
22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
23 | #include <linux/pid_namespace.h> | ||
23 | 24 | ||
24 | #include <asm/uaccess.h> | 25 | #include <asm/uaccess.h> |
25 | 26 | ||
@@ -48,7 +49,7 @@ static struct inode *coda_alloc_inode(struct super_block *sb) | |||
48 | return NULL; | 49 | return NULL; |
49 | memset(&ei->c_fid, 0, sizeof(struct CodaFid)); | 50 | memset(&ei->c_fid, 0, sizeof(struct CodaFid)); |
50 | ei->c_flags = 0; | 51 | ei->c_flags = 0; |
51 | ei->c_uid = 0; | 52 | ei->c_uid = GLOBAL_ROOT_UID; |
52 | ei->c_cached_perm = 0; | 53 | ei->c_cached_perm = 0; |
53 | spin_lock_init(&ei->c_lock); | 54 | spin_lock_init(&ei->c_lock); |
54 | return &ei->vfs_inode; | 55 | return &ei->vfs_inode; |
@@ -157,6 +158,9 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent) | |||
157 | int error; | 158 | int error; |
158 | int idx; | 159 | int idx; |
159 | 160 | ||
161 | if (task_active_pid_ns(current) != &init_pid_ns) | ||
162 | return -EINVAL; | ||
163 | |||
160 | idx = get_device_index((struct coda_mount_data *) data); | 164 | idx = get_device_index((struct coda_mount_data *) data); |
161 | 165 | ||
162 | /* Ignore errors in data, for backward compatibility */ | 166 | /* Ignore errors in data, for backward compatibility */ |
diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c index 761d5b31b18d..ebc2bae6c289 100644 --- a/fs/coda/psdev.c +++ b/fs/coda/psdev.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/list.h> | 37 | #include <linux/list.h> |
38 | #include <linux/mutex.h> | 38 | #include <linux/mutex.h> |
39 | #include <linux/device.h> | 39 | #include <linux/device.h> |
40 | #include <linux/pid_namespace.h> | ||
40 | #include <asm/io.h> | 41 | #include <asm/io.h> |
41 | #include <asm/poll.h> | 42 | #include <asm/poll.h> |
42 | #include <asm/uaccess.h> | 43 | #include <asm/uaccess.h> |
@@ -266,6 +267,12 @@ static int coda_psdev_open(struct inode * inode, struct file * file) | |||
266 | struct venus_comm *vcp; | 267 | struct venus_comm *vcp; |
267 | int idx, err; | 268 | int idx, err; |
268 | 269 | ||
270 | if (task_active_pid_ns(current) != &init_pid_ns) | ||
271 | return -EINVAL; | ||
272 | |||
273 | if (current_user_ns() != &init_user_ns) | ||
274 | return -EINVAL; | ||
275 | |||
269 | idx = iminor(inode); | 276 | idx = iminor(inode); |
270 | if (idx < 0 || idx >= MAX_CODADEVS) | 277 | if (idx < 0 || idx >= MAX_CODADEVS) |
271 | return -ENODEV; | 278 | return -ENODEV; |
diff --git a/fs/coda/upcall.c b/fs/coda/upcall.c index 0c68fd31fbf2..3a731976dc5e 100644 --- a/fs/coda/upcall.c +++ b/fs/coda/upcall.c | |||
@@ -50,9 +50,9 @@ static void *alloc_upcall(int opcode, int size) | |||
50 | return ERR_PTR(-ENOMEM); | 50 | return ERR_PTR(-ENOMEM); |
51 | 51 | ||
52 | inp->ih.opcode = opcode; | 52 | inp->ih.opcode = opcode; |
53 | inp->ih.pid = current->pid; | 53 | inp->ih.pid = task_pid_nr_ns(current, &init_pid_ns); |
54 | inp->ih.pgid = task_pgrp_nr(current); | 54 | inp->ih.pgid = task_pgrp_nr_ns(current, &init_pid_ns); |
55 | inp->ih.uid = current_fsuid(); | 55 | inp->ih.uid = from_kuid(&init_user_ns, current_fsuid()); |
56 | 56 | ||
57 | return (void*)inp; | 57 | return (void*)inp; |
58 | } | 58 | } |
@@ -157,7 +157,7 @@ int venus_lookup(struct super_block *sb, struct CodaFid *fid, | |||
157 | } | 157 | } |
158 | 158 | ||
159 | int venus_close(struct super_block *sb, struct CodaFid *fid, int flags, | 159 | int venus_close(struct super_block *sb, struct CodaFid *fid, int flags, |
160 | vuid_t uid) | 160 | kuid_t uid) |
161 | { | 161 | { |
162 | union inputArgs *inp; | 162 | union inputArgs *inp; |
163 | union outputArgs *outp; | 163 | union outputArgs *outp; |
@@ -166,7 +166,7 @@ int venus_close(struct super_block *sb, struct CodaFid *fid, int flags, | |||
166 | insize = SIZE(release); | 166 | insize = SIZE(release); |
167 | UPARG(CODA_CLOSE); | 167 | UPARG(CODA_CLOSE); |
168 | 168 | ||
169 | inp->ih.uid = uid; | 169 | inp->ih.uid = from_kuid(&init_user_ns, uid); |
170 | inp->coda_close.VFid = *fid; | 170 | inp->coda_close.VFid = *fid; |
171 | inp->coda_close.flags = flags; | 171 | inp->coda_close.flags = flags; |
172 | 172 | ||
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index 472e6befc54d..073d30b9d1ac 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c | |||
@@ -243,6 +243,13 @@ static int mknod_ptmx(struct super_block *sb) | |||
243 | struct dentry *root = sb->s_root; | 243 | struct dentry *root = sb->s_root; |
244 | struct pts_fs_info *fsi = DEVPTS_SB(sb); | 244 | struct pts_fs_info *fsi = DEVPTS_SB(sb); |
245 | struct pts_mount_opts *opts = &fsi->mount_opts; | 245 | struct pts_mount_opts *opts = &fsi->mount_opts; |
246 | kuid_t root_uid; | ||
247 | kgid_t root_gid; | ||
248 | |||
249 | root_uid = make_kuid(current_user_ns(), 0); | ||
250 | root_gid = make_kgid(current_user_ns(), 0); | ||
251 | if (!uid_valid(root_uid) || !gid_valid(root_gid)) | ||
252 | return -EINVAL; | ||
246 | 253 | ||
247 | mutex_lock(&root->d_inode->i_mutex); | 254 | mutex_lock(&root->d_inode->i_mutex); |
248 | 255 | ||
@@ -273,6 +280,8 @@ static int mknod_ptmx(struct super_block *sb) | |||
273 | 280 | ||
274 | mode = S_IFCHR|opts->ptmxmode; | 281 | mode = S_IFCHR|opts->ptmxmode; |
275 | init_special_inode(inode, mode, MKDEV(TTYAUX_MAJOR, 2)); | 282 | init_special_inode(inode, mode, MKDEV(TTYAUX_MAJOR, 2)); |
283 | inode->i_uid = root_uid; | ||
284 | inode->i_gid = root_gid; | ||
276 | 285 | ||
277 | d_add(dentry, inode); | 286 | d_add(dentry, inode); |
278 | 287 | ||
@@ -438,6 +447,12 @@ static struct dentry *devpts_mount(struct file_system_type *fs_type, | |||
438 | if (error) | 447 | if (error) |
439 | return ERR_PTR(error); | 448 | return ERR_PTR(error); |
440 | 449 | ||
450 | /* Require newinstance for all user namespace mounts to ensure | ||
451 | * the mount options are not changed. | ||
452 | */ | ||
453 | if ((current_user_ns() != &init_user_ns) && !opts.newinstance) | ||
454 | return ERR_PTR(-EINVAL); | ||
455 | |||
441 | if (opts.newinstance) | 456 | if (opts.newinstance) |
442 | s = sget(fs_type, NULL, set_anon_super, flags, NULL); | 457 | s = sget(fs_type, NULL, set_anon_super, flags, NULL); |
443 | else | 458 | else |
@@ -491,6 +506,9 @@ static struct file_system_type devpts_fs_type = { | |||
491 | .name = "devpts", | 506 | .name = "devpts", |
492 | .mount = devpts_mount, | 507 | .mount = devpts_mount, |
493 | .kill_sb = devpts_kill_sb, | 508 | .kill_sb = devpts_kill_sb, |
509 | #ifdef CONFIG_DEVPTS_MULTIPLE_INSTANCES | ||
510 | .fs_flags = FS_USERNS_MOUNT | FS_USERNS_DEV_MOUNT, | ||
511 | #endif | ||
494 | }; | 512 | }; |
495 | 513 | ||
496 | /* | 514 | /* |
diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c index f850020ad906..f69ac0af5496 100644 --- a/fs/gfs2/acl.c +++ b/fs/gfs2/acl.c | |||
@@ -237,7 +237,7 @@ static int gfs2_xattr_system_set(struct dentry *dentry, const char *name, | |||
237 | return -EINVAL; | 237 | return -EINVAL; |
238 | if (type == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode)) | 238 | if (type == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode)) |
239 | return value ? -EACCES : 0; | 239 | return value ? -EACCES : 0; |
240 | if ((current_fsuid() != inode->i_uid) && !capable(CAP_FOWNER)) | 240 | if (!uid_eq(current_fsuid(), inode->i_uid) && !capable(CAP_FOWNER)) |
241 | return -EPERM; | 241 | return -EPERM; |
242 | if (S_ISLNK(inode->i_mode)) | 242 | if (S_ISLNK(inode->i_mode)) |
243 | return -EOPNOTSUPP; | 243 | return -EOPNOTSUPP; |
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index df686d13a7d2..5e83657f046e 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c | |||
@@ -1099,7 +1099,7 @@ static int trunc_dealloc(struct gfs2_inode *ip, u64 size) | |||
1099 | if (error) | 1099 | if (error) |
1100 | return error; | 1100 | return error; |
1101 | 1101 | ||
1102 | error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); | 1102 | error = gfs2_quota_hold(ip, NO_UID_QUOTA_CHANGE, NO_GID_QUOTA_CHANGE); |
1103 | if (error) | 1103 | if (error) |
1104 | return error; | 1104 | return error; |
1105 | 1105 | ||
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index 7179478e5a28..c3e82bd23179 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c | |||
@@ -1849,7 +1849,7 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len, | |||
1849 | if (!ht) | 1849 | if (!ht) |
1850 | return -ENOMEM; | 1850 | return -ENOMEM; |
1851 | 1851 | ||
1852 | error = gfs2_quota_hold(dip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); | 1852 | error = gfs2_quota_hold(dip, NO_UID_QUOTA_CHANGE, NO_GID_QUOTA_CHANGE); |
1853 | if (error) | 1853 | if (error) |
1854 | goto out; | 1854 | goto out; |
1855 | 1855 | ||
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index 78d4184ffc7d..444b6503ebc4 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c | |||
@@ -322,8 +322,8 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) | |||
322 | break; | 322 | break; |
323 | }; | 323 | }; |
324 | 324 | ||
325 | ip->i_inode.i_uid = be32_to_cpu(str->di_uid); | 325 | i_uid_write(&ip->i_inode, be32_to_cpu(str->di_uid)); |
326 | ip->i_inode.i_gid = be32_to_cpu(str->di_gid); | 326 | i_gid_write(&ip->i_inode, be32_to_cpu(str->di_gid)); |
327 | gfs2_set_nlink(&ip->i_inode, be32_to_cpu(str->di_nlink)); | 327 | gfs2_set_nlink(&ip->i_inode, be32_to_cpu(str->di_nlink)); |
328 | i_size_write(&ip->i_inode, be64_to_cpu(str->di_size)); | 328 | i_size_write(&ip->i_inode, be64_to_cpu(str->di_size)); |
329 | gfs2_set_inode_blocks(&ip->i_inode, be64_to_cpu(str->di_blocks)); | 329 | gfs2_set_inode_blocks(&ip->i_inode, be64_to_cpu(str->di_blocks)); |
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index e2601ba38ef5..156e42ec84ea 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h | |||
@@ -392,7 +392,6 @@ struct gfs2_revoke_replay { | |||
392 | }; | 392 | }; |
393 | 393 | ||
394 | enum { | 394 | enum { |
395 | QDF_USER = 0, | ||
396 | QDF_CHANGE = 1, | 395 | QDF_CHANGE = 1, |
397 | QDF_LOCKED = 2, | 396 | QDF_LOCKED = 2, |
398 | QDF_REFRESH = 3, | 397 | QDF_REFRESH = 3, |
@@ -404,7 +403,7 @@ struct gfs2_quota_data { | |||
404 | 403 | ||
405 | atomic_t qd_count; | 404 | atomic_t qd_count; |
406 | 405 | ||
407 | u32 qd_id; | 406 | struct kqid qd_id; |
408 | unsigned long qd_flags; /* QDF_... */ | 407 | unsigned long qd_flags; /* QDF_... */ |
409 | 408 | ||
410 | s64 qd_change; | 409 | s64 qd_change; |
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index db048a8ab6a8..cc00bd1d1f87 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -368,10 +368,11 @@ static void munge_mode_uid_gid(const struct gfs2_inode *dip, | |||
368 | struct inode *inode) | 368 | struct inode *inode) |
369 | { | 369 | { |
370 | if (GFS2_SB(&dip->i_inode)->sd_args.ar_suiddir && | 370 | if (GFS2_SB(&dip->i_inode)->sd_args.ar_suiddir && |
371 | (dip->i_inode.i_mode & S_ISUID) && dip->i_inode.i_uid) { | 371 | (dip->i_inode.i_mode & S_ISUID) && |
372 | !uid_eq(dip->i_inode.i_uid, GLOBAL_ROOT_UID)) { | ||
372 | if (S_ISDIR(inode->i_mode)) | 373 | if (S_ISDIR(inode->i_mode)) |
373 | inode->i_mode |= S_ISUID; | 374 | inode->i_mode |= S_ISUID; |
374 | else if (dip->i_inode.i_uid != current_fsuid()) | 375 | else if (!uid_eq(dip->i_inode.i_uid, current_fsuid())) |
375 | inode->i_mode &= ~07111; | 376 | inode->i_mode &= ~07111; |
376 | inode->i_uid = dip->i_inode.i_uid; | 377 | inode->i_uid = dip->i_inode.i_uid; |
377 | } else | 378 | } else |
@@ -455,8 +456,8 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_inode *ip, | |||
455 | di->di_num.no_formal_ino = cpu_to_be64(ip->i_no_formal_ino); | 456 | di->di_num.no_formal_ino = cpu_to_be64(ip->i_no_formal_ino); |
456 | di->di_num.no_addr = cpu_to_be64(ip->i_no_addr); | 457 | di->di_num.no_addr = cpu_to_be64(ip->i_no_addr); |
457 | di->di_mode = cpu_to_be32(ip->i_inode.i_mode); | 458 | di->di_mode = cpu_to_be32(ip->i_inode.i_mode); |
458 | di->di_uid = cpu_to_be32(ip->i_inode.i_uid); | 459 | di->di_uid = cpu_to_be32(i_uid_read(&ip->i_inode)); |
459 | di->di_gid = cpu_to_be32(ip->i_inode.i_gid); | 460 | di->di_gid = cpu_to_be32(i_gid_read(&ip->i_inode)); |
460 | di->di_nlink = 0; | 461 | di->di_nlink = 0; |
461 | di->di_size = cpu_to_be64(ip->i_inode.i_size); | 462 | di->di_size = cpu_to_be64(ip->i_inode.i_size); |
462 | di->di_blocks = cpu_to_be64(1); | 463 | di->di_blocks = cpu_to_be64(1); |
@@ -548,7 +549,7 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name, | |||
548 | if (error) | 549 | if (error) |
549 | return error; | 550 | return error; |
550 | 551 | ||
551 | error = gfs2_quota_lock(dip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); | 552 | error = gfs2_quota_lock(dip, NO_UID_QUOTA_CHANGE, NO_GID_QUOTA_CHANGE); |
552 | if (error) | 553 | if (error) |
553 | goto fail; | 554 | goto fail; |
554 | 555 | ||
@@ -978,8 +979,8 @@ static int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, | |||
978 | return -EPERM; | 979 | return -EPERM; |
979 | 980 | ||
980 | if ((dip->i_inode.i_mode & S_ISVTX) && | 981 | if ((dip->i_inode.i_mode & S_ISVTX) && |
981 | dip->i_inode.i_uid != current_fsuid() && | 982 | !uid_eq(dip->i_inode.i_uid, current_fsuid()) && |
982 | ip->i_inode.i_uid != current_fsuid() && !capable(CAP_FOWNER)) | 983 | !uid_eq(ip->i_inode.i_uid, current_fsuid()) && !capable(CAP_FOWNER)) |
983 | return -EPERM; | 984 | return -EPERM; |
984 | 985 | ||
985 | if (IS_APPEND(&dip->i_inode)) | 986 | if (IS_APPEND(&dip->i_inode)) |
@@ -1580,7 +1581,8 @@ static int setattr_chown(struct inode *inode, struct iattr *attr) | |||
1580 | { | 1581 | { |
1581 | struct gfs2_inode *ip = GFS2_I(inode); | 1582 | struct gfs2_inode *ip = GFS2_I(inode); |
1582 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 1583 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
1583 | u32 ouid, ogid, nuid, ngid; | 1584 | kuid_t ouid, nuid; |
1585 | kgid_t ogid, ngid; | ||
1584 | int error; | 1586 | int error; |
1585 | 1587 | ||
1586 | ouid = inode->i_uid; | 1588 | ouid = inode->i_uid; |
@@ -1588,16 +1590,17 @@ static int setattr_chown(struct inode *inode, struct iattr *attr) | |||
1588 | nuid = attr->ia_uid; | 1590 | nuid = attr->ia_uid; |
1589 | ngid = attr->ia_gid; | 1591 | ngid = attr->ia_gid; |
1590 | 1592 | ||
1591 | if (!(attr->ia_valid & ATTR_UID) || ouid == nuid) | 1593 | if (!(attr->ia_valid & ATTR_UID) || uid_eq(ouid, nuid)) |
1592 | ouid = nuid = NO_QUOTA_CHANGE; | 1594 | ouid = nuid = NO_UID_QUOTA_CHANGE; |
1593 | if (!(attr->ia_valid & ATTR_GID) || ogid == ngid) | 1595 | if (!(attr->ia_valid & ATTR_GID) || gid_eq(ogid, ngid)) |
1594 | ogid = ngid = NO_QUOTA_CHANGE; | 1596 | ogid = ngid = NO_GID_QUOTA_CHANGE; |
1595 | 1597 | ||
1596 | error = gfs2_quota_lock(ip, nuid, ngid); | 1598 | error = gfs2_quota_lock(ip, nuid, ngid); |
1597 | if (error) | 1599 | if (error) |
1598 | return error; | 1600 | return error; |
1599 | 1601 | ||
1600 | if (ouid != NO_QUOTA_CHANGE || ogid != NO_QUOTA_CHANGE) { | 1602 | if (!uid_eq(ouid, NO_UID_QUOTA_CHANGE) || |
1603 | !gid_eq(ogid, NO_GID_QUOTA_CHANGE)) { | ||
1601 | error = gfs2_quota_check(ip, nuid, ngid); | 1604 | error = gfs2_quota_check(ip, nuid, ngid); |
1602 | if (error) | 1605 | if (error) |
1603 | goto out_gunlock_q; | 1606 | goto out_gunlock_q; |
@@ -1611,7 +1614,8 @@ static int setattr_chown(struct inode *inode, struct iattr *attr) | |||
1611 | if (error) | 1614 | if (error) |
1612 | goto out_end_trans; | 1615 | goto out_end_trans; |
1613 | 1616 | ||
1614 | if (ouid != NO_QUOTA_CHANGE || ogid != NO_QUOTA_CHANGE) { | 1617 | if (!uid_eq(ouid, NO_UID_QUOTA_CHANGE) || |
1618 | !gid_eq(ogid, NO_GID_QUOTA_CHANGE)) { | ||
1615 | u64 blocks = gfs2_get_inode_blocks(&ip->i_inode); | 1619 | u64 blocks = gfs2_get_inode_blocks(&ip->i_inode); |
1616 | gfs2_quota_change(ip, -blocks, ouid, ogid); | 1620 | gfs2_quota_change(ip, -blocks, ouid, ogid); |
1617 | gfs2_quota_change(ip, blocks, nuid, ngid); | 1621 | gfs2_quota_change(ip, blocks, nuid, ngid); |
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index 06122d09c0d1..c7c840e916f8 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c | |||
@@ -65,13 +65,10 @@ | |||
65 | #include "inode.h" | 65 | #include "inode.h" |
66 | #include "util.h" | 66 | #include "util.h" |
67 | 67 | ||
68 | #define QUOTA_USER 1 | ||
69 | #define QUOTA_GROUP 0 | ||
70 | |||
71 | struct gfs2_quota_change_host { | 68 | struct gfs2_quota_change_host { |
72 | u64 qc_change; | 69 | u64 qc_change; |
73 | u32 qc_flags; /* GFS2_QCF_... */ | 70 | u32 qc_flags; /* GFS2_QCF_... */ |
74 | u32 qc_id; | 71 | struct kqid qc_id; |
75 | }; | 72 | }; |
76 | 73 | ||
77 | static LIST_HEAD(qd_lru_list); | 74 | static LIST_HEAD(qd_lru_list); |
@@ -120,17 +117,24 @@ out: | |||
120 | return (atomic_read(&qd_lru_count) * sysctl_vfs_cache_pressure) / 100; | 117 | return (atomic_read(&qd_lru_count) * sysctl_vfs_cache_pressure) / 100; |
121 | } | 118 | } |
122 | 119 | ||
120 | static u64 qd2index(struct gfs2_quota_data *qd) | ||
121 | { | ||
122 | struct kqid qid = qd->qd_id; | ||
123 | return (2 * (u64)from_kqid(&init_user_ns, qid)) + | ||
124 | (qid.type == USRQUOTA) ? 0 : 1; | ||
125 | } | ||
126 | |||
123 | static u64 qd2offset(struct gfs2_quota_data *qd) | 127 | static u64 qd2offset(struct gfs2_quota_data *qd) |
124 | { | 128 | { |
125 | u64 offset; | 129 | u64 offset; |
126 | 130 | ||
127 | offset = 2 * (u64)qd->qd_id + !test_bit(QDF_USER, &qd->qd_flags); | 131 | offset = qd2index(qd); |
128 | offset *= sizeof(struct gfs2_quota); | 132 | offset *= sizeof(struct gfs2_quota); |
129 | 133 | ||
130 | return offset; | 134 | return offset; |
131 | } | 135 | } |
132 | 136 | ||
133 | static int qd_alloc(struct gfs2_sbd *sdp, int user, u32 id, | 137 | static int qd_alloc(struct gfs2_sbd *sdp, struct kqid qid, |
134 | struct gfs2_quota_data **qdp) | 138 | struct gfs2_quota_data **qdp) |
135 | { | 139 | { |
136 | struct gfs2_quota_data *qd; | 140 | struct gfs2_quota_data *qd; |
@@ -141,13 +145,11 @@ static int qd_alloc(struct gfs2_sbd *sdp, int user, u32 id, | |||
141 | return -ENOMEM; | 145 | return -ENOMEM; |
142 | 146 | ||
143 | atomic_set(&qd->qd_count, 1); | 147 | atomic_set(&qd->qd_count, 1); |
144 | qd->qd_id = id; | 148 | qd->qd_id = qid; |
145 | if (user) | ||
146 | set_bit(QDF_USER, &qd->qd_flags); | ||
147 | qd->qd_slot = -1; | 149 | qd->qd_slot = -1; |
148 | INIT_LIST_HEAD(&qd->qd_reclaim); | 150 | INIT_LIST_HEAD(&qd->qd_reclaim); |
149 | 151 | ||
150 | error = gfs2_glock_get(sdp, 2 * (u64)id + !user, | 152 | error = gfs2_glock_get(sdp, qd2index(qd), |
151 | &gfs2_quota_glops, CREATE, &qd->qd_gl); | 153 | &gfs2_quota_glops, CREATE, &qd->qd_gl); |
152 | if (error) | 154 | if (error) |
153 | goto fail; | 155 | goto fail; |
@@ -161,7 +163,7 @@ fail: | |||
161 | return error; | 163 | return error; |
162 | } | 164 | } |
163 | 165 | ||
164 | static int qd_get(struct gfs2_sbd *sdp, int user, u32 id, | 166 | static int qd_get(struct gfs2_sbd *sdp, struct kqid qid, |
165 | struct gfs2_quota_data **qdp) | 167 | struct gfs2_quota_data **qdp) |
166 | { | 168 | { |
167 | struct gfs2_quota_data *qd = NULL, *new_qd = NULL; | 169 | struct gfs2_quota_data *qd = NULL, *new_qd = NULL; |
@@ -173,8 +175,7 @@ static int qd_get(struct gfs2_sbd *sdp, int user, u32 id, | |||
173 | found = 0; | 175 | found = 0; |
174 | spin_lock(&qd_lru_lock); | 176 | spin_lock(&qd_lru_lock); |
175 | list_for_each_entry(qd, &sdp->sd_quota_list, qd_list) { | 177 | list_for_each_entry(qd, &sdp->sd_quota_list, qd_list) { |
176 | if (qd->qd_id == id && | 178 | if (qid_eq(qd->qd_id, qid)) { |
177 | !test_bit(QDF_USER, &qd->qd_flags) == !user) { | ||
178 | if (!atomic_read(&qd->qd_count) && | 179 | if (!atomic_read(&qd->qd_count) && |
179 | !list_empty(&qd->qd_reclaim)) { | 180 | !list_empty(&qd->qd_reclaim)) { |
180 | /* Remove it from reclaim list */ | 181 | /* Remove it from reclaim list */ |
@@ -208,7 +209,7 @@ static int qd_get(struct gfs2_sbd *sdp, int user, u32 id, | |||
208 | return 0; | 209 | return 0; |
209 | } | 210 | } |
210 | 211 | ||
211 | error = qd_alloc(sdp, user, id, &new_qd); | 212 | error = qd_alloc(sdp, qid, &new_qd); |
212 | if (error) | 213 | if (error) |
213 | return error; | 214 | return error; |
214 | } | 215 | } |
@@ -458,12 +459,12 @@ static void qd_unlock(struct gfs2_quota_data *qd) | |||
458 | qd_put(qd); | 459 | qd_put(qd); |
459 | } | 460 | } |
460 | 461 | ||
461 | static int qdsb_get(struct gfs2_sbd *sdp, int user, u32 id, | 462 | static int qdsb_get(struct gfs2_sbd *sdp, struct kqid qid, |
462 | struct gfs2_quota_data **qdp) | 463 | struct gfs2_quota_data **qdp) |
463 | { | 464 | { |
464 | int error; | 465 | int error; |
465 | 466 | ||
466 | error = qd_get(sdp, user, id, qdp); | 467 | error = qd_get(sdp, qid, qdp); |
467 | if (error) | 468 | if (error) |
468 | return error; | 469 | return error; |
469 | 470 | ||
@@ -491,7 +492,7 @@ static void qdsb_put(struct gfs2_quota_data *qd) | |||
491 | qd_put(qd); | 492 | qd_put(qd); |
492 | } | 493 | } |
493 | 494 | ||
494 | int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid) | 495 | int gfs2_quota_hold(struct gfs2_inode *ip, kuid_t uid, kgid_t gid) |
495 | { | 496 | { |
496 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 497 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
497 | struct gfs2_quota_data **qd; | 498 | struct gfs2_quota_data **qd; |
@@ -512,28 +513,30 @@ int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid) | |||
512 | if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF) | 513 | if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF) |
513 | return 0; | 514 | return 0; |
514 | 515 | ||
515 | error = qdsb_get(sdp, QUOTA_USER, ip->i_inode.i_uid, qd); | 516 | error = qdsb_get(sdp, make_kqid_uid(ip->i_inode.i_uid), qd); |
516 | if (error) | 517 | if (error) |
517 | goto out; | 518 | goto out; |
518 | ip->i_res->rs_qa_qd_num++; | 519 | ip->i_res->rs_qa_qd_num++; |
519 | qd++; | 520 | qd++; |
520 | 521 | ||
521 | error = qdsb_get(sdp, QUOTA_GROUP, ip->i_inode.i_gid, qd); | 522 | error = qdsb_get(sdp, make_kqid_gid(ip->i_inode.i_gid), qd); |
522 | if (error) | 523 | if (error) |
523 | goto out; | 524 | goto out; |
524 | ip->i_res->rs_qa_qd_num++; | 525 | ip->i_res->rs_qa_qd_num++; |
525 | qd++; | 526 | qd++; |
526 | 527 | ||
527 | if (uid != NO_QUOTA_CHANGE && uid != ip->i_inode.i_uid) { | 528 | if (!uid_eq(uid, NO_UID_QUOTA_CHANGE) && |
528 | error = qdsb_get(sdp, QUOTA_USER, uid, qd); | 529 | !uid_eq(uid, ip->i_inode.i_uid)) { |
530 | error = qdsb_get(sdp, make_kqid_uid(uid), qd); | ||
529 | if (error) | 531 | if (error) |
530 | goto out; | 532 | goto out; |
531 | ip->i_res->rs_qa_qd_num++; | 533 | ip->i_res->rs_qa_qd_num++; |
532 | qd++; | 534 | qd++; |
533 | } | 535 | } |
534 | 536 | ||
535 | if (gid != NO_QUOTA_CHANGE && gid != ip->i_inode.i_gid) { | 537 | if (!gid_eq(gid, NO_GID_QUOTA_CHANGE) && |
536 | error = qdsb_get(sdp, QUOTA_GROUP, gid, qd); | 538 | !gid_eq(gid, ip->i_inode.i_gid)) { |
539 | error = qdsb_get(sdp, make_kqid_gid(gid), qd); | ||
537 | if (error) | 540 | if (error) |
538 | goto out; | 541 | goto out; |
539 | ip->i_res->rs_qa_qd_num++; | 542 | ip->i_res->rs_qa_qd_num++; |
@@ -567,18 +570,10 @@ static int sort_qd(const void *a, const void *b) | |||
567 | const struct gfs2_quota_data *qd_a = *(const struct gfs2_quota_data **)a; | 570 | const struct gfs2_quota_data *qd_a = *(const struct gfs2_quota_data **)a; |
568 | const struct gfs2_quota_data *qd_b = *(const struct gfs2_quota_data **)b; | 571 | const struct gfs2_quota_data *qd_b = *(const struct gfs2_quota_data **)b; |
569 | 572 | ||
570 | if (!test_bit(QDF_USER, &qd_a->qd_flags) != | 573 | if (qid_lt(qd_a->qd_id, qd_b->qd_id)) |
571 | !test_bit(QDF_USER, &qd_b->qd_flags)) { | ||
572 | if (test_bit(QDF_USER, &qd_a->qd_flags)) | ||
573 | return -1; | ||
574 | else | ||
575 | return 1; | ||
576 | } | ||
577 | if (qd_a->qd_id < qd_b->qd_id) | ||
578 | return -1; | 574 | return -1; |
579 | if (qd_a->qd_id > qd_b->qd_id) | 575 | if (qid_lt(qd_b->qd_id, qd_a->qd_id)) |
580 | return 1; | 576 | return 1; |
581 | |||
582 | return 0; | 577 | return 0; |
583 | } | 578 | } |
584 | 579 | ||
@@ -595,9 +590,9 @@ static void do_qc(struct gfs2_quota_data *qd, s64 change) | |||
595 | if (!test_bit(QDF_CHANGE, &qd->qd_flags)) { | 590 | if (!test_bit(QDF_CHANGE, &qd->qd_flags)) { |
596 | qc->qc_change = 0; | 591 | qc->qc_change = 0; |
597 | qc->qc_flags = 0; | 592 | qc->qc_flags = 0; |
598 | if (test_bit(QDF_USER, &qd->qd_flags)) | 593 | if (qd->qd_id.type == USRQUOTA) |
599 | qc->qc_flags = cpu_to_be32(GFS2_QCF_USER); | 594 | qc->qc_flags = cpu_to_be32(GFS2_QCF_USER); |
600 | qc->qc_id = cpu_to_be32(qd->qd_id); | 595 | qc->qc_id = cpu_to_be32(from_kqid(&init_user_ns, qd->qd_id)); |
601 | } | 596 | } |
602 | 597 | ||
603 | x = be64_to_cpu(qc->qc_change) + change; | 598 | x = be64_to_cpu(qc->qc_change) + change; |
@@ -925,7 +920,7 @@ fail: | |||
925 | return error; | 920 | return error; |
926 | } | 921 | } |
927 | 922 | ||
928 | int gfs2_quota_lock(struct gfs2_inode *ip, u32 uid, u32 gid) | 923 | int gfs2_quota_lock(struct gfs2_inode *ip, kuid_t uid, kgid_t gid) |
929 | { | 924 | { |
930 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 925 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
931 | struct gfs2_quota_data *qd; | 926 | struct gfs2_quota_data *qd; |
@@ -1040,13 +1035,13 @@ static int print_message(struct gfs2_quota_data *qd, char *type) | |||
1040 | 1035 | ||
1041 | printk(KERN_INFO "GFS2: fsid=%s: quota %s for %s %u\n", | 1036 | printk(KERN_INFO "GFS2: fsid=%s: quota %s for %s %u\n", |
1042 | sdp->sd_fsname, type, | 1037 | sdp->sd_fsname, type, |
1043 | (test_bit(QDF_USER, &qd->qd_flags)) ? "user" : "group", | 1038 | (qd->qd_id.type == USRQUOTA) ? "user" : "group", |
1044 | qd->qd_id); | 1039 | from_kqid(&init_user_ns, qd->qd_id)); |
1045 | 1040 | ||
1046 | return 0; | 1041 | return 0; |
1047 | } | 1042 | } |
1048 | 1043 | ||
1049 | int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid) | 1044 | int gfs2_quota_check(struct gfs2_inode *ip, kuid_t uid, kgid_t gid) |
1050 | { | 1045 | { |
1051 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 1046 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
1052 | struct gfs2_quota_data *qd; | 1047 | struct gfs2_quota_data *qd; |
@@ -1063,8 +1058,8 @@ int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid) | |||
1063 | for (x = 0; x < ip->i_res->rs_qa_qd_num; x++) { | 1058 | for (x = 0; x < ip->i_res->rs_qa_qd_num; x++) { |
1064 | qd = ip->i_res->rs_qa_qd[x]; | 1059 | qd = ip->i_res->rs_qa_qd[x]; |
1065 | 1060 | ||
1066 | if (!((qd->qd_id == uid && test_bit(QDF_USER, &qd->qd_flags)) || | 1061 | if (!(qid_eq(qd->qd_id, make_kqid_uid(uid)) || |
1067 | (qd->qd_id == gid && !test_bit(QDF_USER, &qd->qd_flags)))) | 1062 | qid_eq(qd->qd_id, make_kqid_gid(gid)))) |
1068 | continue; | 1063 | continue; |
1069 | 1064 | ||
1070 | value = (s64)be64_to_cpu(qd->qd_qb.qb_value); | 1065 | value = (s64)be64_to_cpu(qd->qd_qb.qb_value); |
@@ -1074,10 +1069,7 @@ int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid) | |||
1074 | 1069 | ||
1075 | if (be64_to_cpu(qd->qd_qb.qb_limit) && (s64)be64_to_cpu(qd->qd_qb.qb_limit) < value) { | 1070 | if (be64_to_cpu(qd->qd_qb.qb_limit) && (s64)be64_to_cpu(qd->qd_qb.qb_limit) < value) { |
1076 | print_message(qd, "exceeded"); | 1071 | print_message(qd, "exceeded"); |
1077 | quota_send_warning(make_kqid(&init_user_ns, | 1072 | quota_send_warning(qd->qd_id, |
1078 | test_bit(QDF_USER, &qd->qd_flags) ? | ||
1079 | USRQUOTA : GRPQUOTA, | ||
1080 | qd->qd_id), | ||
1081 | sdp->sd_vfs->s_dev, QUOTA_NL_BHARDWARN); | 1073 | sdp->sd_vfs->s_dev, QUOTA_NL_BHARDWARN); |
1082 | 1074 | ||
1083 | error = -EDQUOT; | 1075 | error = -EDQUOT; |
@@ -1087,10 +1079,7 @@ int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid) | |||
1087 | time_after_eq(jiffies, qd->qd_last_warn + | 1079 | time_after_eq(jiffies, qd->qd_last_warn + |
1088 | gfs2_tune_get(sdp, | 1080 | gfs2_tune_get(sdp, |
1089 | gt_quota_warn_period) * HZ)) { | 1081 | gt_quota_warn_period) * HZ)) { |
1090 | quota_send_warning(make_kqid(&init_user_ns, | 1082 | quota_send_warning(qd->qd_id, |
1091 | test_bit(QDF_USER, &qd->qd_flags) ? | ||
1092 | USRQUOTA : GRPQUOTA, | ||
1093 | qd->qd_id), | ||
1094 | sdp->sd_vfs->s_dev, QUOTA_NL_BSOFTWARN); | 1083 | sdp->sd_vfs->s_dev, QUOTA_NL_BSOFTWARN); |
1095 | error = print_message(qd, "warning"); | 1084 | error = print_message(qd, "warning"); |
1096 | qd->qd_last_warn = jiffies; | 1085 | qd->qd_last_warn = jiffies; |
@@ -1101,7 +1090,7 @@ int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid) | |||
1101 | } | 1090 | } |
1102 | 1091 | ||
1103 | void gfs2_quota_change(struct gfs2_inode *ip, s64 change, | 1092 | void gfs2_quota_change(struct gfs2_inode *ip, s64 change, |
1104 | u32 uid, u32 gid) | 1093 | kuid_t uid, kgid_t gid) |
1105 | { | 1094 | { |
1106 | struct gfs2_quota_data *qd; | 1095 | struct gfs2_quota_data *qd; |
1107 | unsigned int x; | 1096 | unsigned int x; |
@@ -1114,8 +1103,8 @@ void gfs2_quota_change(struct gfs2_inode *ip, s64 change, | |||
1114 | for (x = 0; x < ip->i_res->rs_qa_qd_num; x++) { | 1103 | for (x = 0; x < ip->i_res->rs_qa_qd_num; x++) { |
1115 | qd = ip->i_res->rs_qa_qd[x]; | 1104 | qd = ip->i_res->rs_qa_qd[x]; |
1116 | 1105 | ||
1117 | if ((qd->qd_id == uid && test_bit(QDF_USER, &qd->qd_flags)) || | 1106 | if (qid_eq(qd->qd_id, make_kqid_uid(uid)) || |
1118 | (qd->qd_id == gid && !test_bit(QDF_USER, &qd->qd_flags))) { | 1107 | qid_eq(qd->qd_id, make_kqid_gid(gid))) { |
1119 | do_qc(qd, change); | 1108 | do_qc(qd, change); |
1120 | } | 1109 | } |
1121 | } | 1110 | } |
@@ -1170,13 +1159,13 @@ static int gfs2_quota_sync_timeo(struct super_block *sb, int type) | |||
1170 | return gfs2_quota_sync(sb, type); | 1159 | return gfs2_quota_sync(sb, type); |
1171 | } | 1160 | } |
1172 | 1161 | ||
1173 | int gfs2_quota_refresh(struct gfs2_sbd *sdp, int user, u32 id) | 1162 | int gfs2_quota_refresh(struct gfs2_sbd *sdp, struct kqid qid) |
1174 | { | 1163 | { |
1175 | struct gfs2_quota_data *qd; | 1164 | struct gfs2_quota_data *qd; |
1176 | struct gfs2_holder q_gh; | 1165 | struct gfs2_holder q_gh; |
1177 | int error; | 1166 | int error; |
1178 | 1167 | ||
1179 | error = qd_get(sdp, user, id, &qd); | 1168 | error = qd_get(sdp, qid, &qd); |
1180 | if (error) | 1169 | if (error) |
1181 | return error; | 1170 | return error; |
1182 | 1171 | ||
@@ -1194,7 +1183,9 @@ static void gfs2_quota_change_in(struct gfs2_quota_change_host *qc, const void * | |||
1194 | 1183 | ||
1195 | qc->qc_change = be64_to_cpu(str->qc_change); | 1184 | qc->qc_change = be64_to_cpu(str->qc_change); |
1196 | qc->qc_flags = be32_to_cpu(str->qc_flags); | 1185 | qc->qc_flags = be32_to_cpu(str->qc_flags); |
1197 | qc->qc_id = be32_to_cpu(str->qc_id); | 1186 | qc->qc_id = make_kqid(&init_user_ns, |
1187 | (qc->qc_flags & GFS2_QCF_USER)?USRQUOTA:GRPQUOTA, | ||
1188 | be32_to_cpu(str->qc_id)); | ||
1198 | } | 1189 | } |
1199 | 1190 | ||
1200 | int gfs2_quota_init(struct gfs2_sbd *sdp) | 1191 | int gfs2_quota_init(struct gfs2_sbd *sdp) |
@@ -1257,8 +1248,7 @@ int gfs2_quota_init(struct gfs2_sbd *sdp) | |||
1257 | if (!qc.qc_change) | 1248 | if (!qc.qc_change) |
1258 | continue; | 1249 | continue; |
1259 | 1250 | ||
1260 | error = qd_alloc(sdp, (qc.qc_flags & GFS2_QCF_USER), | 1251 | error = qd_alloc(sdp, qc.qc_id, &qd); |
1261 | qc.qc_id, &qd); | ||
1262 | if (error) { | 1252 | if (error) { |
1263 | brelse(bh); | 1253 | brelse(bh); |
1264 | goto fail; | 1254 | goto fail; |
@@ -1485,21 +1475,17 @@ static int gfs2_get_dqblk(struct super_block *sb, struct kqid qid, | |||
1485 | struct gfs2_quota_data *qd; | 1475 | struct gfs2_quota_data *qd; |
1486 | struct gfs2_holder q_gh; | 1476 | struct gfs2_holder q_gh; |
1487 | int error; | 1477 | int error; |
1488 | int type; | ||
1489 | 1478 | ||
1490 | memset(fdq, 0, sizeof(struct fs_disk_quota)); | 1479 | memset(fdq, 0, sizeof(struct fs_disk_quota)); |
1491 | 1480 | ||
1492 | if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF) | 1481 | if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF) |
1493 | return -ESRCH; /* Crazy XFS error code */ | 1482 | return -ESRCH; /* Crazy XFS error code */ |
1494 | 1483 | ||
1495 | if (qid.type == USRQUOTA) | 1484 | if ((qid.type != USRQUOTA) && |
1496 | type = QUOTA_USER; | 1485 | (qid.type != GRPQUOTA)) |
1497 | else if (qid.type == GRPQUOTA) | ||
1498 | type = QUOTA_GROUP; | ||
1499 | else | ||
1500 | return -EINVAL; | 1486 | return -EINVAL; |
1501 | 1487 | ||
1502 | error = qd_get(sdp, type, from_kqid(&init_user_ns, qid), &qd); | 1488 | error = qd_get(sdp, qid, &qd); |
1503 | if (error) | 1489 | if (error) |
1504 | return error; | 1490 | return error; |
1505 | error = do_glock(qd, FORCE, &q_gh); | 1491 | error = do_glock(qd, FORCE, &q_gh); |
@@ -1508,8 +1494,8 @@ static int gfs2_get_dqblk(struct super_block *sb, struct kqid qid, | |||
1508 | 1494 | ||
1509 | qlvb = (struct gfs2_quota_lvb *)qd->qd_gl->gl_lksb.sb_lvbptr; | 1495 | qlvb = (struct gfs2_quota_lvb *)qd->qd_gl->gl_lksb.sb_lvbptr; |
1510 | fdq->d_version = FS_DQUOT_VERSION; | 1496 | fdq->d_version = FS_DQUOT_VERSION; |
1511 | fdq->d_flags = (type == QUOTA_USER) ? FS_USER_QUOTA : FS_GROUP_QUOTA; | 1497 | fdq->d_flags = (qid.type == USRQUOTA) ? FS_USER_QUOTA : FS_GROUP_QUOTA; |
1512 | fdq->d_id = from_kqid(&init_user_ns, qid); | 1498 | fdq->d_id = from_kqid_munged(current_user_ns(), qid); |
1513 | fdq->d_blk_hardlimit = be64_to_cpu(qlvb->qb_limit) << sdp->sd_fsb2bb_shift; | 1499 | fdq->d_blk_hardlimit = be64_to_cpu(qlvb->qb_limit) << sdp->sd_fsb2bb_shift; |
1514 | fdq->d_blk_softlimit = be64_to_cpu(qlvb->qb_warn) << sdp->sd_fsb2bb_shift; | 1500 | fdq->d_blk_softlimit = be64_to_cpu(qlvb->qb_warn) << sdp->sd_fsb2bb_shift; |
1515 | fdq->d_bcount = be64_to_cpu(qlvb->qb_value) << sdp->sd_fsb2bb_shift; | 1501 | fdq->d_bcount = be64_to_cpu(qlvb->qb_value) << sdp->sd_fsb2bb_shift; |
@@ -1535,32 +1521,18 @@ static int gfs2_set_dqblk(struct super_block *sb, struct kqid qid, | |||
1535 | int alloc_required; | 1521 | int alloc_required; |
1536 | loff_t offset; | 1522 | loff_t offset; |
1537 | int error; | 1523 | int error; |
1538 | int type; | ||
1539 | 1524 | ||
1540 | if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF) | 1525 | if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF) |
1541 | return -ESRCH; /* Crazy XFS error code */ | 1526 | return -ESRCH; /* Crazy XFS error code */ |
1542 | 1527 | ||
1543 | switch(qid.type) { | 1528 | if ((qid.type != USRQUOTA) && |
1544 | case USRQUOTA: | 1529 | (qid.type != GRPQUOTA)) |
1545 | type = QUOTA_USER; | ||
1546 | if (fdq->d_flags != FS_USER_QUOTA) | ||
1547 | return -EINVAL; | ||
1548 | break; | ||
1549 | case GRPQUOTA: | ||
1550 | type = QUOTA_GROUP; | ||
1551 | if (fdq->d_flags != FS_GROUP_QUOTA) | ||
1552 | return -EINVAL; | ||
1553 | break; | ||
1554 | default: | ||
1555 | return -EINVAL; | 1530 | return -EINVAL; |
1556 | } | ||
1557 | 1531 | ||
1558 | if (fdq->d_fieldmask & ~GFS2_FIELDMASK) | 1532 | if (fdq->d_fieldmask & ~GFS2_FIELDMASK) |
1559 | return -EINVAL; | 1533 | return -EINVAL; |
1560 | if (fdq->d_id != from_kqid(&init_user_ns, qid)) | ||
1561 | return -EINVAL; | ||
1562 | 1534 | ||
1563 | error = qd_get(sdp, type, from_kqid(&init_user_ns, qid), &qd); | 1535 | error = qd_get(sdp, qid, &qd); |
1564 | if (error) | 1536 | if (error) |
1565 | return error; | 1537 | return error; |
1566 | 1538 | ||
diff --git a/fs/gfs2/quota.h b/fs/gfs2/quota.h index f25d98b87904..4f5e6e44ed83 100644 --- a/fs/gfs2/quota.h +++ b/fs/gfs2/quota.h | |||
@@ -14,20 +14,21 @@ struct gfs2_inode; | |||
14 | struct gfs2_sbd; | 14 | struct gfs2_sbd; |
15 | struct shrink_control; | 15 | struct shrink_control; |
16 | 16 | ||
17 | #define NO_QUOTA_CHANGE ((u32)-1) | 17 | #define NO_UID_QUOTA_CHANGE INVALID_UID |
18 | #define NO_GID_QUOTA_CHANGE INVALID_GID | ||
18 | 19 | ||
19 | extern int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid); | 20 | extern int gfs2_quota_hold(struct gfs2_inode *ip, kuid_t uid, kgid_t gid); |
20 | extern void gfs2_quota_unhold(struct gfs2_inode *ip); | 21 | extern void gfs2_quota_unhold(struct gfs2_inode *ip); |
21 | 22 | ||
22 | extern int gfs2_quota_lock(struct gfs2_inode *ip, u32 uid, u32 gid); | 23 | extern int gfs2_quota_lock(struct gfs2_inode *ip, kuid_t uid, kgid_t gid); |
23 | extern void gfs2_quota_unlock(struct gfs2_inode *ip); | 24 | extern void gfs2_quota_unlock(struct gfs2_inode *ip); |
24 | 25 | ||
25 | extern int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid); | 26 | extern int gfs2_quota_check(struct gfs2_inode *ip, kuid_t uid, kgid_t gid); |
26 | extern void gfs2_quota_change(struct gfs2_inode *ip, s64 change, | 27 | extern void gfs2_quota_change(struct gfs2_inode *ip, s64 change, |
27 | u32 uid, u32 gid); | 28 | kuid_t uid, kgid_t gid); |
28 | 29 | ||
29 | extern int gfs2_quota_sync(struct super_block *sb, int type); | 30 | extern int gfs2_quota_sync(struct super_block *sb, int type); |
30 | extern int gfs2_quota_refresh(struct gfs2_sbd *sdp, int user, u32 id); | 31 | extern int gfs2_quota_refresh(struct gfs2_sbd *sdp, struct kqid qid); |
31 | 32 | ||
32 | extern int gfs2_quota_init(struct gfs2_sbd *sdp); | 33 | extern int gfs2_quota_init(struct gfs2_sbd *sdp); |
33 | extern void gfs2_quota_cleanup(struct gfs2_sbd *sdp); | 34 | extern void gfs2_quota_cleanup(struct gfs2_sbd *sdp); |
@@ -41,7 +42,7 @@ static inline int gfs2_quota_lock_check(struct gfs2_inode *ip) | |||
41 | int ret; | 42 | int ret; |
42 | if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF) | 43 | if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF) |
43 | return 0; | 44 | return 0; |
44 | ret = gfs2_quota_lock(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); | 45 | ret = gfs2_quota_lock(ip, NO_UID_QUOTA_CHANGE, NO_GID_QUOTA_CHANGE); |
45 | if (ret) | 46 | if (ret) |
46 | return ret; | 47 | return ret; |
47 | if (sdp->sd_args.ar_quota != GFS2_QUOTA_ON) | 48 | if (sdp->sd_args.ar_quota != GFS2_QUOTA_ON) |
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index a3b40eeaa6e2..cab77b8ba84f 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c | |||
@@ -673,8 +673,8 @@ void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf) | |||
673 | str->di_num.no_addr = cpu_to_be64(ip->i_no_addr); | 673 | str->di_num.no_addr = cpu_to_be64(ip->i_no_addr); |
674 | str->di_num.no_formal_ino = cpu_to_be64(ip->i_no_formal_ino); | 674 | str->di_num.no_formal_ino = cpu_to_be64(ip->i_no_formal_ino); |
675 | str->di_mode = cpu_to_be32(ip->i_inode.i_mode); | 675 | str->di_mode = cpu_to_be32(ip->i_inode.i_mode); |
676 | str->di_uid = cpu_to_be32(ip->i_inode.i_uid); | 676 | str->di_uid = cpu_to_be32(i_uid_read(&ip->i_inode)); |
677 | str->di_gid = cpu_to_be32(ip->i_inode.i_gid); | 677 | str->di_gid = cpu_to_be32(i_gid_read(&ip->i_inode)); |
678 | str->di_nlink = cpu_to_be32(ip->i_inode.i_nlink); | 678 | str->di_nlink = cpu_to_be32(ip->i_inode.i_nlink); |
679 | str->di_size = cpu_to_be64(i_size_read(&ip->i_inode)); | 679 | str->di_size = cpu_to_be64(i_size_read(&ip->i_inode)); |
680 | str->di_blocks = cpu_to_be64(gfs2_get_inode_blocks(&ip->i_inode)); | 680 | str->di_blocks = cpu_to_be64(gfs2_get_inode_blocks(&ip->i_inode)); |
@@ -1376,7 +1376,7 @@ static int gfs2_dinode_dealloc(struct gfs2_inode *ip) | |||
1376 | if (error) | 1376 | if (error) |
1377 | return error; | 1377 | return error; |
1378 | 1378 | ||
1379 | error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); | 1379 | error = gfs2_quota_hold(ip, NO_UID_QUOTA_CHANGE, NO_GID_QUOTA_CHANGE); |
1380 | if (error) | 1380 | if (error) |
1381 | return error; | 1381 | return error; |
1382 | 1382 | ||
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c index 4fb9ad80d260..597a612834dc 100644 --- a/fs/gfs2/sys.c +++ b/fs/gfs2/sys.c | |||
@@ -173,6 +173,7 @@ static ssize_t quota_sync_store(struct gfs2_sbd *sdp, const char *buf, | |||
173 | static ssize_t quota_refresh_user_store(struct gfs2_sbd *sdp, const char *buf, | 173 | static ssize_t quota_refresh_user_store(struct gfs2_sbd *sdp, const char *buf, |
174 | size_t len) | 174 | size_t len) |
175 | { | 175 | { |
176 | struct kqid qid; | ||
176 | int error; | 177 | int error; |
177 | u32 id; | 178 | u32 id; |
178 | 179 | ||
@@ -181,13 +182,18 @@ static ssize_t quota_refresh_user_store(struct gfs2_sbd *sdp, const char *buf, | |||
181 | 182 | ||
182 | id = simple_strtoul(buf, NULL, 0); | 183 | id = simple_strtoul(buf, NULL, 0); |
183 | 184 | ||
184 | error = gfs2_quota_refresh(sdp, 1, id); | 185 | qid = make_kqid(current_user_ns(), USRQUOTA, id); |
186 | if (!qid_valid(qid)) | ||
187 | return -EINVAL; | ||
188 | |||
189 | error = gfs2_quota_refresh(sdp, qid); | ||
185 | return error ? error : len; | 190 | return error ? error : len; |
186 | } | 191 | } |
187 | 192 | ||
188 | static ssize_t quota_refresh_group_store(struct gfs2_sbd *sdp, const char *buf, | 193 | static ssize_t quota_refresh_group_store(struct gfs2_sbd *sdp, const char *buf, |
189 | size_t len) | 194 | size_t len) |
190 | { | 195 | { |
196 | struct kqid qid; | ||
191 | int error; | 197 | int error; |
192 | u32 id; | 198 | u32 id; |
193 | 199 | ||
@@ -196,7 +202,11 @@ static ssize_t quota_refresh_group_store(struct gfs2_sbd *sdp, const char *buf, | |||
196 | 202 | ||
197 | id = simple_strtoul(buf, NULL, 0); | 203 | id = simple_strtoul(buf, NULL, 0); |
198 | 204 | ||
199 | error = gfs2_quota_refresh(sdp, 0, id); | 205 | qid = make_kqid(current_user_ns(), GRPQUOTA, id); |
206 | if (!qid_valid(qid)) | ||
207 | return -EINVAL; | ||
208 | |||
209 | error = gfs2_quota_refresh(sdp, qid); | ||
200 | return error ? error : len; | 210 | return error ? error : len; |
201 | } | 211 | } |
202 | 212 | ||
diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c index cbb46c2baa69..ecd37f30ab91 100644 --- a/fs/gfs2/xattr.c +++ b/fs/gfs2/xattr.c | |||
@@ -331,7 +331,7 @@ static int ea_remove_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh, | |||
331 | if (error) | 331 | if (error) |
332 | return error; | 332 | return error; |
333 | 333 | ||
334 | error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); | 334 | error = gfs2_quota_hold(ip, NO_UID_QUOTA_CHANGE, NO_GID_QUOTA_CHANGE); |
335 | if (error) | 335 | if (error) |
336 | goto out_alloc; | 336 | goto out_alloc; |
337 | 337 | ||
@@ -1461,7 +1461,7 @@ int gfs2_ea_dealloc(struct gfs2_inode *ip) | |||
1461 | if (error) | 1461 | if (error) |
1462 | return error; | 1462 | return error; |
1463 | 1463 | ||
1464 | error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); | 1464 | error = gfs2_quota_hold(ip, NO_UID_QUOTA_CHANGE, NO_GID_QUOTA_CHANGE); |
1465 | if (error) | 1465 | if (error) |
1466 | return error; | 1466 | return error; |
1467 | 1467 | ||
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c index 1acdad7fcec7..e2be336d1c22 100644 --- a/fs/ncpfs/inode.c +++ b/fs/ncpfs/inode.c | |||
@@ -331,12 +331,15 @@ static int ncp_show_options(struct seq_file *seq, struct dentry *root) | |||
331 | struct ncp_server *server = NCP_SBP(root->d_sb); | 331 | struct ncp_server *server = NCP_SBP(root->d_sb); |
332 | unsigned int tmp; | 332 | unsigned int tmp; |
333 | 333 | ||
334 | if (server->m.uid != 0) | 334 | if (!uid_eq(server->m.uid, GLOBAL_ROOT_UID)) |
335 | seq_printf(seq, ",uid=%u", server->m.uid); | 335 | seq_printf(seq, ",uid=%u", |
336 | if (server->m.gid != 0) | 336 | from_kuid_munged(&init_user_ns, server->m.uid)); |
337 | seq_printf(seq, ",gid=%u", server->m.gid); | 337 | if (!gid_eq(server->m.gid, GLOBAL_ROOT_GID)) |
338 | if (server->m.mounted_uid != 0) | 338 | seq_printf(seq, ",gid=%u", |
339 | seq_printf(seq, ",owner=%u", server->m.mounted_uid); | 339 | from_kgid_munged(&init_user_ns, server->m.gid)); |
340 | if (!uid_eq(server->m.mounted_uid, GLOBAL_ROOT_UID)) | ||
341 | seq_printf(seq, ",owner=%u", | ||
342 | from_kuid_munged(&init_user_ns, server->m.mounted_uid)); | ||
340 | tmp = server->m.file_mode & S_IALLUGO; | 343 | tmp = server->m.file_mode & S_IALLUGO; |
341 | if (tmp != NCP_DEFAULT_FILE_MODE) | 344 | if (tmp != NCP_DEFAULT_FILE_MODE) |
342 | seq_printf(seq, ",mode=0%o", tmp); | 345 | seq_printf(seq, ",mode=0%o", tmp); |
@@ -381,13 +384,13 @@ static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options) | |||
381 | 384 | ||
382 | data->flags = 0; | 385 | data->flags = 0; |
383 | data->int_flags = 0; | 386 | data->int_flags = 0; |
384 | data->mounted_uid = 0; | 387 | data->mounted_uid = GLOBAL_ROOT_UID; |
385 | data->wdog_pid = NULL; | 388 | data->wdog_pid = NULL; |
386 | data->ncp_fd = ~0; | 389 | data->ncp_fd = ~0; |
387 | data->time_out = NCP_DEFAULT_TIME_OUT; | 390 | data->time_out = NCP_DEFAULT_TIME_OUT; |
388 | data->retry_count = NCP_DEFAULT_RETRY_COUNT; | 391 | data->retry_count = NCP_DEFAULT_RETRY_COUNT; |
389 | data->uid = 0; | 392 | data->uid = GLOBAL_ROOT_UID; |
390 | data->gid = 0; | 393 | data->gid = GLOBAL_ROOT_GID; |
391 | data->file_mode = NCP_DEFAULT_FILE_MODE; | 394 | data->file_mode = NCP_DEFAULT_FILE_MODE; |
392 | data->dir_mode = NCP_DEFAULT_DIR_MODE; | 395 | data->dir_mode = NCP_DEFAULT_DIR_MODE; |
393 | data->info_fd = -1; | 396 | data->info_fd = -1; |
@@ -399,13 +402,19 @@ static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options) | |||
399 | goto err; | 402 | goto err; |
400 | switch (optval) { | 403 | switch (optval) { |
401 | case 'u': | 404 | case 'u': |
402 | data->uid = optint; | 405 | data->uid = make_kuid(current_user_ns(), optint); |
406 | if (!uid_valid(data->uid)) | ||
407 | goto err; | ||
403 | break; | 408 | break; |
404 | case 'g': | 409 | case 'g': |
405 | data->gid = optint; | 410 | data->gid = make_kgid(current_user_ns(), optint); |
411 | if (!gid_valid(data->gid)) | ||
412 | goto err; | ||
406 | break; | 413 | break; |
407 | case 'o': | 414 | case 'o': |
408 | data->mounted_uid = optint; | 415 | data->mounted_uid = make_kuid(current_user_ns(), optint); |
416 | if (!uid_valid(data->mounted_uid)) | ||
417 | goto err; | ||
409 | break; | 418 | break; |
410 | case 'm': | 419 | case 'm': |
411 | data->file_mode = optint; | 420 | data->file_mode = optint; |
@@ -480,13 +489,13 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent) | |||
480 | 489 | ||
481 | data.flags = md->flags; | 490 | data.flags = md->flags; |
482 | data.int_flags = NCP_IMOUNT_LOGGEDIN_POSSIBLE; | 491 | data.int_flags = NCP_IMOUNT_LOGGEDIN_POSSIBLE; |
483 | data.mounted_uid = md->mounted_uid; | 492 | data.mounted_uid = make_kuid(current_user_ns(), md->mounted_uid); |
484 | data.wdog_pid = find_get_pid(md->wdog_pid); | 493 | data.wdog_pid = find_get_pid(md->wdog_pid); |
485 | data.ncp_fd = md->ncp_fd; | 494 | data.ncp_fd = md->ncp_fd; |
486 | data.time_out = md->time_out; | 495 | data.time_out = md->time_out; |
487 | data.retry_count = md->retry_count; | 496 | data.retry_count = md->retry_count; |
488 | data.uid = md->uid; | 497 | data.uid = make_kuid(current_user_ns(), md->uid); |
489 | data.gid = md->gid; | 498 | data.gid = make_kgid(current_user_ns(), md->gid); |
490 | data.file_mode = md->file_mode; | 499 | data.file_mode = md->file_mode; |
491 | data.dir_mode = md->dir_mode; | 500 | data.dir_mode = md->dir_mode; |
492 | data.info_fd = -1; | 501 | data.info_fd = -1; |
@@ -499,13 +508,13 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent) | |||
499 | struct ncp_mount_data_v4* md = (struct ncp_mount_data_v4*)raw_data; | 508 | struct ncp_mount_data_v4* md = (struct ncp_mount_data_v4*)raw_data; |
500 | 509 | ||
501 | data.flags = md->flags; | 510 | data.flags = md->flags; |
502 | data.mounted_uid = md->mounted_uid; | 511 | data.mounted_uid = make_kuid(current_user_ns(), md->mounted_uid); |
503 | data.wdog_pid = find_get_pid(md->wdog_pid); | 512 | data.wdog_pid = find_get_pid(md->wdog_pid); |
504 | data.ncp_fd = md->ncp_fd; | 513 | data.ncp_fd = md->ncp_fd; |
505 | data.time_out = md->time_out; | 514 | data.time_out = md->time_out; |
506 | data.retry_count = md->retry_count; | 515 | data.retry_count = md->retry_count; |
507 | data.uid = md->uid; | 516 | data.uid = make_kuid(current_user_ns(), md->uid); |
508 | data.gid = md->gid; | 517 | data.gid = make_kgid(current_user_ns(), md->gid); |
509 | data.file_mode = md->file_mode; | 518 | data.file_mode = md->file_mode; |
510 | data.dir_mode = md->dir_mode; | 519 | data.dir_mode = md->dir_mode; |
511 | data.info_fd = -1; | 520 | data.info_fd = -1; |
@@ -520,6 +529,10 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent) | |||
520 | goto out; | 529 | goto out; |
521 | break; | 530 | break; |
522 | } | 531 | } |
532 | error = -EINVAL; | ||
533 | if (!uid_valid(data.mounted_uid) || !uid_valid(data.uid) || | ||
534 | !gid_valid(data.gid)) | ||
535 | goto out; | ||
523 | error = -EBADF; | 536 | error = -EBADF; |
524 | ncp_filp = fget(data.ncp_fd); | 537 | ncp_filp = fget(data.ncp_fd); |
525 | if (!ncp_filp) | 538 | if (!ncp_filp) |
@@ -886,12 +899,10 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr) | |||
886 | goto out; | 899 | goto out; |
887 | 900 | ||
888 | result = -EPERM; | 901 | result = -EPERM; |
889 | if (((attr->ia_valid & ATTR_UID) && | 902 | if ((attr->ia_valid & ATTR_UID) && !uid_eq(attr->ia_uid, server->m.uid)) |
890 | (attr->ia_uid != server->m.uid))) | ||
891 | goto out; | 903 | goto out; |
892 | 904 | ||
893 | if (((attr->ia_valid & ATTR_GID) && | 905 | if ((attr->ia_valid & ATTR_GID) && !gid_eq(attr->ia_gid, server->m.gid)) |
894 | (attr->ia_gid != server->m.gid))) | ||
895 | goto out; | 906 | goto out; |
896 | 907 | ||
897 | if (((attr->ia_valid & ATTR_MODE) && | 908 | if (((attr->ia_valid & ATTR_MODE) && |
diff --git a/fs/ncpfs/ioctl.c b/fs/ncpfs/ioctl.c index 6958adfaff08..d44318d27504 100644 --- a/fs/ncpfs/ioctl.c +++ b/fs/ncpfs/ioctl.c | |||
@@ -45,7 +45,7 @@ ncp_get_fs_info(struct ncp_server * server, struct inode *inode, | |||
45 | return -EINVAL; | 45 | return -EINVAL; |
46 | } | 46 | } |
47 | /* TODO: info.addr = server->m.serv_addr; */ | 47 | /* TODO: info.addr = server->m.serv_addr; */ |
48 | SET_UID(info.mounted_uid, server->m.mounted_uid); | 48 | SET_UID(info.mounted_uid, from_kuid_munged(current_user_ns(), server->m.mounted_uid)); |
49 | info.connection = server->connection; | 49 | info.connection = server->connection; |
50 | info.buffer_size = server->buffer_size; | 50 | info.buffer_size = server->buffer_size; |
51 | info.volume_number = NCP_FINFO(inode)->volNumber; | 51 | info.volume_number = NCP_FINFO(inode)->volNumber; |
@@ -69,7 +69,7 @@ ncp_get_fs_info_v2(struct ncp_server * server, struct inode *inode, | |||
69 | DPRINTK("info.version invalid: %d\n", info2.version); | 69 | DPRINTK("info.version invalid: %d\n", info2.version); |
70 | return -EINVAL; | 70 | return -EINVAL; |
71 | } | 71 | } |
72 | info2.mounted_uid = server->m.mounted_uid; | 72 | info2.mounted_uid = from_kuid_munged(current_user_ns(), server->m.mounted_uid); |
73 | info2.connection = server->connection; | 73 | info2.connection = server->connection; |
74 | info2.buffer_size = server->buffer_size; | 74 | info2.buffer_size = server->buffer_size; |
75 | info2.volume_number = NCP_FINFO(inode)->volNumber; | 75 | info2.volume_number = NCP_FINFO(inode)->volNumber; |
@@ -135,7 +135,7 @@ ncp_get_compat_fs_info_v2(struct ncp_server * server, struct inode *inode, | |||
135 | DPRINTK("info.version invalid: %d\n", info2.version); | 135 | DPRINTK("info.version invalid: %d\n", info2.version); |
136 | return -EINVAL; | 136 | return -EINVAL; |
137 | } | 137 | } |
138 | info2.mounted_uid = server->m.mounted_uid; | 138 | info2.mounted_uid = from_kuid_munged(current_user_ns(), server->m.mounted_uid); |
139 | info2.connection = server->connection; | 139 | info2.connection = server->connection; |
140 | info2.buffer_size = server->buffer_size; | 140 | info2.buffer_size = server->buffer_size; |
141 | info2.volume_number = NCP_FINFO(inode)->volNumber; | 141 | info2.volume_number = NCP_FINFO(inode)->volNumber; |
@@ -348,22 +348,25 @@ static long __ncp_ioctl(struct inode *inode, unsigned int cmd, unsigned long arg | |||
348 | { | 348 | { |
349 | u16 uid; | 349 | u16 uid; |
350 | 350 | ||
351 | SET_UID(uid, server->m.mounted_uid); | 351 | SET_UID(uid, from_kuid_munged(current_user_ns(), server->m.mounted_uid)); |
352 | if (put_user(uid, (u16 __user *)argp)) | 352 | if (put_user(uid, (u16 __user *)argp)) |
353 | return -EFAULT; | 353 | return -EFAULT; |
354 | return 0; | 354 | return 0; |
355 | } | 355 | } |
356 | case NCP_IOC_GETMOUNTUID32: | 356 | case NCP_IOC_GETMOUNTUID32: |
357 | if (put_user(server->m.mounted_uid, | 357 | { |
358 | (u32 __user *)argp)) | 358 | uid_t uid = from_kuid_munged(current_user_ns(), server->m.mounted_uid); |
359 | if (put_user(uid, (u32 __user *)argp)) | ||
359 | return -EFAULT; | 360 | return -EFAULT; |
360 | return 0; | 361 | return 0; |
362 | } | ||
361 | case NCP_IOC_GETMOUNTUID64: | 363 | case NCP_IOC_GETMOUNTUID64: |
362 | if (put_user(server->m.mounted_uid, | 364 | { |
363 | (u64 __user *)argp)) | 365 | uid_t uid = from_kuid_munged(current_user_ns(), server->m.mounted_uid); |
366 | if (put_user(uid, (u64 __user *)argp)) | ||
364 | return -EFAULT; | 367 | return -EFAULT; |
365 | return 0; | 368 | return 0; |
366 | 369 | } | |
367 | case NCP_IOC_GETROOT: | 370 | case NCP_IOC_GETROOT: |
368 | { | 371 | { |
369 | struct ncp_setroot_ioctl sr; | 372 | struct ncp_setroot_ioctl sr; |
@@ -810,7 +813,7 @@ long ncp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
810 | { | 813 | { |
811 | struct inode *inode = filp->f_dentry->d_inode; | 814 | struct inode *inode = filp->f_dentry->d_inode; |
812 | struct ncp_server *server = NCP_SERVER(inode); | 815 | struct ncp_server *server = NCP_SERVER(inode); |
813 | uid_t uid = current_uid(); | 816 | kuid_t uid = current_uid(); |
814 | int need_drop_write = 0; | 817 | int need_drop_write = 0; |
815 | long ret; | 818 | long ret; |
816 | 819 | ||
@@ -824,7 +827,7 @@ long ncp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
824 | } | 827 | } |
825 | break; | 828 | break; |
826 | } | 829 | } |
827 | if (server->m.mounted_uid != uid) { | 830 | if (!uid_eq(server->m.mounted_uid, uid)) { |
828 | switch (cmd) { | 831 | switch (cmd) { |
829 | /* | 832 | /* |
830 | * Only mount owner can issue these ioctls. Information | 833 | * Only mount owner can issue these ioctls. Information |
diff --git a/fs/ncpfs/ncp_fs_sb.h b/fs/ncpfs/ncp_fs_sb.h index 54cc0cdb3dcb..c51b2c543539 100644 --- a/fs/ncpfs/ncp_fs_sb.h +++ b/fs/ncpfs/ncp_fs_sb.h | |||
@@ -23,15 +23,15 @@ struct ncp_mount_data_kernel { | |||
23 | unsigned long flags; /* NCP_MOUNT_* flags */ | 23 | unsigned long flags; /* NCP_MOUNT_* flags */ |
24 | unsigned int int_flags; /* internal flags */ | 24 | unsigned int int_flags; /* internal flags */ |
25 | #define NCP_IMOUNT_LOGGEDIN_POSSIBLE 0x0001 | 25 | #define NCP_IMOUNT_LOGGEDIN_POSSIBLE 0x0001 |
26 | uid_t mounted_uid; /* Who may umount() this filesystem? */ | 26 | kuid_t mounted_uid; /* Who may umount() this filesystem? */ |
27 | struct pid *wdog_pid; /* Who cares for our watchdog packets? */ | 27 | struct pid *wdog_pid; /* Who cares for our watchdog packets? */ |
28 | unsigned int ncp_fd; /* The socket to the ncp port */ | 28 | unsigned int ncp_fd; /* The socket to the ncp port */ |
29 | unsigned int time_out; /* How long should I wait after | 29 | unsigned int time_out; /* How long should I wait after |
30 | sending a NCP request? */ | 30 | sending a NCP request? */ |
31 | unsigned int retry_count; /* And how often should I retry? */ | 31 | unsigned int retry_count; /* And how often should I retry? */ |
32 | unsigned char mounted_vol[NCP_VOLNAME_LEN + 1]; | 32 | unsigned char mounted_vol[NCP_VOLNAME_LEN + 1]; |
33 | uid_t uid; | 33 | kuid_t uid; |
34 | gid_t gid; | 34 | kgid_t gid; |
35 | umode_t file_mode; | 35 | umode_t file_mode; |
36 | umode_t dir_mode; | 36 | umode_t dir_mode; |
37 | int info_fd; | 37 | int info_fd; |
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c index bc3968fa81e5..b9623d19d599 100644 --- a/fs/nfs/idmap.c +++ b/fs/nfs/idmap.c | |||
@@ -97,7 +97,7 @@ static void nfs_fattr_free_group_name(struct nfs_fattr *fattr) | |||
97 | static bool nfs_fattr_map_owner_name(struct nfs_server *server, struct nfs_fattr *fattr) | 97 | static bool nfs_fattr_map_owner_name(struct nfs_server *server, struct nfs_fattr *fattr) |
98 | { | 98 | { |
99 | struct nfs4_string *owner = fattr->owner_name; | 99 | struct nfs4_string *owner = fattr->owner_name; |
100 | __u32 uid; | 100 | kuid_t uid; |
101 | 101 | ||
102 | if (!(fattr->valid & NFS_ATTR_FATTR_OWNER_NAME)) | 102 | if (!(fattr->valid & NFS_ATTR_FATTR_OWNER_NAME)) |
103 | return false; | 103 | return false; |
@@ -111,7 +111,7 @@ static bool nfs_fattr_map_owner_name(struct nfs_server *server, struct nfs_fattr | |||
111 | static bool nfs_fattr_map_group_name(struct nfs_server *server, struct nfs_fattr *fattr) | 111 | static bool nfs_fattr_map_group_name(struct nfs_server *server, struct nfs_fattr *fattr) |
112 | { | 112 | { |
113 | struct nfs4_string *group = fattr->group_name; | 113 | struct nfs4_string *group = fattr->group_name; |
114 | __u32 gid; | 114 | kgid_t gid; |
115 | 115 | ||
116 | if (!(fattr->valid & NFS_ATTR_FATTR_GROUP_NAME)) | 116 | if (!(fattr->valid & NFS_ATTR_FATTR_GROUP_NAME)) |
117 | return false; | 117 | return false; |
@@ -193,7 +193,8 @@ static int nfs_idmap_init_keyring(void) | |||
193 | if (!cred) | 193 | if (!cred) |
194 | return -ENOMEM; | 194 | return -ENOMEM; |
195 | 195 | ||
196 | keyring = keyring_alloc(".id_resolver", 0, 0, cred, | 196 | keyring = keyring_alloc(".id_resolver", |
197 | GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, | ||
197 | (KEY_POS_ALL & ~KEY_POS_SETATTR) | | 198 | (KEY_POS_ALL & ~KEY_POS_SETATTR) | |
198 | KEY_USR_VIEW | KEY_USR_READ, | 199 | KEY_USR_VIEW | KEY_USR_READ, |
199 | KEY_ALLOC_NOT_IN_QUOTA, NULL); | 200 | KEY_ALLOC_NOT_IN_QUOTA, NULL); |
@@ -836,43 +837,61 @@ idmap_release_pipe(struct inode *inode) | |||
836 | nfs_idmap_abort_pipe_upcall(idmap, -EPIPE); | 837 | nfs_idmap_abort_pipe_upcall(idmap, -EPIPE); |
837 | } | 838 | } |
838 | 839 | ||
839 | int nfs_map_name_to_uid(const struct nfs_server *server, const char *name, size_t namelen, __u32 *uid) | 840 | int nfs_map_name_to_uid(const struct nfs_server *server, const char *name, size_t namelen, kuid_t *uid) |
840 | { | 841 | { |
841 | struct idmap *idmap = server->nfs_client->cl_idmap; | 842 | struct idmap *idmap = server->nfs_client->cl_idmap; |
843 | __u32 id = -1; | ||
844 | int ret = 0; | ||
842 | 845 | ||
843 | if (nfs_map_string_to_numeric(name, namelen, uid)) | 846 | if (!nfs_map_string_to_numeric(name, namelen, &id)) |
844 | return 0; | 847 | ret = nfs_idmap_lookup_id(name, namelen, "uid", &id, idmap); |
845 | return nfs_idmap_lookup_id(name, namelen, "uid", uid, idmap); | 848 | if (ret == 0) { |
849 | *uid = make_kuid(&init_user_ns, id); | ||
850 | if (!uid_valid(*uid)) | ||
851 | ret = -ERANGE; | ||
852 | } | ||
853 | return ret; | ||
846 | } | 854 | } |
847 | 855 | ||
848 | int nfs_map_group_to_gid(const struct nfs_server *server, const char *name, size_t namelen, __u32 *gid) | 856 | int nfs_map_group_to_gid(const struct nfs_server *server, const char *name, size_t namelen, kgid_t *gid) |
849 | { | 857 | { |
850 | struct idmap *idmap = server->nfs_client->cl_idmap; | 858 | struct idmap *idmap = server->nfs_client->cl_idmap; |
859 | __u32 id = -1; | ||
860 | int ret = 0; | ||
851 | 861 | ||
852 | if (nfs_map_string_to_numeric(name, namelen, gid)) | 862 | if (!nfs_map_string_to_numeric(name, namelen, &id)) |
853 | return 0; | 863 | ret = nfs_idmap_lookup_id(name, namelen, "gid", &id, idmap); |
854 | return nfs_idmap_lookup_id(name, namelen, "gid", gid, idmap); | 864 | if (ret == 0) { |
865 | *gid = make_kgid(&init_user_ns, id); | ||
866 | if (!gid_valid(*gid)) | ||
867 | ret = -ERANGE; | ||
868 | } | ||
869 | return ret; | ||
855 | } | 870 | } |
856 | 871 | ||
857 | int nfs_map_uid_to_name(const struct nfs_server *server, __u32 uid, char *buf, size_t buflen) | 872 | int nfs_map_uid_to_name(const struct nfs_server *server, kuid_t uid, char *buf, size_t buflen) |
858 | { | 873 | { |
859 | struct idmap *idmap = server->nfs_client->cl_idmap; | 874 | struct idmap *idmap = server->nfs_client->cl_idmap; |
860 | int ret = -EINVAL; | 875 | int ret = -EINVAL; |
876 | __u32 id; | ||
861 | 877 | ||
878 | id = from_kuid(&init_user_ns, uid); | ||
862 | if (!(server->caps & NFS_CAP_UIDGID_NOMAP)) | 879 | if (!(server->caps & NFS_CAP_UIDGID_NOMAP)) |
863 | ret = nfs_idmap_lookup_name(uid, "user", buf, buflen, idmap); | 880 | ret = nfs_idmap_lookup_name(id, "user", buf, buflen, idmap); |
864 | if (ret < 0) | 881 | if (ret < 0) |
865 | ret = nfs_map_numeric_to_string(uid, buf, buflen); | 882 | ret = nfs_map_numeric_to_string(id, buf, buflen); |
866 | return ret; | 883 | return ret; |
867 | } | 884 | } |
868 | int nfs_map_gid_to_group(const struct nfs_server *server, __u32 gid, char *buf, size_t buflen) | 885 | int nfs_map_gid_to_group(const struct nfs_server *server, kgid_t gid, char *buf, size_t buflen) |
869 | { | 886 | { |
870 | struct idmap *idmap = server->nfs_client->cl_idmap; | 887 | struct idmap *idmap = server->nfs_client->cl_idmap; |
871 | int ret = -EINVAL; | 888 | int ret = -EINVAL; |
889 | __u32 id; | ||
872 | 890 | ||
891 | id = from_kgid(&init_user_ns, gid); | ||
873 | if (!(server->caps & NFS_CAP_UIDGID_NOMAP)) | 892 | if (!(server->caps & NFS_CAP_UIDGID_NOMAP)) |
874 | ret = nfs_idmap_lookup_name(gid, "group", buf, buflen, idmap); | 893 | ret = nfs_idmap_lookup_name(id, "group", buf, buflen, idmap); |
875 | if (ret < 0) | 894 | if (ret < 0) |
876 | ret = nfs_map_numeric_to_string(gid, buf, buflen); | 895 | ret = nfs_map_numeric_to_string(id, buf, buflen); |
877 | return ret; | 896 | return ret; |
878 | } | 897 | } |
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 6acc73c80d7f..468ba8bf0f56 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -332,8 +332,8 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) | |||
332 | inode->i_version = 0; | 332 | inode->i_version = 0; |
333 | inode->i_size = 0; | 333 | inode->i_size = 0; |
334 | clear_nlink(inode); | 334 | clear_nlink(inode); |
335 | inode->i_uid = -2; | 335 | inode->i_uid = make_kuid(&init_user_ns, -2); |
336 | inode->i_gid = -2; | 336 | inode->i_gid = make_kgid(&init_user_ns, -2); |
337 | inode->i_blocks = 0; | 337 | inode->i_blocks = 0; |
338 | memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf)); | 338 | memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf)); |
339 | nfsi->write_io = 0; | 339 | nfsi->write_io = 0; |
@@ -1006,9 +1006,9 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat | |||
1006 | /* Have any file permissions changed? */ | 1006 | /* Have any file permissions changed? */ |
1007 | if ((fattr->valid & NFS_ATTR_FATTR_MODE) && (inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO)) | 1007 | if ((fattr->valid & NFS_ATTR_FATTR_MODE) && (inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO)) |
1008 | invalid |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL; | 1008 | invalid |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL; |
1009 | if ((fattr->valid & NFS_ATTR_FATTR_OWNER) && inode->i_uid != fattr->uid) | 1009 | if ((fattr->valid & NFS_ATTR_FATTR_OWNER) && !uid_eq(inode->i_uid, fattr->uid)) |
1010 | invalid |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL; | 1010 | invalid |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL; |
1011 | if ((fattr->valid & NFS_ATTR_FATTR_GROUP) && inode->i_gid != fattr->gid) | 1011 | if ((fattr->valid & NFS_ATTR_FATTR_GROUP) && !gid_eq(inode->i_gid, fattr->gid)) |
1012 | invalid |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL; | 1012 | invalid |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL; |
1013 | 1013 | ||
1014 | /* Has the link count changed? */ | 1014 | /* Has the link count changed? */ |
@@ -1437,7 +1437,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1437 | | NFS_INO_REVAL_FORCED); | 1437 | | NFS_INO_REVAL_FORCED); |
1438 | 1438 | ||
1439 | if (fattr->valid & NFS_ATTR_FATTR_OWNER) { | 1439 | if (fattr->valid & NFS_ATTR_FATTR_OWNER) { |
1440 | if (inode->i_uid != fattr->uid) { | 1440 | if (!uid_eq(inode->i_uid, fattr->uid)) { |
1441 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; | 1441 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; |
1442 | inode->i_uid = fattr->uid; | 1442 | inode->i_uid = fattr->uid; |
1443 | } | 1443 | } |
@@ -1448,7 +1448,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1448 | | NFS_INO_REVAL_FORCED); | 1448 | | NFS_INO_REVAL_FORCED); |
1449 | 1449 | ||
1450 | if (fattr->valid & NFS_ATTR_FATTR_GROUP) { | 1450 | if (fattr->valid & NFS_ATTR_FATTR_GROUP) { |
1451 | if (inode->i_gid != fattr->gid) { | 1451 | if (!gid_eq(inode->i_gid, fattr->gid)) { |
1452 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; | 1452 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; |
1453 | inode->i_gid = fattr->gid; | 1453 | inode->i_gid = fattr->gid; |
1454 | } | 1454 | } |
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c index 06b9df49f7f7..62db136339ea 100644 --- a/fs/nfs/nfs2xdr.c +++ b/fs/nfs/nfs2xdr.c | |||
@@ -290,8 +290,13 @@ static int decode_fattr(struct xdr_stream *xdr, struct nfs_fattr *fattr) | |||
290 | 290 | ||
291 | fattr->mode = be32_to_cpup(p++); | 291 | fattr->mode = be32_to_cpup(p++); |
292 | fattr->nlink = be32_to_cpup(p++); | 292 | fattr->nlink = be32_to_cpup(p++); |
293 | fattr->uid = be32_to_cpup(p++); | 293 | fattr->uid = make_kuid(&init_user_ns, be32_to_cpup(p++)); |
294 | fattr->gid = be32_to_cpup(p++); | 294 | if (!uid_valid(fattr->uid)) |
295 | goto out_uid; | ||
296 | fattr->gid = make_kgid(&init_user_ns, be32_to_cpup(p++)); | ||
297 | if (!gid_valid(fattr->gid)) | ||
298 | goto out_gid; | ||
299 | |||
295 | fattr->size = be32_to_cpup(p++); | 300 | fattr->size = be32_to_cpup(p++); |
296 | fattr->du.nfs2.blocksize = be32_to_cpup(p++); | 301 | fattr->du.nfs2.blocksize = be32_to_cpup(p++); |
297 | 302 | ||
@@ -313,6 +318,12 @@ static int decode_fattr(struct xdr_stream *xdr, struct nfs_fattr *fattr) | |||
313 | fattr->change_attr = nfs_timespec_to_change_attr(&fattr->ctime); | 318 | fattr->change_attr = nfs_timespec_to_change_attr(&fattr->ctime); |
314 | 319 | ||
315 | return 0; | 320 | return 0; |
321 | out_uid: | ||
322 | dprintk("NFS: returned invalid uid\n"); | ||
323 | return -EINVAL; | ||
324 | out_gid: | ||
325 | dprintk("NFS: returned invalid gid\n"); | ||
326 | return -EINVAL; | ||
316 | out_overflow: | 327 | out_overflow: |
317 | print_overflow_msg(__func__, xdr); | 328 | print_overflow_msg(__func__, xdr); |
318 | return -EIO; | 329 | return -EIO; |
@@ -351,11 +362,11 @@ static void encode_sattr(struct xdr_stream *xdr, const struct iattr *attr) | |||
351 | else | 362 | else |
352 | *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET); | 363 | *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET); |
353 | if (attr->ia_valid & ATTR_UID) | 364 | if (attr->ia_valid & ATTR_UID) |
354 | *p++ = cpu_to_be32(attr->ia_uid); | 365 | *p++ = cpu_to_be32(from_kuid(&init_user_ns, attr->ia_uid)); |
355 | else | 366 | else |
356 | *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET); | 367 | *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET); |
357 | if (attr->ia_valid & ATTR_GID) | 368 | if (attr->ia_valid & ATTR_GID) |
358 | *p++ = cpu_to_be32(attr->ia_gid); | 369 | *p++ = cpu_to_be32(from_kgid(&init_user_ns, attr->ia_gid)); |
359 | else | 370 | else |
360 | *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET); | 371 | *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET); |
361 | if (attr->ia_valid & ATTR_SIZE) | 372 | if (attr->ia_valid & ATTR_SIZE) |
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index bffc32406fbf..fa6d72131c19 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c | |||
@@ -592,13 +592,13 @@ static void encode_sattr3(struct xdr_stream *xdr, const struct iattr *attr) | |||
592 | 592 | ||
593 | if (attr->ia_valid & ATTR_UID) { | 593 | if (attr->ia_valid & ATTR_UID) { |
594 | *p++ = xdr_one; | 594 | *p++ = xdr_one; |
595 | *p++ = cpu_to_be32(attr->ia_uid); | 595 | *p++ = cpu_to_be32(from_kuid(&init_user_ns, attr->ia_uid)); |
596 | } else | 596 | } else |
597 | *p++ = xdr_zero; | 597 | *p++ = xdr_zero; |
598 | 598 | ||
599 | if (attr->ia_valid & ATTR_GID) { | 599 | if (attr->ia_valid & ATTR_GID) { |
600 | *p++ = xdr_one; | 600 | *p++ = xdr_one; |
601 | *p++ = cpu_to_be32(attr->ia_gid); | 601 | *p++ = cpu_to_be32(from_kgid(&init_user_ns, attr->ia_gid)); |
602 | } else | 602 | } else |
603 | *p++ = xdr_zero; | 603 | *p++ = xdr_zero; |
604 | 604 | ||
@@ -657,8 +657,12 @@ static int decode_fattr3(struct xdr_stream *xdr, struct nfs_fattr *fattr) | |||
657 | 657 | ||
658 | fattr->mode = (be32_to_cpup(p++) & ~S_IFMT) | fmode; | 658 | fattr->mode = (be32_to_cpup(p++) & ~S_IFMT) | fmode; |
659 | fattr->nlink = be32_to_cpup(p++); | 659 | fattr->nlink = be32_to_cpup(p++); |
660 | fattr->uid = be32_to_cpup(p++); | 660 | fattr->uid = make_kuid(&init_user_ns, be32_to_cpup(p++)); |
661 | fattr->gid = be32_to_cpup(p++); | 661 | if (!uid_valid(fattr->uid)) |
662 | goto out_uid; | ||
663 | fattr->gid = make_kgid(&init_user_ns, be32_to_cpup(p++)); | ||
664 | if (!gid_valid(fattr->gid)) | ||
665 | goto out_gid; | ||
662 | 666 | ||
663 | p = xdr_decode_size3(p, &fattr->size); | 667 | p = xdr_decode_size3(p, &fattr->size); |
664 | p = xdr_decode_size3(p, &fattr->du.nfs3.used); | 668 | p = xdr_decode_size3(p, &fattr->du.nfs3.used); |
@@ -675,6 +679,12 @@ static int decode_fattr3(struct xdr_stream *xdr, struct nfs_fattr *fattr) | |||
675 | 679 | ||
676 | fattr->valid |= NFS_ATTR_FATTR_V3; | 680 | fattr->valid |= NFS_ATTR_FATTR_V3; |
677 | return 0; | 681 | return 0; |
682 | out_uid: | ||
683 | dprintk("NFS: returned invalid uid\n"); | ||
684 | return -EINVAL; | ||
685 | out_gid: | ||
686 | dprintk("NFS: returned invalid gid\n"); | ||
687 | return -EINVAL; | ||
678 | out_overflow: | 688 | out_overflow: |
679 | print_overflow_msg(__func__, xdr); | 689 | print_overflow_msg(__func__, xdr); |
680 | return -EIO; | 690 | return -EIO; |
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 26b143920433..e3edda554ac7 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -1002,7 +1002,7 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const | |||
1002 | owner_namelen = nfs_map_uid_to_name(server, iap->ia_uid, owner_name, IDMAP_NAMESZ); | 1002 | owner_namelen = nfs_map_uid_to_name(server, iap->ia_uid, owner_name, IDMAP_NAMESZ); |
1003 | if (owner_namelen < 0) { | 1003 | if (owner_namelen < 0) { |
1004 | dprintk("nfs: couldn't resolve uid %d to string\n", | 1004 | dprintk("nfs: couldn't resolve uid %d to string\n", |
1005 | iap->ia_uid); | 1005 | from_kuid(&init_user_ns, iap->ia_uid)); |
1006 | /* XXX */ | 1006 | /* XXX */ |
1007 | strcpy(owner_name, "nobody"); | 1007 | strcpy(owner_name, "nobody"); |
1008 | owner_namelen = sizeof("nobody") - 1; | 1008 | owner_namelen = sizeof("nobody") - 1; |
@@ -1014,7 +1014,7 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const | |||
1014 | owner_grouplen = nfs_map_gid_to_group(server, iap->ia_gid, owner_group, IDMAP_NAMESZ); | 1014 | owner_grouplen = nfs_map_gid_to_group(server, iap->ia_gid, owner_group, IDMAP_NAMESZ); |
1015 | if (owner_grouplen < 0) { | 1015 | if (owner_grouplen < 0) { |
1016 | dprintk("nfs: couldn't resolve gid %d to string\n", | 1016 | dprintk("nfs: couldn't resolve gid %d to string\n", |
1017 | iap->ia_gid); | 1017 | from_kgid(&init_user_ns, iap->ia_gid)); |
1018 | strcpy(owner_group, "nobody"); | 1018 | strcpy(owner_group, "nobody"); |
1019 | owner_grouplen = sizeof("nobody") - 1; | 1019 | owner_grouplen = sizeof("nobody") - 1; |
1020 | /* goto out; */ | 1020 | /* goto out; */ |
@@ -3778,14 +3778,14 @@ out_overflow: | |||
3778 | } | 3778 | } |
3779 | 3779 | ||
3780 | static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, | 3780 | static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, |
3781 | const struct nfs_server *server, uint32_t *uid, | 3781 | const struct nfs_server *server, kuid_t *uid, |
3782 | struct nfs4_string *owner_name) | 3782 | struct nfs4_string *owner_name) |
3783 | { | 3783 | { |
3784 | uint32_t len; | 3784 | uint32_t len; |
3785 | __be32 *p; | 3785 | __be32 *p; |
3786 | int ret = 0; | 3786 | int ret = 0; |
3787 | 3787 | ||
3788 | *uid = -2; | 3788 | *uid = make_kuid(&init_user_ns, -2); |
3789 | if (unlikely(bitmap[1] & (FATTR4_WORD1_OWNER - 1U))) | 3789 | if (unlikely(bitmap[1] & (FATTR4_WORD1_OWNER - 1U))) |
3790 | return -EIO; | 3790 | return -EIO; |
3791 | if (likely(bitmap[1] & FATTR4_WORD1_OWNER)) { | 3791 | if (likely(bitmap[1] & FATTR4_WORD1_OWNER)) { |
@@ -3813,7 +3813,7 @@ static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, | |||
3813 | __func__, len); | 3813 | __func__, len); |
3814 | bitmap[1] &= ~FATTR4_WORD1_OWNER; | 3814 | bitmap[1] &= ~FATTR4_WORD1_OWNER; |
3815 | } | 3815 | } |
3816 | dprintk("%s: uid=%d\n", __func__, (int)*uid); | 3816 | dprintk("%s: uid=%d\n", __func__, (int)from_kuid(&init_user_ns, *uid)); |
3817 | return ret; | 3817 | return ret; |
3818 | out_overflow: | 3818 | out_overflow: |
3819 | print_overflow_msg(__func__, xdr); | 3819 | print_overflow_msg(__func__, xdr); |
@@ -3821,14 +3821,14 @@ out_overflow: | |||
3821 | } | 3821 | } |
3822 | 3822 | ||
3823 | static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, | 3823 | static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, |
3824 | const struct nfs_server *server, uint32_t *gid, | 3824 | const struct nfs_server *server, kgid_t *gid, |
3825 | struct nfs4_string *group_name) | 3825 | struct nfs4_string *group_name) |
3826 | { | 3826 | { |
3827 | uint32_t len; | 3827 | uint32_t len; |
3828 | __be32 *p; | 3828 | __be32 *p; |
3829 | int ret = 0; | 3829 | int ret = 0; |
3830 | 3830 | ||
3831 | *gid = -2; | 3831 | *gid = make_kgid(&init_user_ns, -2); |
3832 | if (unlikely(bitmap[1] & (FATTR4_WORD1_OWNER_GROUP - 1U))) | 3832 | if (unlikely(bitmap[1] & (FATTR4_WORD1_OWNER_GROUP - 1U))) |
3833 | return -EIO; | 3833 | return -EIO; |
3834 | if (likely(bitmap[1] & FATTR4_WORD1_OWNER_GROUP)) { | 3834 | if (likely(bitmap[1] & FATTR4_WORD1_OWNER_GROUP)) { |
@@ -3856,7 +3856,7 @@ static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, | |||
3856 | __func__, len); | 3856 | __func__, len); |
3857 | bitmap[1] &= ~FATTR4_WORD1_OWNER_GROUP; | 3857 | bitmap[1] &= ~FATTR4_WORD1_OWNER_GROUP; |
3858 | } | 3858 | } |
3859 | dprintk("%s: gid=%d\n", __func__, (int)*gid); | 3859 | dprintk("%s: gid=%d\n", __func__, (int)from_kgid(&init_user_ns, *gid)); |
3860 | return ret; | 3860 | return ret; |
3861 | out_overflow: | 3861 | out_overflow: |
3862 | print_overflow_msg(__func__, xdr); | 3862 | print_overflow_msg(__func__, xdr); |
diff --git a/fs/nfs_common/nfsacl.c b/fs/nfs_common/nfsacl.c index 6940439bd609..ed628f71274c 100644 --- a/fs/nfs_common/nfsacl.c +++ b/fs/nfs_common/nfsacl.c | |||
@@ -38,8 +38,8 @@ struct nfsacl_encode_desc { | |||
38 | unsigned int count; | 38 | unsigned int count; |
39 | struct posix_acl *acl; | 39 | struct posix_acl *acl; |
40 | int typeflag; | 40 | int typeflag; |
41 | uid_t uid; | 41 | kuid_t uid; |
42 | gid_t gid; | 42 | kgid_t gid; |
43 | }; | 43 | }; |
44 | 44 | ||
45 | struct nfsacl_simple_acl { | 45 | struct nfsacl_simple_acl { |
@@ -60,14 +60,16 @@ xdr_nfsace_encode(struct xdr_array2_desc *desc, void *elem) | |||
60 | *p++ = htonl(entry->e_tag | nfsacl_desc->typeflag); | 60 | *p++ = htonl(entry->e_tag | nfsacl_desc->typeflag); |
61 | switch(entry->e_tag) { | 61 | switch(entry->e_tag) { |
62 | case ACL_USER_OBJ: | 62 | case ACL_USER_OBJ: |
63 | *p++ = htonl(nfsacl_desc->uid); | 63 | *p++ = htonl(from_kuid(&init_user_ns, nfsacl_desc->uid)); |
64 | break; | 64 | break; |
65 | case ACL_GROUP_OBJ: | 65 | case ACL_GROUP_OBJ: |
66 | *p++ = htonl(nfsacl_desc->gid); | 66 | *p++ = htonl(from_kgid(&init_user_ns, nfsacl_desc->gid)); |
67 | break; | 67 | break; |
68 | case ACL_USER: | 68 | case ACL_USER: |
69 | *p++ = htonl(from_kuid(&init_user_ns, entry->e_uid)); | ||
70 | break; | ||
69 | case ACL_GROUP: | 71 | case ACL_GROUP: |
70 | *p++ = htonl(entry->e_id); | 72 | *p++ = htonl(from_kgid(&init_user_ns, entry->e_gid)); |
71 | break; | 73 | break; |
72 | default: /* Solaris depends on that! */ | 74 | default: /* Solaris depends on that! */ |
73 | *p++ = 0; | 75 | *p++ = 0; |
@@ -148,6 +150,7 @@ xdr_nfsace_decode(struct xdr_array2_desc *desc, void *elem) | |||
148 | (struct nfsacl_decode_desc *) desc; | 150 | (struct nfsacl_decode_desc *) desc; |
149 | __be32 *p = elem; | 151 | __be32 *p = elem; |
150 | struct posix_acl_entry *entry; | 152 | struct posix_acl_entry *entry; |
153 | unsigned int id; | ||
151 | 154 | ||
152 | if (!nfsacl_desc->acl) { | 155 | if (!nfsacl_desc->acl) { |
153 | if (desc->array_len > NFS_ACL_MAX_ENTRIES) | 156 | if (desc->array_len > NFS_ACL_MAX_ENTRIES) |
@@ -160,14 +163,22 @@ xdr_nfsace_decode(struct xdr_array2_desc *desc, void *elem) | |||
160 | 163 | ||
161 | entry = &nfsacl_desc->acl->a_entries[nfsacl_desc->count++]; | 164 | entry = &nfsacl_desc->acl->a_entries[nfsacl_desc->count++]; |
162 | entry->e_tag = ntohl(*p++) & ~NFS_ACL_DEFAULT; | 165 | entry->e_tag = ntohl(*p++) & ~NFS_ACL_DEFAULT; |
163 | entry->e_id = ntohl(*p++); | 166 | id = ntohl(*p++); |
164 | entry->e_perm = ntohl(*p++); | 167 | entry->e_perm = ntohl(*p++); |
165 | 168 | ||
166 | switch(entry->e_tag) { | 169 | switch(entry->e_tag) { |
167 | case ACL_USER_OBJ: | ||
168 | case ACL_USER: | 170 | case ACL_USER: |
169 | case ACL_GROUP_OBJ: | 171 | entry->e_uid = make_kuid(&init_user_ns, id); |
172 | if (!uid_valid(entry->e_uid)) | ||
173 | return -EINVAL; | ||
174 | break; | ||
170 | case ACL_GROUP: | 175 | case ACL_GROUP: |
176 | entry->e_gid = make_kgid(&init_user_ns, id); | ||
177 | if (!gid_valid(entry->e_gid)) | ||
178 | return -EINVAL; | ||
179 | break; | ||
180 | case ACL_USER_OBJ: | ||
181 | case ACL_GROUP_OBJ: | ||
171 | case ACL_OTHER: | 182 | case ACL_OTHER: |
172 | if (entry->e_perm & ~S_IRWXO) | 183 | if (entry->e_perm & ~S_IRWXO) |
173 | return -EINVAL; | 184 | return -EINVAL; |
@@ -190,9 +201,13 @@ cmp_acl_entry(const void *x, const void *y) | |||
190 | 201 | ||
191 | if (a->e_tag != b->e_tag) | 202 | if (a->e_tag != b->e_tag) |
192 | return a->e_tag - b->e_tag; | 203 | return a->e_tag - b->e_tag; |
193 | else if (a->e_id > b->e_id) | 204 | else if ((a->e_tag == ACL_USER) && uid_gt(a->e_uid, b->e_uid)) |
205 | return 1; | ||
206 | else if ((a->e_tag == ACL_USER) && uid_lt(a->e_uid, b->e_uid)) | ||
207 | return -1; | ||
208 | else if ((a->e_tag == ACL_GROUP) && gid_gt(a->e_gid, b->e_gid)) | ||
194 | return 1; | 209 | return 1; |
195 | else if (a->e_id < b->e_id) | 210 | else if ((a->e_tag == ACL_GROUP) && gid_lt(a->e_gid, b->e_gid)) |
196 | return -1; | 211 | return -1; |
197 | else | 212 | else |
198 | return 0; | 213 | return 0; |
@@ -213,22 +228,18 @@ posix_acl_from_nfsacl(struct posix_acl *acl) | |||
213 | sort(acl->a_entries, acl->a_count, sizeof(struct posix_acl_entry), | 228 | sort(acl->a_entries, acl->a_count, sizeof(struct posix_acl_entry), |
214 | cmp_acl_entry, NULL); | 229 | cmp_acl_entry, NULL); |
215 | 230 | ||
216 | /* Clear undefined identifier fields and find the ACL_GROUP_OBJ | 231 | /* Find the ACL_GROUP_OBJ and ACL_MASK entries. */ |
217 | and ACL_MASK entries. */ | ||
218 | FOREACH_ACL_ENTRY(pa, acl, pe) { | 232 | FOREACH_ACL_ENTRY(pa, acl, pe) { |
219 | switch(pa->e_tag) { | 233 | switch(pa->e_tag) { |
220 | case ACL_USER_OBJ: | 234 | case ACL_USER_OBJ: |
221 | pa->e_id = ACL_UNDEFINED_ID; | ||
222 | break; | 235 | break; |
223 | case ACL_GROUP_OBJ: | 236 | case ACL_GROUP_OBJ: |
224 | pa->e_id = ACL_UNDEFINED_ID; | ||
225 | group_obj = pa; | 237 | group_obj = pa; |
226 | break; | 238 | break; |
227 | case ACL_MASK: | 239 | case ACL_MASK: |
228 | mask = pa; | 240 | mask = pa; |
229 | /* fall through */ | 241 | /* fall through */ |
230 | case ACL_OTHER: | 242 | case ACL_OTHER: |
231 | pa->e_id = ACL_UNDEFINED_ID; | ||
232 | break; | 243 | break; |
233 | } | 244 | } |
234 | } | 245 | } |
diff --git a/fs/nfsd/acl.h b/fs/nfsd/acl.h index 34e5c40af5ef..8b186a4955cc 100644 --- a/fs/nfsd/acl.h +++ b/fs/nfsd/acl.h | |||
@@ -44,8 +44,6 @@ | |||
44 | struct nfs4_acl *nfs4_acl_new(int); | 44 | struct nfs4_acl *nfs4_acl_new(int); |
45 | int nfs4_acl_get_whotype(char *, u32); | 45 | int nfs4_acl_get_whotype(char *, u32); |
46 | int nfs4_acl_write_who(int who, char *p); | 46 | int nfs4_acl_write_who(int who, char *p); |
47 | int nfs4_acl_permission(struct nfs4_acl *acl, uid_t owner, gid_t group, | ||
48 | uid_t who, u32 mask); | ||
49 | 47 | ||
50 | #define NFS4_ACL_TYPE_DEFAULT 0x01 | 48 | #define NFS4_ACL_TYPE_DEFAULT 0x01 |
51 | #define NFS4_ACL_DIR 0x02 | 49 | #define NFS4_ACL_DIR 0x02 |
diff --git a/fs/nfsd/auth.c b/fs/nfsd/auth.c index 34a10d78b839..06cddd572264 100644 --- a/fs/nfsd/auth.c +++ b/fs/nfsd/auth.c | |||
@@ -47,9 +47,9 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp) | |||
47 | if (!gi) | 47 | if (!gi) |
48 | goto oom; | 48 | goto oom; |
49 | } else if (flags & NFSEXP_ROOTSQUASH) { | 49 | } else if (flags & NFSEXP_ROOTSQUASH) { |
50 | if (!new->fsuid) | 50 | if (uid_eq(new->fsuid, GLOBAL_ROOT_UID)) |
51 | new->fsuid = exp->ex_anon_uid; | 51 | new->fsuid = exp->ex_anon_uid; |
52 | if (!new->fsgid) | 52 | if (gid_eq(new->fsgid, GLOBAL_ROOT_GID)) |
53 | new->fsgid = exp->ex_anon_gid; | 53 | new->fsgid = exp->ex_anon_gid; |
54 | 54 | ||
55 | gi = groups_alloc(rqgi->ngroups); | 55 | gi = groups_alloc(rqgi->ngroups); |
@@ -58,7 +58,7 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp) | |||
58 | 58 | ||
59 | for (i = 0; i < rqgi->ngroups; i++) { | 59 | for (i = 0; i < rqgi->ngroups; i++) { |
60 | if (gid_eq(GLOBAL_ROOT_GID, GROUP_AT(rqgi, i))) | 60 | if (gid_eq(GLOBAL_ROOT_GID, GROUP_AT(rqgi, i))) |
61 | GROUP_AT(gi, i) = make_kgid(&init_user_ns, exp->ex_anon_gid); | 61 | GROUP_AT(gi, i) = exp->ex_anon_gid; |
62 | else | 62 | else |
63 | GROUP_AT(gi, i) = GROUP_AT(rqgi, i); | 63 | GROUP_AT(gi, i) = GROUP_AT(rqgi, i); |
64 | } | 64 | } |
@@ -66,9 +66,9 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp) | |||
66 | gi = get_group_info(rqgi); | 66 | gi = get_group_info(rqgi); |
67 | } | 67 | } |
68 | 68 | ||
69 | if (new->fsuid == (uid_t) -1) | 69 | if (uid_eq(new->fsuid, INVALID_UID)) |
70 | new->fsuid = exp->ex_anon_uid; | 70 | new->fsuid = exp->ex_anon_uid; |
71 | if (new->fsgid == (gid_t) -1) | 71 | if (gid_eq(new->fsgid, INVALID_GID)) |
72 | new->fsgid = exp->ex_anon_gid; | 72 | new->fsgid = exp->ex_anon_gid; |
73 | 73 | ||
74 | ret = set_groups(new, gi); | 74 | ret = set_groups(new, gi); |
@@ -76,7 +76,7 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp) | |||
76 | if (ret < 0) | 76 | if (ret < 0) |
77 | goto error; | 77 | goto error; |
78 | 78 | ||
79 | if (new->fsuid) | 79 | if (!uid_eq(new->fsuid, GLOBAL_ROOT_UID)) |
80 | new->cap_effective = cap_drop_nfsd_set(new->cap_effective); | 80 | new->cap_effective = cap_drop_nfsd_set(new->cap_effective); |
81 | else | 81 | else |
82 | new->cap_effective = cap_raise_nfsd_set(new->cap_effective, | 82 | new->cap_effective = cap_raise_nfsd_set(new->cap_effective, |
diff --git a/fs/nfsd/auth.h b/fs/nfsd/auth.h index 78b3c0e93822..53325a12ba62 100644 --- a/fs/nfsd/auth.h +++ b/fs/nfsd/auth.h | |||
@@ -1,6 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * nfsd-specific authentication stuff. | 2 | * nfsd-specific authentication stuff. |
3 | * uid/gid mapping not yet implemented. | ||
4 | * | 3 | * |
5 | * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> | 4 | * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> |
6 | */ | 5 | */ |
@@ -8,11 +7,6 @@ | |||
8 | #ifndef LINUX_NFSD_AUTH_H | 7 | #ifndef LINUX_NFSD_AUTH_H |
9 | #define LINUX_NFSD_AUTH_H | 8 | #define LINUX_NFSD_AUTH_H |
10 | 9 | ||
11 | #define nfsd_luid(rq, uid) ((u32)(uid)) | ||
12 | #define nfsd_lgid(rq, gid) ((u32)(gid)) | ||
13 | #define nfsd_ruid(rq, uid) ((u32)(uid)) | ||
14 | #define nfsd_rgid(rq, gid) ((u32)(gid)) | ||
15 | |||
16 | /* | 10 | /* |
17 | * Set the current process's fsuid/fsgid etc to those of the NFS | 11 | * Set the current process's fsuid/fsgid etc to those of the NFS |
18 | * client user | 12 | * client user |
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index a3946cf13fc8..5681c5906f08 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c | |||
@@ -544,13 +544,17 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen) | |||
544 | err = get_int(&mesg, &an_int); | 544 | err = get_int(&mesg, &an_int); |
545 | if (err) | 545 | if (err) |
546 | goto out3; | 546 | goto out3; |
547 | exp.ex_anon_uid= an_int; | 547 | exp.ex_anon_uid= make_kuid(&init_user_ns, an_int); |
548 | if (!uid_valid(exp.ex_anon_uid)) | ||
549 | goto out3; | ||
548 | 550 | ||
549 | /* anon gid */ | 551 | /* anon gid */ |
550 | err = get_int(&mesg, &an_int); | 552 | err = get_int(&mesg, &an_int); |
551 | if (err) | 553 | if (err) |
552 | goto out3; | 554 | goto out3; |
553 | exp.ex_anon_gid= an_int; | 555 | exp.ex_anon_gid= make_kgid(&init_user_ns, an_int); |
556 | if (!gid_valid(exp.ex_anon_gid)) | ||
557 | goto out3; | ||
554 | 558 | ||
555 | /* fsid */ | 559 | /* fsid */ |
556 | err = get_int(&mesg, &an_int); | 560 | err = get_int(&mesg, &an_int); |
@@ -613,7 +617,7 @@ out: | |||
613 | } | 617 | } |
614 | 618 | ||
615 | static void exp_flags(struct seq_file *m, int flag, int fsid, | 619 | static void exp_flags(struct seq_file *m, int flag, int fsid, |
616 | uid_t anonu, uid_t anong, struct nfsd4_fs_locations *fslocs); | 620 | kuid_t anonu, kgid_t anong, struct nfsd4_fs_locations *fslocs); |
617 | static void show_secinfo(struct seq_file *m, struct svc_export *exp); | 621 | static void show_secinfo(struct seq_file *m, struct svc_export *exp); |
618 | 622 | ||
619 | static int svc_export_show(struct seq_file *m, | 623 | static int svc_export_show(struct seq_file *m, |
@@ -1179,15 +1183,17 @@ static void show_secinfo(struct seq_file *m, struct svc_export *exp) | |||
1179 | } | 1183 | } |
1180 | 1184 | ||
1181 | static void exp_flags(struct seq_file *m, int flag, int fsid, | 1185 | static void exp_flags(struct seq_file *m, int flag, int fsid, |
1182 | uid_t anonu, uid_t anong, struct nfsd4_fs_locations *fsloc) | 1186 | kuid_t anonu, kgid_t anong, struct nfsd4_fs_locations *fsloc) |
1183 | { | 1187 | { |
1184 | show_expflags(m, flag, NFSEXP_ALLFLAGS); | 1188 | show_expflags(m, flag, NFSEXP_ALLFLAGS); |
1185 | if (flag & NFSEXP_FSID) | 1189 | if (flag & NFSEXP_FSID) |
1186 | seq_printf(m, ",fsid=%d", fsid); | 1190 | seq_printf(m, ",fsid=%d", fsid); |
1187 | if (anonu != (uid_t)-2 && anonu != (0x10000-2)) | 1191 | if (!uid_eq(anonu, make_kuid(&init_user_ns, (uid_t)-2)) && |
1188 | seq_printf(m, ",anonuid=%u", anonu); | 1192 | !uid_eq(anonu, make_kuid(&init_user_ns, 0x10000-2))) |
1189 | if (anong != (gid_t)-2 && anong != (0x10000-2)) | 1193 | seq_printf(m, ",anonuid=%u", from_kuid(&init_user_ns, anonu)); |
1190 | seq_printf(m, ",anongid=%u", anong); | 1194 | if (!gid_eq(anong, make_kgid(&init_user_ns, (gid_t)-2)) && |
1195 | !gid_eq(anong, make_kgid(&init_user_ns, 0x10000-2))) | ||
1196 | seq_printf(m, ",anongid=%u", from_kgid(&init_user_ns, anong)); | ||
1191 | if (fsloc && fsloc->locations_count > 0) { | 1197 | if (fsloc && fsloc->locations_count > 0) { |
1192 | char *loctype = (fsloc->migrated) ? "refer" : "replicas"; | 1198 | char *loctype = (fsloc->migrated) ? "refer" : "replicas"; |
1193 | int i; | 1199 | int i; |
diff --git a/fs/nfsd/idmap.h b/fs/nfsd/idmap.h index 9d513efc01ba..bf95f6b817a4 100644 --- a/fs/nfsd/idmap.h +++ b/fs/nfsd/idmap.h | |||
@@ -54,9 +54,9 @@ static inline void nfsd_idmap_shutdown(struct net *net) | |||
54 | } | 54 | } |
55 | #endif | 55 | #endif |
56 | 56 | ||
57 | __be32 nfsd_map_name_to_uid(struct svc_rqst *, const char *, size_t, __u32 *); | 57 | __be32 nfsd_map_name_to_uid(struct svc_rqst *, const char *, size_t, kuid_t *); |
58 | __be32 nfsd_map_name_to_gid(struct svc_rqst *, const char *, size_t, __u32 *); | 58 | __be32 nfsd_map_name_to_gid(struct svc_rqst *, const char *, size_t, kgid_t *); |
59 | int nfsd_map_uid_to_name(struct svc_rqst *, __u32, char *); | 59 | int nfsd_map_uid_to_name(struct svc_rqst *, kuid_t, char *); |
60 | int nfsd_map_gid_to_name(struct svc_rqst *, __u32, char *); | 60 | int nfsd_map_gid_to_name(struct svc_rqst *, kgid_t, char *); |
61 | 61 | ||
62 | #endif /* LINUX_NFSD_IDMAP_H */ | 62 | #endif /* LINUX_NFSD_IDMAP_H */ |
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c index 324c0baf7cda..925c944bc0bc 100644 --- a/fs/nfsd/nfs3xdr.c +++ b/fs/nfsd/nfs3xdr.c | |||
@@ -105,12 +105,14 @@ decode_sattr3(__be32 *p, struct iattr *iap) | |||
105 | iap->ia_mode = ntohl(*p++); | 105 | iap->ia_mode = ntohl(*p++); |
106 | } | 106 | } |
107 | if (*p++) { | 107 | if (*p++) { |
108 | iap->ia_valid |= ATTR_UID; | 108 | iap->ia_uid = make_kuid(&init_user_ns, ntohl(*p++)); |
109 | iap->ia_uid = ntohl(*p++); | 109 | if (uid_valid(iap->ia_uid)) |
110 | iap->ia_valid |= ATTR_UID; | ||
110 | } | 111 | } |
111 | if (*p++) { | 112 | if (*p++) { |
112 | iap->ia_valid |= ATTR_GID; | 113 | iap->ia_gid = make_kgid(&init_user_ns, ntohl(*p++)); |
113 | iap->ia_gid = ntohl(*p++); | 114 | if (gid_valid(iap->ia_gid)) |
115 | iap->ia_valid |= ATTR_GID; | ||
114 | } | 116 | } |
115 | if (*p++) { | 117 | if (*p++) { |
116 | u64 newsize; | 118 | u64 newsize; |
@@ -167,8 +169,8 @@ encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, | |||
167 | *p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]); | 169 | *p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]); |
168 | *p++ = htonl((u32) stat->mode); | 170 | *p++ = htonl((u32) stat->mode); |
169 | *p++ = htonl((u32) stat->nlink); | 171 | *p++ = htonl((u32) stat->nlink); |
170 | *p++ = htonl((u32) nfsd_ruid(rqstp, stat->uid)); | 172 | *p++ = htonl((u32) from_kuid(&init_user_ns, stat->uid)); |
171 | *p++ = htonl((u32) nfsd_rgid(rqstp, stat->gid)); | 173 | *p++ = htonl((u32) from_kgid(&init_user_ns, stat->gid)); |
172 | if (S_ISLNK(stat->mode) && stat->size > NFS3_MAXPATHLEN) { | 174 | if (S_ISLNK(stat->mode) && stat->size > NFS3_MAXPATHLEN) { |
173 | p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN); | 175 | p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN); |
174 | } else { | 176 | } else { |
diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c index 9c51aff02ae2..8a50b3c18093 100644 --- a/fs/nfsd/nfs4acl.c +++ b/fs/nfsd/nfs4acl.c | |||
@@ -264,7 +264,7 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl, | |||
264 | ace->flag = eflag; | 264 | ace->flag = eflag; |
265 | ace->access_mask = deny_mask_from_posix(deny, flags); | 265 | ace->access_mask = deny_mask_from_posix(deny, flags); |
266 | ace->whotype = NFS4_ACL_WHO_NAMED; | 266 | ace->whotype = NFS4_ACL_WHO_NAMED; |
267 | ace->who = pa->e_id; | 267 | ace->who_uid = pa->e_uid; |
268 | ace++; | 268 | ace++; |
269 | acl->naces++; | 269 | acl->naces++; |
270 | } | 270 | } |
@@ -273,7 +273,7 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl, | |||
273 | ace->access_mask = mask_from_posix(pa->e_perm & pas.mask, | 273 | ace->access_mask = mask_from_posix(pa->e_perm & pas.mask, |
274 | flags); | 274 | flags); |
275 | ace->whotype = NFS4_ACL_WHO_NAMED; | 275 | ace->whotype = NFS4_ACL_WHO_NAMED; |
276 | ace->who = pa->e_id; | 276 | ace->who_uid = pa->e_uid; |
277 | ace++; | 277 | ace++; |
278 | acl->naces++; | 278 | acl->naces++; |
279 | pa++; | 279 | pa++; |
@@ -300,7 +300,7 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl, | |||
300 | ace->access_mask = mask_from_posix(pa->e_perm & pas.mask, | 300 | ace->access_mask = mask_from_posix(pa->e_perm & pas.mask, |
301 | flags); | 301 | flags); |
302 | ace->whotype = NFS4_ACL_WHO_NAMED; | 302 | ace->whotype = NFS4_ACL_WHO_NAMED; |
303 | ace->who = pa->e_id; | 303 | ace->who_gid = pa->e_gid; |
304 | ace++; | 304 | ace++; |
305 | acl->naces++; | 305 | acl->naces++; |
306 | pa++; | 306 | pa++; |
@@ -329,7 +329,7 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl, | |||
329 | ace->flag = eflag | NFS4_ACE_IDENTIFIER_GROUP; | 329 | ace->flag = eflag | NFS4_ACE_IDENTIFIER_GROUP; |
330 | ace->access_mask = deny_mask_from_posix(deny, flags); | 330 | ace->access_mask = deny_mask_from_posix(deny, flags); |
331 | ace->whotype = NFS4_ACL_WHO_NAMED; | 331 | ace->whotype = NFS4_ACL_WHO_NAMED; |
332 | ace->who = pa->e_id; | 332 | ace->who_gid = pa->e_gid; |
333 | ace++; | 333 | ace++; |
334 | acl->naces++; | 334 | acl->naces++; |
335 | } | 335 | } |
@@ -345,6 +345,18 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl, | |||
345 | acl->naces++; | 345 | acl->naces++; |
346 | } | 346 | } |
347 | 347 | ||
348 | static bool | ||
349 | pace_gt(struct posix_acl_entry *pace1, struct posix_acl_entry *pace2) | ||
350 | { | ||
351 | if (pace1->e_tag != pace2->e_tag) | ||
352 | return pace1->e_tag > pace2->e_tag; | ||
353 | if (pace1->e_tag == ACL_USER) | ||
354 | return uid_gt(pace1->e_uid, pace2->e_uid); | ||
355 | if (pace1->e_tag == ACL_GROUP) | ||
356 | return gid_gt(pace1->e_gid, pace2->e_gid); | ||
357 | return false; | ||
358 | } | ||
359 | |||
348 | static void | 360 | static void |
349 | sort_pacl_range(struct posix_acl *pacl, int start, int end) { | 361 | sort_pacl_range(struct posix_acl *pacl, int start, int end) { |
350 | int sorted = 0, i; | 362 | int sorted = 0, i; |
@@ -355,8 +367,8 @@ sort_pacl_range(struct posix_acl *pacl, int start, int end) { | |||
355 | while (!sorted) { | 367 | while (!sorted) { |
356 | sorted = 1; | 368 | sorted = 1; |
357 | for (i = start; i < end; i++) { | 369 | for (i = start; i < end; i++) { |
358 | if (pacl->a_entries[i].e_id | 370 | if (pace_gt(&pacl->a_entries[i], |
359 | > pacl->a_entries[i+1].e_id) { | 371 | &pacl->a_entries[i+1])) { |
360 | sorted = 0; | 372 | sorted = 0; |
361 | tmp = pacl->a_entries[i]; | 373 | tmp = pacl->a_entries[i]; |
362 | pacl->a_entries[i] = pacl->a_entries[i+1]; | 374 | pacl->a_entries[i] = pacl->a_entries[i+1]; |
@@ -398,7 +410,10 @@ struct posix_ace_state { | |||
398 | }; | 410 | }; |
399 | 411 | ||
400 | struct posix_user_ace_state { | 412 | struct posix_user_ace_state { |
401 | uid_t uid; | 413 | union { |
414 | kuid_t uid; | ||
415 | kgid_t gid; | ||
416 | }; | ||
402 | struct posix_ace_state perms; | 417 | struct posix_ace_state perms; |
403 | }; | 418 | }; |
404 | 419 | ||
@@ -521,7 +536,6 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags) | |||
521 | if (error) | 536 | if (error) |
522 | goto out_err; | 537 | goto out_err; |
523 | low_mode_from_nfs4(state->owner.allow, &pace->e_perm, flags); | 538 | low_mode_from_nfs4(state->owner.allow, &pace->e_perm, flags); |
524 | pace->e_id = ACL_UNDEFINED_ID; | ||
525 | 539 | ||
526 | for (i=0; i < state->users->n; i++) { | 540 | for (i=0; i < state->users->n; i++) { |
527 | pace++; | 541 | pace++; |
@@ -531,7 +545,7 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags) | |||
531 | goto out_err; | 545 | goto out_err; |
532 | low_mode_from_nfs4(state->users->aces[i].perms.allow, | 546 | low_mode_from_nfs4(state->users->aces[i].perms.allow, |
533 | &pace->e_perm, flags); | 547 | &pace->e_perm, flags); |
534 | pace->e_id = state->users->aces[i].uid; | 548 | pace->e_uid = state->users->aces[i].uid; |
535 | add_to_mask(state, &state->users->aces[i].perms); | 549 | add_to_mask(state, &state->users->aces[i].perms); |
536 | } | 550 | } |
537 | 551 | ||
@@ -541,7 +555,6 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags) | |||
541 | if (error) | 555 | if (error) |
542 | goto out_err; | 556 | goto out_err; |
543 | low_mode_from_nfs4(state->group.allow, &pace->e_perm, flags); | 557 | low_mode_from_nfs4(state->group.allow, &pace->e_perm, flags); |
544 | pace->e_id = ACL_UNDEFINED_ID; | ||
545 | add_to_mask(state, &state->group); | 558 | add_to_mask(state, &state->group); |
546 | 559 | ||
547 | for (i=0; i < state->groups->n; i++) { | 560 | for (i=0; i < state->groups->n; i++) { |
@@ -552,14 +565,13 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags) | |||
552 | goto out_err; | 565 | goto out_err; |
553 | low_mode_from_nfs4(state->groups->aces[i].perms.allow, | 566 | low_mode_from_nfs4(state->groups->aces[i].perms.allow, |
554 | &pace->e_perm, flags); | 567 | &pace->e_perm, flags); |
555 | pace->e_id = state->groups->aces[i].uid; | 568 | pace->e_gid = state->groups->aces[i].gid; |
556 | add_to_mask(state, &state->groups->aces[i].perms); | 569 | add_to_mask(state, &state->groups->aces[i].perms); |
557 | } | 570 | } |
558 | 571 | ||
559 | pace++; | 572 | pace++; |
560 | pace->e_tag = ACL_MASK; | 573 | pace->e_tag = ACL_MASK; |
561 | low_mode_from_nfs4(state->mask.allow, &pace->e_perm, flags); | 574 | low_mode_from_nfs4(state->mask.allow, &pace->e_perm, flags); |
562 | pace->e_id = ACL_UNDEFINED_ID; | ||
563 | 575 | ||
564 | pace++; | 576 | pace++; |
565 | pace->e_tag = ACL_OTHER; | 577 | pace->e_tag = ACL_OTHER; |
@@ -567,7 +579,6 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags) | |||
567 | if (error) | 579 | if (error) |
568 | goto out_err; | 580 | goto out_err; |
569 | low_mode_from_nfs4(state->other.allow, &pace->e_perm, flags); | 581 | low_mode_from_nfs4(state->other.allow, &pace->e_perm, flags); |
570 | pace->e_id = ACL_UNDEFINED_ID; | ||
571 | 582 | ||
572 | return pacl; | 583 | return pacl; |
573 | out_err: | 584 | out_err: |
@@ -587,12 +598,13 @@ static inline void deny_bits(struct posix_ace_state *astate, u32 mask) | |||
587 | astate->deny |= mask & ~astate->allow; | 598 | astate->deny |= mask & ~astate->allow; |
588 | } | 599 | } |
589 | 600 | ||
590 | static int find_uid(struct posix_acl_state *state, struct posix_ace_state_array *a, uid_t uid) | 601 | static int find_uid(struct posix_acl_state *state, kuid_t uid) |
591 | { | 602 | { |
603 | struct posix_ace_state_array *a = state->users; | ||
592 | int i; | 604 | int i; |
593 | 605 | ||
594 | for (i = 0; i < a->n; i++) | 606 | for (i = 0; i < a->n; i++) |
595 | if (a->aces[i].uid == uid) | 607 | if (uid_eq(a->aces[i].uid, uid)) |
596 | return i; | 608 | return i; |
597 | /* Not found: */ | 609 | /* Not found: */ |
598 | a->n++; | 610 | a->n++; |
@@ -603,6 +615,23 @@ static int find_uid(struct posix_acl_state *state, struct posix_ace_state_array | |||
603 | return i; | 615 | return i; |
604 | } | 616 | } |
605 | 617 | ||
618 | static int find_gid(struct posix_acl_state *state, kgid_t gid) | ||
619 | { | ||
620 | struct posix_ace_state_array *a = state->groups; | ||
621 | int i; | ||
622 | |||
623 | for (i = 0; i < a->n; i++) | ||
624 | if (gid_eq(a->aces[i].gid, gid)) | ||
625 | return i; | ||
626 | /* Not found: */ | ||
627 | a->n++; | ||
628 | a->aces[i].gid = gid; | ||
629 | a->aces[i].perms.allow = state->everyone.allow; | ||
630 | a->aces[i].perms.deny = state->everyone.deny; | ||
631 | |||
632 | return i; | ||
633 | } | ||
634 | |||
606 | static void deny_bits_array(struct posix_ace_state_array *a, u32 mask) | 635 | static void deny_bits_array(struct posix_ace_state_array *a, u32 mask) |
607 | { | 636 | { |
608 | int i; | 637 | int i; |
@@ -636,7 +665,7 @@ static void process_one_v4_ace(struct posix_acl_state *state, | |||
636 | } | 665 | } |
637 | break; | 666 | break; |
638 | case ACL_USER: | 667 | case ACL_USER: |
639 | i = find_uid(state, state->users, ace->who); | 668 | i = find_uid(state, ace->who_uid); |
640 | if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { | 669 | if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { |
641 | allow_bits(&state->users->aces[i].perms, mask); | 670 | allow_bits(&state->users->aces[i].perms, mask); |
642 | } else { | 671 | } else { |
@@ -658,7 +687,7 @@ static void process_one_v4_ace(struct posix_acl_state *state, | |||
658 | } | 687 | } |
659 | break; | 688 | break; |
660 | case ACL_GROUP: | 689 | case ACL_GROUP: |
661 | i = find_uid(state, state->groups, ace->who); | 690 | i = find_gid(state, ace->who_gid); |
662 | if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { | 691 | if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { |
663 | allow_bits(&state->groups->aces[i].perms, mask); | 692 | allow_bits(&state->groups->aces[i].perms, mask); |
664 | } else { | 693 | } else { |
diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c index a1f10c0a6255..0ce12346df9c 100644 --- a/fs/nfsd/nfs4idmap.c +++ b/fs/nfsd/nfs4idmap.c | |||
@@ -65,7 +65,7 @@ MODULE_PARM_DESC(nfs4_disable_idmapping, | |||
65 | struct ent { | 65 | struct ent { |
66 | struct cache_head h; | 66 | struct cache_head h; |
67 | int type; /* User / Group */ | 67 | int type; /* User / Group */ |
68 | uid_t id; | 68 | u32 id; |
69 | char name[IDMAP_NAMESZ]; | 69 | char name[IDMAP_NAMESZ]; |
70 | char authname[IDMAP_NAMESZ]; | 70 | char authname[IDMAP_NAMESZ]; |
71 | }; | 71 | }; |
@@ -540,7 +540,7 @@ rqst_authname(struct svc_rqst *rqstp) | |||
540 | 540 | ||
541 | static __be32 | 541 | static __be32 |
542 | idmap_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, | 542 | idmap_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, |
543 | uid_t *id) | 543 | u32 *id) |
544 | { | 544 | { |
545 | struct ent *item, key = { | 545 | struct ent *item, key = { |
546 | .type = type, | 546 | .type = type, |
@@ -564,7 +564,7 @@ idmap_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen | |||
564 | } | 564 | } |
565 | 565 | ||
566 | static int | 566 | static int |
567 | idmap_id_to_name(struct svc_rqst *rqstp, int type, uid_t id, char *name) | 567 | idmap_id_to_name(struct svc_rqst *rqstp, int type, u32 id, char *name) |
568 | { | 568 | { |
569 | struct ent *item, key = { | 569 | struct ent *item, key = { |
570 | .id = id, | 570 | .id = id, |
@@ -587,7 +587,7 @@ idmap_id_to_name(struct svc_rqst *rqstp, int type, uid_t id, char *name) | |||
587 | } | 587 | } |
588 | 588 | ||
589 | static bool | 589 | static bool |
590 | numeric_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, uid_t *id) | 590 | numeric_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, u32 *id) |
591 | { | 591 | { |
592 | int ret; | 592 | int ret; |
593 | char buf[11]; | 593 | char buf[11]; |
@@ -603,7 +603,7 @@ numeric_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namel | |||
603 | } | 603 | } |
604 | 604 | ||
605 | static __be32 | 605 | static __be32 |
606 | do_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, uid_t *id) | 606 | do_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, u32 *id) |
607 | { | 607 | { |
608 | if (nfs4_disable_idmapping && rqstp->rq_cred.cr_flavor < RPC_AUTH_GSS) | 608 | if (nfs4_disable_idmapping && rqstp->rq_cred.cr_flavor < RPC_AUTH_GSS) |
609 | if (numeric_name_to_id(rqstp, type, name, namelen, id)) | 609 | if (numeric_name_to_id(rqstp, type, name, namelen, id)) |
@@ -616,7 +616,7 @@ do_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, u | |||
616 | } | 616 | } |
617 | 617 | ||
618 | static int | 618 | static int |
619 | do_id_to_name(struct svc_rqst *rqstp, int type, uid_t id, char *name) | 619 | do_id_to_name(struct svc_rqst *rqstp, int type, u32 id, char *name) |
620 | { | 620 | { |
621 | if (nfs4_disable_idmapping && rqstp->rq_cred.cr_flavor < RPC_AUTH_GSS) | 621 | if (nfs4_disable_idmapping && rqstp->rq_cred.cr_flavor < RPC_AUTH_GSS) |
622 | return sprintf(name, "%u", id); | 622 | return sprintf(name, "%u", id); |
@@ -625,26 +625,40 @@ do_id_to_name(struct svc_rqst *rqstp, int type, uid_t id, char *name) | |||
625 | 625 | ||
626 | __be32 | 626 | __be32 |
627 | nfsd_map_name_to_uid(struct svc_rqst *rqstp, const char *name, size_t namelen, | 627 | nfsd_map_name_to_uid(struct svc_rqst *rqstp, const char *name, size_t namelen, |
628 | __u32 *id) | 628 | kuid_t *uid) |
629 | { | 629 | { |
630 | return do_name_to_id(rqstp, IDMAP_TYPE_USER, name, namelen, id); | 630 | __be32 status; |
631 | u32 id = -1; | ||
632 | status = do_name_to_id(rqstp, IDMAP_TYPE_USER, name, namelen, &id); | ||
633 | *uid = make_kuid(&init_user_ns, id); | ||
634 | if (!uid_valid(*uid)) | ||
635 | status = nfserr_badowner; | ||
636 | return status; | ||
631 | } | 637 | } |
632 | 638 | ||
633 | __be32 | 639 | __be32 |
634 | nfsd_map_name_to_gid(struct svc_rqst *rqstp, const char *name, size_t namelen, | 640 | nfsd_map_name_to_gid(struct svc_rqst *rqstp, const char *name, size_t namelen, |
635 | __u32 *id) | 641 | kgid_t *gid) |
636 | { | 642 | { |
637 | return do_name_to_id(rqstp, IDMAP_TYPE_GROUP, name, namelen, id); | 643 | __be32 status; |
644 | u32 id = -1; | ||
645 | status = do_name_to_id(rqstp, IDMAP_TYPE_GROUP, name, namelen, &id); | ||
646 | *gid = make_kgid(&init_user_ns, id); | ||
647 | if (!gid_valid(*gid)) | ||
648 | status = nfserr_badowner; | ||
649 | return status; | ||
638 | } | 650 | } |
639 | 651 | ||
640 | int | 652 | int |
641 | nfsd_map_uid_to_name(struct svc_rqst *rqstp, __u32 id, char *name) | 653 | nfsd_map_uid_to_name(struct svc_rqst *rqstp, kuid_t uid, char *name) |
642 | { | 654 | { |
655 | u32 id = from_kuid(&init_user_ns, uid); | ||
643 | return do_id_to_name(rqstp, IDMAP_TYPE_USER, id, name); | 656 | return do_id_to_name(rqstp, IDMAP_TYPE_USER, id, name); |
644 | } | 657 | } |
645 | 658 | ||
646 | int | 659 | int |
647 | nfsd_map_gid_to_name(struct svc_rqst *rqstp, __u32 id, char *name) | 660 | nfsd_map_gid_to_name(struct svc_rqst *rqstp, kgid_t gid, char *name) |
648 | { | 661 | { |
662 | u32 id = from_kgid(&init_user_ns, gid); | ||
649 | return do_id_to_name(rqstp, IDMAP_TYPE_GROUP, id, name); | 663 | return do_id_to_name(rqstp, IDMAP_TYPE_GROUP, id, name); |
650 | } | 664 | } |
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index ba6fdd4a0455..4914af4a817e 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c | |||
@@ -73,8 +73,8 @@ nfs4_save_creds(const struct cred **original_creds) | |||
73 | if (!new) | 73 | if (!new) |
74 | return -ENOMEM; | 74 | return -ENOMEM; |
75 | 75 | ||
76 | new->fsuid = 0; | 76 | new->fsuid = GLOBAL_ROOT_UID; |
77 | new->fsgid = 0; | 77 | new->fsgid = GLOBAL_ROOT_GID; |
78 | *original_creds = override_creds(new); | 78 | *original_creds = override_creds(new); |
79 | put_cred(new); | 79 | put_cred(new); |
80 | return 0; | 80 | return 0; |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 499e957510e7..9e7103b6e0ad 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -1202,7 +1202,7 @@ static bool groups_equal(struct group_info *g1, struct group_info *g2) | |||
1202 | if (g1->ngroups != g2->ngroups) | 1202 | if (g1->ngroups != g2->ngroups) |
1203 | return false; | 1203 | return false; |
1204 | for (i=0; i<g1->ngroups; i++) | 1204 | for (i=0; i<g1->ngroups; i++) |
1205 | if (GROUP_AT(g1, i) != GROUP_AT(g2, i)) | 1205 | if (!gid_eq(GROUP_AT(g1, i), GROUP_AT(g2, i))) |
1206 | return false; | 1206 | return false; |
1207 | return true; | 1207 | return true; |
1208 | } | 1208 | } |
@@ -1227,8 +1227,8 @@ static bool | |||
1227 | same_creds(struct svc_cred *cr1, struct svc_cred *cr2) | 1227 | same_creds(struct svc_cred *cr1, struct svc_cred *cr2) |
1228 | { | 1228 | { |
1229 | if ((is_gss_cred(cr1) != is_gss_cred(cr2)) | 1229 | if ((is_gss_cred(cr1) != is_gss_cred(cr2)) |
1230 | || (cr1->cr_uid != cr2->cr_uid) | 1230 | || (!uid_eq(cr1->cr_uid, cr2->cr_uid)) |
1231 | || (cr1->cr_gid != cr2->cr_gid) | 1231 | || (!gid_eq(cr1->cr_gid, cr2->cr_gid)) |
1232 | || !groups_equal(cr1->cr_group_info, cr2->cr_group_info)) | 1232 | || !groups_equal(cr1->cr_group_info, cr2->cr_group_info)) |
1233 | return false; | 1233 | return false; |
1234 | if (cr1->cr_principal == cr2->cr_principal) | 1234 | if (cr1->cr_principal == cr2->cr_principal) |
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 0dc11586682f..2d1d06bae3a7 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c | |||
@@ -293,13 +293,13 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, | |||
293 | ace->whotype = nfs4_acl_get_whotype(buf, dummy32); | 293 | ace->whotype = nfs4_acl_get_whotype(buf, dummy32); |
294 | status = nfs_ok; | 294 | status = nfs_ok; |
295 | if (ace->whotype != NFS4_ACL_WHO_NAMED) | 295 | if (ace->whotype != NFS4_ACL_WHO_NAMED) |
296 | ace->who = 0; | 296 | ; |
297 | else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP) | 297 | else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP) |
298 | status = nfsd_map_name_to_gid(argp->rqstp, | 298 | status = nfsd_map_name_to_gid(argp->rqstp, |
299 | buf, dummy32, &ace->who); | 299 | buf, dummy32, &ace->who_gid); |
300 | else | 300 | else |
301 | status = nfsd_map_name_to_uid(argp->rqstp, | 301 | status = nfsd_map_name_to_uid(argp->rqstp, |
302 | buf, dummy32, &ace->who); | 302 | buf, dummy32, &ace->who_uid); |
303 | if (status) | 303 | if (status) |
304 | return status; | 304 | return status; |
305 | } | 305 | } |
@@ -464,9 +464,16 @@ static __be32 nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_ | |||
464 | READ32(dummy); | 464 | READ32(dummy); |
465 | READ_BUF(dummy * 4); | 465 | READ_BUF(dummy * 4); |
466 | if (cbs->flavor == (u32)(-1)) { | 466 | if (cbs->flavor == (u32)(-1)) { |
467 | cbs->uid = uid; | 467 | kuid_t kuid = make_kuid(&init_user_ns, uid); |
468 | cbs->gid = gid; | 468 | kgid_t kgid = make_kgid(&init_user_ns, gid); |
469 | cbs->flavor = RPC_AUTH_UNIX; | 469 | if (uid_valid(kuid) && gid_valid(kgid)) { |
470 | cbs->uid = kuid; | ||
471 | cbs->gid = kgid; | ||
472 | cbs->flavor = RPC_AUTH_UNIX; | ||
473 | } else { | ||
474 | dprintk("RPC_AUTH_UNIX with invalid" | ||
475 | "uid or gid ignoring!\n"); | ||
476 | } | ||
470 | } | 477 | } |
471 | break; | 478 | break; |
472 | case RPC_AUTH_GSS: | 479 | case RPC_AUTH_GSS: |
@@ -1926,7 +1933,7 @@ static u32 nfs4_file_type(umode_t mode) | |||
1926 | } | 1933 | } |
1927 | 1934 | ||
1928 | static __be32 | 1935 | static __be32 |
1929 | nfsd4_encode_name(struct svc_rqst *rqstp, int whotype, uid_t id, int group, | 1936 | nfsd4_encode_name(struct svc_rqst *rqstp, int whotype, kuid_t uid, kgid_t gid, |
1930 | __be32 **p, int *buflen) | 1937 | __be32 **p, int *buflen) |
1931 | { | 1938 | { |
1932 | int status; | 1939 | int status; |
@@ -1935,10 +1942,10 @@ nfsd4_encode_name(struct svc_rqst *rqstp, int whotype, uid_t id, int group, | |||
1935 | return nfserr_resource; | 1942 | return nfserr_resource; |
1936 | if (whotype != NFS4_ACL_WHO_NAMED) | 1943 | if (whotype != NFS4_ACL_WHO_NAMED) |
1937 | status = nfs4_acl_write_who(whotype, (u8 *)(*p + 1)); | 1944 | status = nfs4_acl_write_who(whotype, (u8 *)(*p + 1)); |
1938 | else if (group) | 1945 | else if (gid_valid(gid)) |
1939 | status = nfsd_map_gid_to_name(rqstp, id, (u8 *)(*p + 1)); | 1946 | status = nfsd_map_gid_to_name(rqstp, gid, (u8 *)(*p + 1)); |
1940 | else | 1947 | else |
1941 | status = nfsd_map_uid_to_name(rqstp, id, (u8 *)(*p + 1)); | 1948 | status = nfsd_map_uid_to_name(rqstp, uid, (u8 *)(*p + 1)); |
1942 | if (status < 0) | 1949 | if (status < 0) |
1943 | return nfserrno(status); | 1950 | return nfserrno(status); |
1944 | *p = xdr_encode_opaque(*p, NULL, status); | 1951 | *p = xdr_encode_opaque(*p, NULL, status); |
@@ -1948,22 +1955,33 @@ nfsd4_encode_name(struct svc_rqst *rqstp, int whotype, uid_t id, int group, | |||
1948 | } | 1955 | } |
1949 | 1956 | ||
1950 | static inline __be32 | 1957 | static inline __be32 |
1951 | nfsd4_encode_user(struct svc_rqst *rqstp, uid_t uid, __be32 **p, int *buflen) | 1958 | nfsd4_encode_user(struct svc_rqst *rqstp, kuid_t user, __be32 **p, int *buflen) |
1952 | { | 1959 | { |
1953 | return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, uid, 0, p, buflen); | 1960 | return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, user, INVALID_GID, |
1961 | p, buflen); | ||
1954 | } | 1962 | } |
1955 | 1963 | ||
1956 | static inline __be32 | 1964 | static inline __be32 |
1957 | nfsd4_encode_group(struct svc_rqst *rqstp, uid_t gid, __be32 **p, int *buflen) | 1965 | nfsd4_encode_group(struct svc_rqst *rqstp, kgid_t group, __be32 **p, int *buflen) |
1958 | { | 1966 | { |
1959 | return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, gid, 1, p, buflen); | 1967 | return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, INVALID_UID, group, |
1968 | p, buflen); | ||
1960 | } | 1969 | } |
1961 | 1970 | ||
1962 | static inline __be32 | 1971 | static inline __be32 |
1963 | nfsd4_encode_aclname(struct svc_rqst *rqstp, int whotype, uid_t id, int group, | 1972 | nfsd4_encode_aclname(struct svc_rqst *rqstp, struct nfs4_ace *ace, |
1964 | __be32 **p, int *buflen) | 1973 | __be32 **p, int *buflen) |
1965 | { | 1974 | { |
1966 | return nfsd4_encode_name(rqstp, whotype, id, group, p, buflen); | 1975 | kuid_t uid = INVALID_UID; |
1976 | kgid_t gid = INVALID_GID; | ||
1977 | |||
1978 | if (ace->whotype == NFS4_ACL_WHO_NAMED) { | ||
1979 | if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP) | ||
1980 | gid = ace->who_gid; | ||
1981 | else | ||
1982 | uid = ace->who_uid; | ||
1983 | } | ||
1984 | return nfsd4_encode_name(rqstp, ace->whotype, uid, gid, p, buflen); | ||
1967 | } | 1985 | } |
1968 | 1986 | ||
1969 | #define WORD0_ABSENT_FS_ATTRS (FATTR4_WORD0_FS_LOCATIONS | FATTR4_WORD0_FSID | \ | 1987 | #define WORD0_ABSENT_FS_ATTRS (FATTR4_WORD0_FS_LOCATIONS | FATTR4_WORD0_FSID | \ |
@@ -2224,9 +2242,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, | |||
2224 | WRITE32(ace->type); | 2242 | WRITE32(ace->type); |
2225 | WRITE32(ace->flag); | 2243 | WRITE32(ace->flag); |
2226 | WRITE32(ace->access_mask & NFS4_ACE_MASK_ALL); | 2244 | WRITE32(ace->access_mask & NFS4_ACE_MASK_ALL); |
2227 | status = nfsd4_encode_aclname(rqstp, ace->whotype, | 2245 | status = nfsd4_encode_aclname(rqstp, ace, &p, &buflen); |
2228 | ace->who, ace->flag & NFS4_ACE_IDENTIFIER_GROUP, | ||
2229 | &p, &buflen); | ||
2230 | if (status == nfserr_resource) | 2246 | if (status == nfserr_resource) |
2231 | goto out_resource; | 2247 | goto out_resource; |
2232 | if (status) | 2248 | if (status) |
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c index 979b42106979..4201ede0ec91 100644 --- a/fs/nfsd/nfsxdr.c +++ b/fs/nfsd/nfsxdr.c | |||
@@ -100,12 +100,14 @@ decode_sattr(__be32 *p, struct iattr *iap) | |||
100 | iap->ia_mode = tmp; | 100 | iap->ia_mode = tmp; |
101 | } | 101 | } |
102 | if ((tmp = ntohl(*p++)) != (u32)-1) { | 102 | if ((tmp = ntohl(*p++)) != (u32)-1) { |
103 | iap->ia_valid |= ATTR_UID; | 103 | iap->ia_uid = make_kuid(&init_user_ns, tmp); |
104 | iap->ia_uid = tmp; | 104 | if (uid_valid(iap->ia_uid)) |
105 | iap->ia_valid |= ATTR_UID; | ||
105 | } | 106 | } |
106 | if ((tmp = ntohl(*p++)) != (u32)-1) { | 107 | if ((tmp = ntohl(*p++)) != (u32)-1) { |
107 | iap->ia_valid |= ATTR_GID; | 108 | iap->ia_gid = make_kgid(&init_user_ns, tmp); |
108 | iap->ia_gid = tmp; | 109 | if (gid_valid(iap->ia_gid)) |
110 | iap->ia_valid |= ATTR_GID; | ||
109 | } | 111 | } |
110 | if ((tmp = ntohl(*p++)) != (u32)-1) { | 112 | if ((tmp = ntohl(*p++)) != (u32)-1) { |
111 | iap->ia_valid |= ATTR_SIZE; | 113 | iap->ia_valid |= ATTR_SIZE; |
@@ -151,8 +153,8 @@ encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, | |||
151 | *p++ = htonl(nfs_ftypes[type >> 12]); | 153 | *p++ = htonl(nfs_ftypes[type >> 12]); |
152 | *p++ = htonl((u32) stat->mode); | 154 | *p++ = htonl((u32) stat->mode); |
153 | *p++ = htonl((u32) stat->nlink); | 155 | *p++ = htonl((u32) stat->nlink); |
154 | *p++ = htonl((u32) nfsd_ruid(rqstp, stat->uid)); | 156 | *p++ = htonl((u32) from_kuid(&init_user_ns, stat->uid)); |
155 | *p++ = htonl((u32) nfsd_rgid(rqstp, stat->gid)); | 157 | *p++ = htonl((u32) from_kgid(&init_user_ns, stat->gid)); |
156 | 158 | ||
157 | if (S_ISLNK(type) && stat->size > NFS_MAXPATHLEN) { | 159 | if (S_ISLNK(type) && stat->size > NFS_MAXPATHLEN) { |
158 | *p++ = htonl(NFS_MAXPATHLEN); | 160 | *p++ = htonl(NFS_MAXPATHLEN); |
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index d1c229feed52..1a8c7391f7ae 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h | |||
@@ -152,8 +152,8 @@ struct nfsd4_channel_attrs { | |||
152 | 152 | ||
153 | struct nfsd4_cb_sec { | 153 | struct nfsd4_cb_sec { |
154 | u32 flavor; /* (u32)(-1) used to mean "no valid flavor" */ | 154 | u32 flavor; /* (u32)(-1) used to mean "no valid flavor" */ |
155 | u32 uid; | 155 | kuid_t uid; |
156 | u32 gid; | 156 | kgid_t gid; |
157 | }; | 157 | }; |
158 | 158 | ||
159 | struct nfsd4_create_session { | 159 | struct nfsd4_create_session { |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index d586117fa94a..31ff1d642e31 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -401,8 +401,8 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap, | |||
401 | 401 | ||
402 | /* Revoke setuid/setgid on chown */ | 402 | /* Revoke setuid/setgid on chown */ |
403 | if (!S_ISDIR(inode->i_mode) && | 403 | if (!S_ISDIR(inode->i_mode) && |
404 | (((iap->ia_valid & ATTR_UID) && iap->ia_uid != inode->i_uid) || | 404 | (((iap->ia_valid & ATTR_UID) && !uid_eq(iap->ia_uid, inode->i_uid)) || |
405 | ((iap->ia_valid & ATTR_GID) && iap->ia_gid != inode->i_gid))) { | 405 | ((iap->ia_valid & ATTR_GID) && !gid_eq(iap->ia_gid, inode->i_gid)))) { |
406 | iap->ia_valid |= ATTR_KILL_PRIV; | 406 | iap->ia_valid |= ATTR_KILL_PRIV; |
407 | if (iap->ia_valid & ATTR_MODE) { | 407 | if (iap->ia_valid & ATTR_MODE) { |
408 | /* we're setting mode too, just clear the s*id bits */ | 408 | /* we're setting mode too, just clear the s*id bits */ |
@@ -1205,7 +1205,7 @@ nfsd_create_setattr(struct svc_rqst *rqstp, struct svc_fh *resfhp, | |||
1205 | * send along the gid on create when it tries to implement | 1205 | * send along the gid on create when it tries to implement |
1206 | * setgid directories via NFS: | 1206 | * setgid directories via NFS: |
1207 | */ | 1207 | */ |
1208 | if (current_fsuid() != 0) | 1208 | if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) |
1209 | iap->ia_valid &= ~(ATTR_UID|ATTR_GID); | 1209 | iap->ia_valid &= ~(ATTR_UID|ATTR_GID); |
1210 | if (iap->ia_valid) | 1210 | if (iap->ia_valid) |
1211 | return nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0); | 1211 | return nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0); |
@@ -2150,7 +2150,7 @@ nfsd_permission(struct svc_rqst *rqstp, struct svc_export *exp, | |||
2150 | * with NFSv3. | 2150 | * with NFSv3. |
2151 | */ | 2151 | */ |
2152 | if ((acc & NFSD_MAY_OWNER_OVERRIDE) && | 2152 | if ((acc & NFSD_MAY_OWNER_OVERRIDE) && |
2153 | inode->i_uid == current_fsuid()) | 2153 | uid_eq(inode->i_uid, current_fsuid())) |
2154 | return 0; | 2154 | return 0; |
2155 | 2155 | ||
2156 | /* This assumes NFSD_MAY_{READ,WRITE,EXEC} == MAY_{READ,WRITE,EXEC} */ | 2156 | /* This assumes NFSD_MAY_{READ,WRITE,EXEC} == MAY_{READ,WRITE,EXEC} */ |
diff --git a/fs/ocfs2/acl.c b/fs/ocfs2/acl.c index 260b16281fc3..8a404576fb26 100644 --- a/fs/ocfs2/acl.c +++ b/fs/ocfs2/acl.c | |||
@@ -65,7 +65,20 @@ static struct posix_acl *ocfs2_acl_from_xattr(const void *value, size_t size) | |||
65 | 65 | ||
66 | acl->a_entries[n].e_tag = le16_to_cpu(entry->e_tag); | 66 | acl->a_entries[n].e_tag = le16_to_cpu(entry->e_tag); |
67 | acl->a_entries[n].e_perm = le16_to_cpu(entry->e_perm); | 67 | acl->a_entries[n].e_perm = le16_to_cpu(entry->e_perm); |
68 | acl->a_entries[n].e_id = le32_to_cpu(entry->e_id); | 68 | switch(acl->a_entries[n].e_tag) { |
69 | case ACL_USER: | ||
70 | acl->a_entries[n].e_uid = | ||
71 | make_kuid(&init_user_ns, | ||
72 | le32_to_cpu(entry->e_id)); | ||
73 | break; | ||
74 | case ACL_GROUP: | ||
75 | acl->a_entries[n].e_gid = | ||
76 | make_kgid(&init_user_ns, | ||
77 | le32_to_cpu(entry->e_id)); | ||
78 | break; | ||
79 | default: | ||
80 | break; | ||
81 | } | ||
69 | value += sizeof(struct posix_acl_entry); | 82 | value += sizeof(struct posix_acl_entry); |
70 | 83 | ||
71 | } | 84 | } |
@@ -91,7 +104,21 @@ static void *ocfs2_acl_to_xattr(const struct posix_acl *acl, size_t *size) | |||
91 | for (n = 0; n < acl->a_count; n++, entry++) { | 104 | for (n = 0; n < acl->a_count; n++, entry++) { |
92 | entry->e_tag = cpu_to_le16(acl->a_entries[n].e_tag); | 105 | entry->e_tag = cpu_to_le16(acl->a_entries[n].e_tag); |
93 | entry->e_perm = cpu_to_le16(acl->a_entries[n].e_perm); | 106 | entry->e_perm = cpu_to_le16(acl->a_entries[n].e_perm); |
94 | entry->e_id = cpu_to_le32(acl->a_entries[n].e_id); | 107 | switch(acl->a_entries[n].e_tag) { |
108 | case ACL_USER: | ||
109 | entry->e_id = cpu_to_le32( | ||
110 | from_kuid(&init_user_ns, | ||
111 | acl->a_entries[n].e_uid)); | ||
112 | break; | ||
113 | case ACL_GROUP: | ||
114 | entry->e_id = cpu_to_le32( | ||
115 | from_kgid(&init_user_ns, | ||
116 | acl->a_entries[n].e_gid)); | ||
117 | break; | ||
118 | default: | ||
119 | entry->e_id = cpu_to_le32(ACL_UNDEFINED_ID); | ||
120 | break; | ||
121 | } | ||
95 | } | 122 | } |
96 | return ocfs2_acl; | 123 | return ocfs2_acl; |
97 | } | 124 | } |
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index 88577eb5d712..12ae194ac943 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c | |||
@@ -2045,8 +2045,8 @@ static void __ocfs2_stuff_meta_lvb(struct inode *inode) | |||
2045 | lvb->lvb_version = OCFS2_LVB_VERSION; | 2045 | lvb->lvb_version = OCFS2_LVB_VERSION; |
2046 | lvb->lvb_isize = cpu_to_be64(i_size_read(inode)); | 2046 | lvb->lvb_isize = cpu_to_be64(i_size_read(inode)); |
2047 | lvb->lvb_iclusters = cpu_to_be32(oi->ip_clusters); | 2047 | lvb->lvb_iclusters = cpu_to_be32(oi->ip_clusters); |
2048 | lvb->lvb_iuid = cpu_to_be32(inode->i_uid); | 2048 | lvb->lvb_iuid = cpu_to_be32(i_uid_read(inode)); |
2049 | lvb->lvb_igid = cpu_to_be32(inode->i_gid); | 2049 | lvb->lvb_igid = cpu_to_be32(i_gid_read(inode)); |
2050 | lvb->lvb_imode = cpu_to_be16(inode->i_mode); | 2050 | lvb->lvb_imode = cpu_to_be16(inode->i_mode); |
2051 | lvb->lvb_inlink = cpu_to_be16(inode->i_nlink); | 2051 | lvb->lvb_inlink = cpu_to_be16(inode->i_nlink); |
2052 | lvb->lvb_iatime_packed = | 2052 | lvb->lvb_iatime_packed = |
@@ -2095,8 +2095,8 @@ static void ocfs2_refresh_inode_from_lvb(struct inode *inode) | |||
2095 | else | 2095 | else |
2096 | inode->i_blocks = ocfs2_inode_sector_count(inode); | 2096 | inode->i_blocks = ocfs2_inode_sector_count(inode); |
2097 | 2097 | ||
2098 | inode->i_uid = be32_to_cpu(lvb->lvb_iuid); | 2098 | i_uid_write(inode, be32_to_cpu(lvb->lvb_iuid)); |
2099 | inode->i_gid = be32_to_cpu(lvb->lvb_igid); | 2099 | i_gid_write(inode, be32_to_cpu(lvb->lvb_igid)); |
2100 | inode->i_mode = be16_to_cpu(lvb->lvb_imode); | 2100 | inode->i_mode = be16_to_cpu(lvb->lvb_imode); |
2101 | set_nlink(inode, be16_to_cpu(lvb->lvb_inlink)); | 2101 | set_nlink(inode, be16_to_cpu(lvb->lvb_inlink)); |
2102 | ocfs2_unpack_timespec(&inode->i_atime, | 2102 | ocfs2_unpack_timespec(&inode->i_atime, |
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 37d313ede159..0a2924a2d9e6 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -1116,7 +1116,8 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) | |||
1116 | (unsigned long long)OCFS2_I(inode)->ip_blkno, | 1116 | (unsigned long long)OCFS2_I(inode)->ip_blkno, |
1117 | dentry->d_name.len, dentry->d_name.name, | 1117 | dentry->d_name.len, dentry->d_name.name, |
1118 | attr->ia_valid, attr->ia_mode, | 1118 | attr->ia_valid, attr->ia_mode, |
1119 | attr->ia_uid, attr->ia_gid); | 1119 | from_kuid(&init_user_ns, attr->ia_uid), |
1120 | from_kgid(&init_user_ns, attr->ia_gid)); | ||
1120 | 1121 | ||
1121 | /* ensuring we don't even attempt to truncate a symlink */ | 1122 | /* ensuring we don't even attempt to truncate a symlink */ |
1122 | if (S_ISLNK(inode->i_mode)) | 1123 | if (S_ISLNK(inode->i_mode)) |
@@ -1174,14 +1175,14 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) | |||
1174 | } | 1175 | } |
1175 | } | 1176 | } |
1176 | 1177 | ||
1177 | if ((attr->ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || | 1178 | if ((attr->ia_valid & ATTR_UID && !uid_eq(attr->ia_uid, inode->i_uid)) || |
1178 | (attr->ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) { | 1179 | (attr->ia_valid & ATTR_GID && !gid_eq(attr->ia_gid, inode->i_gid))) { |
1179 | /* | 1180 | /* |
1180 | * Gather pointers to quota structures so that allocation / | 1181 | * Gather pointers to quota structures so that allocation / |
1181 | * freeing of quota structures happens here and not inside | 1182 | * freeing of quota structures happens here and not inside |
1182 | * dquot_transfer() where we have problems with lock ordering | 1183 | * dquot_transfer() where we have problems with lock ordering |
1183 | */ | 1184 | */ |
1184 | if (attr->ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid | 1185 | if (attr->ia_valid & ATTR_UID && !uid_eq(attr->ia_uid, inode->i_uid) |
1185 | && OCFS2_HAS_RO_COMPAT_FEATURE(sb, | 1186 | && OCFS2_HAS_RO_COMPAT_FEATURE(sb, |
1186 | OCFS2_FEATURE_RO_COMPAT_USRQUOTA)) { | 1187 | OCFS2_FEATURE_RO_COMPAT_USRQUOTA)) { |
1187 | transfer_to[USRQUOTA] = dqget(sb, make_kqid_uid(attr->ia_uid)); | 1188 | transfer_to[USRQUOTA] = dqget(sb, make_kqid_uid(attr->ia_uid)); |
@@ -1190,7 +1191,7 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) | |||
1190 | goto bail_unlock; | 1191 | goto bail_unlock; |
1191 | } | 1192 | } |
1192 | } | 1193 | } |
1193 | if (attr->ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid | 1194 | if (attr->ia_valid & ATTR_GID && !gid_eq(attr->ia_gid, inode->i_gid) |
1194 | && OCFS2_HAS_RO_COMPAT_FEATURE(sb, | 1195 | && OCFS2_HAS_RO_COMPAT_FEATURE(sb, |
1195 | OCFS2_FEATURE_RO_COMPAT_GRPQUOTA)) { | 1196 | OCFS2_FEATURE_RO_COMPAT_GRPQUOTA)) { |
1196 | transfer_to[GRPQUOTA] = dqget(sb, make_kqid_gid(attr->ia_gid)); | 1197 | transfer_to[GRPQUOTA] = dqget(sb, make_kqid_gid(attr->ia_gid)); |
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index d89e08a81eda..f87f9bd1edff 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c | |||
@@ -269,8 +269,8 @@ void ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe, | |||
269 | inode->i_generation = le32_to_cpu(fe->i_generation); | 269 | inode->i_generation = le32_to_cpu(fe->i_generation); |
270 | inode->i_rdev = huge_decode_dev(le64_to_cpu(fe->id1.dev1.i_rdev)); | 270 | inode->i_rdev = huge_decode_dev(le64_to_cpu(fe->id1.dev1.i_rdev)); |
271 | inode->i_mode = le16_to_cpu(fe->i_mode); | 271 | inode->i_mode = le16_to_cpu(fe->i_mode); |
272 | inode->i_uid = le32_to_cpu(fe->i_uid); | 272 | i_uid_write(inode, le32_to_cpu(fe->i_uid)); |
273 | inode->i_gid = le32_to_cpu(fe->i_gid); | 273 | i_gid_write(inode, le32_to_cpu(fe->i_gid)); |
274 | 274 | ||
275 | /* Fast symlinks will have i_size but no allocated clusters. */ | 275 | /* Fast symlinks will have i_size but no allocated clusters. */ |
276 | if (S_ISLNK(inode->i_mode) && !fe->i_clusters) { | 276 | if (S_ISLNK(inode->i_mode) && !fe->i_clusters) { |
@@ -1259,8 +1259,8 @@ int ocfs2_mark_inode_dirty(handle_t *handle, | |||
1259 | 1259 | ||
1260 | fe->i_size = cpu_to_le64(i_size_read(inode)); | 1260 | fe->i_size = cpu_to_le64(i_size_read(inode)); |
1261 | ocfs2_set_links_count(fe, inode->i_nlink); | 1261 | ocfs2_set_links_count(fe, inode->i_nlink); |
1262 | fe->i_uid = cpu_to_le32(inode->i_uid); | 1262 | fe->i_uid = cpu_to_le32(i_uid_read(inode)); |
1263 | fe->i_gid = cpu_to_le32(inode->i_gid); | 1263 | fe->i_gid = cpu_to_le32(i_gid_read(inode)); |
1264 | fe->i_mode = cpu_to_le16(inode->i_mode); | 1264 | fe->i_mode = cpu_to_le16(inode->i_mode); |
1265 | fe->i_atime = cpu_to_le64(inode->i_atime.tv_sec); | 1265 | fe->i_atime = cpu_to_le64(inode->i_atime.tv_sec); |
1266 | fe->i_atime_nsec = cpu_to_le32(inode->i_atime.tv_nsec); | 1266 | fe->i_atime_nsec = cpu_to_le32(inode->i_atime.tv_nsec); |
@@ -1290,8 +1290,8 @@ void ocfs2_refresh_inode(struct inode *inode, | |||
1290 | ocfs2_set_inode_flags(inode); | 1290 | ocfs2_set_inode_flags(inode); |
1291 | i_size_write(inode, le64_to_cpu(fe->i_size)); | 1291 | i_size_write(inode, le64_to_cpu(fe->i_size)); |
1292 | set_nlink(inode, ocfs2_read_links_count(fe)); | 1292 | set_nlink(inode, ocfs2_read_links_count(fe)); |
1293 | inode->i_uid = le32_to_cpu(fe->i_uid); | 1293 | i_uid_write(inode, le32_to_cpu(fe->i_uid)); |
1294 | inode->i_gid = le32_to_cpu(fe->i_gid); | 1294 | i_gid_write(inode, le32_to_cpu(fe->i_gid)); |
1295 | inode->i_mode = le16_to_cpu(fe->i_mode); | 1295 | inode->i_mode = le16_to_cpu(fe->i_mode); |
1296 | if (S_ISLNK(inode->i_mode) && le32_to_cpu(fe->i_clusters) == 0) | 1296 | if (S_ISLNK(inode->i_mode) && le32_to_cpu(fe->i_clusters) == 0) |
1297 | inode->i_blocks = 0; | 1297 | inode->i_blocks = 0; |
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index f1fd0741162b..04ee1b57c243 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c | |||
@@ -512,8 +512,8 @@ static int __ocfs2_mknod_locked(struct inode *dir, | |||
512 | fe->i_suballoc_loc = cpu_to_le64(suballoc_loc); | 512 | fe->i_suballoc_loc = cpu_to_le64(suballoc_loc); |
513 | fe->i_suballoc_bit = cpu_to_le16(suballoc_bit); | 513 | fe->i_suballoc_bit = cpu_to_le16(suballoc_bit); |
514 | fe->i_suballoc_slot = cpu_to_le16(inode_ac->ac_alloc_slot); | 514 | fe->i_suballoc_slot = cpu_to_le16(inode_ac->ac_alloc_slot); |
515 | fe->i_uid = cpu_to_le32(inode->i_uid); | 515 | fe->i_uid = cpu_to_le32(i_uid_read(inode)); |
516 | fe->i_gid = cpu_to_le32(inode->i_gid); | 516 | fe->i_gid = cpu_to_le32(i_gid_read(inode)); |
517 | fe->i_mode = cpu_to_le16(inode->i_mode); | 517 | fe->i_mode = cpu_to_le16(inode->i_mode); |
518 | if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) | 518 | if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) |
519 | fe->id1.dev1.i_rdev = cpu_to_le64(huge_encode_dev(dev)); | 519 | fe->id1.dev1.i_rdev = cpu_to_le64(huge_encode_dev(dev)); |
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c index 30a055049e16..934a4ac3e7fc 100644 --- a/fs/ocfs2/refcounttree.c +++ b/fs/ocfs2/refcounttree.c | |||
@@ -4407,7 +4407,7 @@ static int ocfs2_vfs_reflink(struct dentry *old_dentry, struct inode *dir, | |||
4407 | * rights to do so. | 4407 | * rights to do so. |
4408 | */ | 4408 | */ |
4409 | if (preserve) { | 4409 | if (preserve) { |
4410 | if ((current_fsuid() != inode->i_uid) && !capable(CAP_CHOWN)) | 4410 | if (!uid_eq(current_fsuid(), inode->i_uid) && !capable(CAP_CHOWN)) |
4411 | return -EPERM; | 4411 | return -EPERM; |
4412 | if (!in_group_p(inode->i_gid) && !capable(CAP_CHOWN)) | 4412 | if (!in_group_p(inode->i_gid) && !capable(CAP_CHOWN)) |
4413 | return -EPERM; | 4413 | return -EPERM; |
diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c index eab8c09d3801..c24f1e10b946 100644 --- a/fs/ramfs/inode.c +++ b/fs/ramfs/inode.c | |||
@@ -260,6 +260,7 @@ static struct file_system_type ramfs_fs_type = { | |||
260 | .name = "ramfs", | 260 | .name = "ramfs", |
261 | .mount = ramfs_mount, | 261 | .mount = ramfs_mount, |
262 | .kill_sb = ramfs_kill_sb, | 262 | .kill_sb = ramfs_kill_sb, |
263 | .fs_flags = FS_USERNS_MOUNT, | ||
263 | }; | 264 | }; |
264 | static struct file_system_type rootfs_fs_type = { | 265 | static struct file_system_type rootfs_fs_type = { |
265 | .name = "rootfs", | 266 | .name = "rootfs", |