diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/9p/client.c | 43 | ||||
-rw-r--r-- | net/9p/protocol.c | 49 | ||||
-rw-r--r-- | net/ceph/ceph_common.c | 5 | ||||
-rw-r--r-- | net/sunrpc/auth.c | 6 | ||||
-rw-r--r-- | net/sunrpc/auth_generic.c | 16 | ||||
-rw-r--r-- | net/sunrpc/auth_gss/auth_gss.c | 45 | ||||
-rw-r--r-- | net/sunrpc/auth_gss/svcauth_gss.c | 18 | ||||
-rw-r--r-- | net/sunrpc/auth_unix.c | 36 | ||||
-rw-r--r-- | net/sunrpc/svcauth_unix.c | 43 |
9 files changed, 170 insertions, 91 deletions
diff --git a/net/9p/client.c b/net/9p/client.c index 34d417670935..8eb75425e6e6 100644 --- a/net/9p/client.c +++ b/net/9p/client.c | |||
@@ -1100,7 +1100,7 @@ void p9_client_begin_disconnect(struct p9_client *clnt) | |||
1100 | EXPORT_SYMBOL(p9_client_begin_disconnect); | 1100 | EXPORT_SYMBOL(p9_client_begin_disconnect); |
1101 | 1101 | ||
1102 | struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid, | 1102 | struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid, |
1103 | char *uname, u32 n_uname, char *aname) | 1103 | char *uname, kuid_t n_uname, char *aname) |
1104 | { | 1104 | { |
1105 | int err = 0; | 1105 | int err = 0; |
1106 | struct p9_req_t *req; | 1106 | struct p9_req_t *req; |
@@ -1117,7 +1117,7 @@ struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid, | |||
1117 | goto error; | 1117 | goto error; |
1118 | } | 1118 | } |
1119 | 1119 | ||
1120 | req = p9_client_rpc(clnt, P9_TATTACH, "ddss?d", fid->fid, | 1120 | req = p9_client_rpc(clnt, P9_TATTACH, "ddss?u", fid->fid, |
1121 | afid ? afid->fid : P9_NOFID, uname, aname, n_uname); | 1121 | afid ? afid->fid : P9_NOFID, uname, aname, n_uname); |
1122 | if (IS_ERR(req)) { | 1122 | if (IS_ERR(req)) { |
1123 | err = PTR_ERR(req); | 1123 | err = PTR_ERR(req); |
@@ -1270,7 +1270,7 @@ error: | |||
1270 | EXPORT_SYMBOL(p9_client_open); | 1270 | EXPORT_SYMBOL(p9_client_open); |
1271 | 1271 | ||
1272 | int p9_client_create_dotl(struct p9_fid *ofid, char *name, u32 flags, u32 mode, | 1272 | int p9_client_create_dotl(struct p9_fid *ofid, char *name, u32 flags, u32 mode, |
1273 | gid_t gid, struct p9_qid *qid) | 1273 | kgid_t gid, struct p9_qid *qid) |
1274 | { | 1274 | { |
1275 | int err = 0; | 1275 | int err = 0; |
1276 | struct p9_client *clnt; | 1276 | struct p9_client *clnt; |
@@ -1279,13 +1279,14 @@ int p9_client_create_dotl(struct p9_fid *ofid, char *name, u32 flags, u32 mode, | |||
1279 | 1279 | ||
1280 | p9_debug(P9_DEBUG_9P, | 1280 | p9_debug(P9_DEBUG_9P, |
1281 | ">>> TLCREATE fid %d name %s flags %d mode %d gid %d\n", | 1281 | ">>> TLCREATE fid %d name %s flags %d mode %d gid %d\n", |
1282 | ofid->fid, name, flags, mode, gid); | 1282 | ofid->fid, name, flags, mode, |
1283 | from_kgid(&init_user_ns, gid)); | ||
1283 | clnt = ofid->clnt; | 1284 | clnt = ofid->clnt; |
1284 | 1285 | ||
1285 | if (ofid->mode != -1) | 1286 | if (ofid->mode != -1) |
1286 | return -EINVAL; | 1287 | return -EINVAL; |
1287 | 1288 | ||
1288 | req = p9_client_rpc(clnt, P9_TLCREATE, "dsddd", ofid->fid, name, flags, | 1289 | req = p9_client_rpc(clnt, P9_TLCREATE, "dsddg", ofid->fid, name, flags, |
1289 | mode, gid); | 1290 | mode, gid); |
1290 | if (IS_ERR(req)) { | 1291 | if (IS_ERR(req)) { |
1291 | err = PTR_ERR(req); | 1292 | err = PTR_ERR(req); |
@@ -1358,7 +1359,7 @@ error: | |||
1358 | } | 1359 | } |
1359 | EXPORT_SYMBOL(p9_client_fcreate); | 1360 | EXPORT_SYMBOL(p9_client_fcreate); |
1360 | 1361 | ||
1361 | int p9_client_symlink(struct p9_fid *dfid, char *name, char *symtgt, gid_t gid, | 1362 | int p9_client_symlink(struct p9_fid *dfid, char *name, char *symtgt, kgid_t gid, |
1362 | struct p9_qid *qid) | 1363 | struct p9_qid *qid) |
1363 | { | 1364 | { |
1364 | int err = 0; | 1365 | int err = 0; |
@@ -1369,7 +1370,7 @@ int p9_client_symlink(struct p9_fid *dfid, char *name, char *symtgt, gid_t gid, | |||
1369 | dfid->fid, name, symtgt); | 1370 | dfid->fid, name, symtgt); |
1370 | clnt = dfid->clnt; | 1371 | clnt = dfid->clnt; |
1371 | 1372 | ||
1372 | req = p9_client_rpc(clnt, P9_TSYMLINK, "dssd", dfid->fid, name, symtgt, | 1373 | req = p9_client_rpc(clnt, P9_TSYMLINK, "dssg", dfid->fid, name, symtgt, |
1373 | gid); | 1374 | gid); |
1374 | if (IS_ERR(req)) { | 1375 | if (IS_ERR(req)) { |
1375 | err = PTR_ERR(req); | 1376 | err = PTR_ERR(req); |
@@ -1710,7 +1711,9 @@ struct p9_wstat *p9_client_stat(struct p9_fid *fid) | |||
1710 | (unsigned long long)ret->qid.path, ret->qid.version, ret->mode, | 1711 | (unsigned long long)ret->qid.path, ret->qid.version, ret->mode, |
1711 | ret->atime, ret->mtime, (unsigned long long)ret->length, | 1712 | ret->atime, ret->mtime, (unsigned long long)ret->length, |
1712 | ret->name, ret->uid, ret->gid, ret->muid, ret->extension, | 1713 | ret->name, ret->uid, ret->gid, ret->muid, ret->extension, |
1713 | ret->n_uid, ret->n_gid, ret->n_muid); | 1714 | from_kuid(&init_user_ns, ret->n_uid), |
1715 | from_kgid(&init_user_ns, ret->n_gid), | ||
1716 | from_kuid(&init_user_ns, ret->n_muid)); | ||
1714 | 1717 | ||
1715 | p9_free_req(clnt, req); | 1718 | p9_free_req(clnt, req); |
1716 | return ret; | 1719 | return ret; |
@@ -1764,8 +1767,10 @@ struct p9_stat_dotl *p9_client_getattr_dotl(struct p9_fid *fid, | |||
1764 | "<<< st_btime_sec=%lld st_btime_nsec=%lld\n" | 1767 | "<<< st_btime_sec=%lld st_btime_nsec=%lld\n" |
1765 | "<<< st_gen=%lld st_data_version=%lld", | 1768 | "<<< st_gen=%lld st_data_version=%lld", |
1766 | ret->st_result_mask, ret->qid.type, ret->qid.path, | 1769 | ret->st_result_mask, ret->qid.type, ret->qid.path, |
1767 | ret->qid.version, ret->st_mode, ret->st_nlink, ret->st_uid, | 1770 | ret->qid.version, ret->st_mode, ret->st_nlink, |
1768 | ret->st_gid, ret->st_rdev, ret->st_size, ret->st_blksize, | 1771 | from_kuid(&init_user_ns, ret->st_uid), |
1772 | from_kgid(&init_user_ns, ret->st_gid), | ||
1773 | ret->st_rdev, ret->st_size, ret->st_blksize, | ||
1769 | ret->st_blocks, ret->st_atime_sec, ret->st_atime_nsec, | 1774 | ret->st_blocks, ret->st_atime_sec, ret->st_atime_nsec, |
1770 | ret->st_mtime_sec, ret->st_mtime_nsec, ret->st_ctime_sec, | 1775 | ret->st_mtime_sec, ret->st_mtime_nsec, ret->st_ctime_sec, |
1771 | ret->st_ctime_nsec, ret->st_btime_sec, ret->st_btime_nsec, | 1776 | ret->st_ctime_nsec, ret->st_btime_sec, ret->st_btime_nsec, |
@@ -1828,7 +1833,9 @@ int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst) | |||
1828 | (unsigned long long)wst->qid.path, wst->qid.version, wst->mode, | 1833 | (unsigned long long)wst->qid.path, wst->qid.version, wst->mode, |
1829 | wst->atime, wst->mtime, (unsigned long long)wst->length, | 1834 | wst->atime, wst->mtime, (unsigned long long)wst->length, |
1830 | wst->name, wst->uid, wst->gid, wst->muid, wst->extension, | 1835 | wst->name, wst->uid, wst->gid, wst->muid, wst->extension, |
1831 | wst->n_uid, wst->n_gid, wst->n_muid); | 1836 | from_kuid(&init_user_ns, wst->n_uid), |
1837 | from_kgid(&init_user_ns, wst->n_gid), | ||
1838 | from_kuid(&init_user_ns, wst->n_muid)); | ||
1832 | 1839 | ||
1833 | req = p9_client_rpc(clnt, P9_TWSTAT, "dwS", fid->fid, wst->size+2, wst); | 1840 | req = p9_client_rpc(clnt, P9_TWSTAT, "dwS", fid->fid, wst->size+2, wst); |
1834 | if (IS_ERR(req)) { | 1841 | if (IS_ERR(req)) { |
@@ -1857,7 +1864,9 @@ int p9_client_setattr(struct p9_fid *fid, struct p9_iattr_dotl *p9attr) | |||
1857 | " valid=%x mode=%x uid=%d gid=%d size=%lld\n" | 1864 | " valid=%x mode=%x uid=%d gid=%d size=%lld\n" |
1858 | " atime_sec=%lld atime_nsec=%lld\n" | 1865 | " atime_sec=%lld atime_nsec=%lld\n" |
1859 | " mtime_sec=%lld mtime_nsec=%lld\n", | 1866 | " mtime_sec=%lld mtime_nsec=%lld\n", |
1860 | p9attr->valid, p9attr->mode, p9attr->uid, p9attr->gid, | 1867 | p9attr->valid, p9attr->mode, |
1868 | from_kuid(&init_user_ns, p9attr->uid), | ||
1869 | from_kgid(&init_user_ns, p9attr->gid), | ||
1861 | p9attr->size, p9attr->atime_sec, p9attr->atime_nsec, | 1870 | p9attr->size, p9attr->atime_sec, p9attr->atime_nsec, |
1862 | p9attr->mtime_sec, p9attr->mtime_nsec); | 1871 | p9attr->mtime_sec, p9attr->mtime_nsec); |
1863 | 1872 | ||
@@ -2106,7 +2115,7 @@ error: | |||
2106 | EXPORT_SYMBOL(p9_client_readdir); | 2115 | EXPORT_SYMBOL(p9_client_readdir); |
2107 | 2116 | ||
2108 | int p9_client_mknod_dotl(struct p9_fid *fid, char *name, int mode, | 2117 | int p9_client_mknod_dotl(struct p9_fid *fid, char *name, int mode, |
2109 | dev_t rdev, gid_t gid, struct p9_qid *qid) | 2118 | dev_t rdev, kgid_t gid, struct p9_qid *qid) |
2110 | { | 2119 | { |
2111 | int err; | 2120 | int err; |
2112 | struct p9_client *clnt; | 2121 | struct p9_client *clnt; |
@@ -2116,7 +2125,7 @@ int p9_client_mknod_dotl(struct p9_fid *fid, char *name, int mode, | |||
2116 | clnt = fid->clnt; | 2125 | clnt = fid->clnt; |
2117 | p9_debug(P9_DEBUG_9P, ">>> TMKNOD fid %d name %s mode %d major %d " | 2126 | p9_debug(P9_DEBUG_9P, ">>> TMKNOD fid %d name %s mode %d major %d " |
2118 | "minor %d\n", fid->fid, name, mode, MAJOR(rdev), MINOR(rdev)); | 2127 | "minor %d\n", fid->fid, name, mode, MAJOR(rdev), MINOR(rdev)); |
2119 | req = p9_client_rpc(clnt, P9_TMKNOD, "dsdddd", fid->fid, name, mode, | 2128 | req = p9_client_rpc(clnt, P9_TMKNOD, "dsdddg", fid->fid, name, mode, |
2120 | MAJOR(rdev), MINOR(rdev), gid); | 2129 | MAJOR(rdev), MINOR(rdev), gid); |
2121 | if (IS_ERR(req)) | 2130 | if (IS_ERR(req)) |
2122 | return PTR_ERR(req); | 2131 | return PTR_ERR(req); |
@@ -2137,7 +2146,7 @@ error: | |||
2137 | EXPORT_SYMBOL(p9_client_mknod_dotl); | 2146 | EXPORT_SYMBOL(p9_client_mknod_dotl); |
2138 | 2147 | ||
2139 | int p9_client_mkdir_dotl(struct p9_fid *fid, char *name, int mode, | 2148 | int p9_client_mkdir_dotl(struct p9_fid *fid, char *name, int mode, |
2140 | gid_t gid, struct p9_qid *qid) | 2149 | kgid_t gid, struct p9_qid *qid) |
2141 | { | 2150 | { |
2142 | int err; | 2151 | int err; |
2143 | struct p9_client *clnt; | 2152 | struct p9_client *clnt; |
@@ -2146,8 +2155,8 @@ int p9_client_mkdir_dotl(struct p9_fid *fid, char *name, int mode, | |||
2146 | err = 0; | 2155 | err = 0; |
2147 | clnt = fid->clnt; | 2156 | clnt = fid->clnt; |
2148 | p9_debug(P9_DEBUG_9P, ">>> TMKDIR fid %d name %s mode %d gid %d\n", | 2157 | p9_debug(P9_DEBUG_9P, ">>> TMKDIR fid %d name %s mode %d gid %d\n", |
2149 | fid->fid, name, mode, gid); | 2158 | fid->fid, name, mode, from_kgid(&init_user_ns, gid)); |
2150 | req = p9_client_rpc(clnt, P9_TMKDIR, "dsdd", fid->fid, name, mode, | 2159 | req = p9_client_rpc(clnt, P9_TMKDIR, "dsdg", fid->fid, name, mode, |
2151 | gid); | 2160 | gid); |
2152 | if (IS_ERR(req)) | 2161 | if (IS_ERR(req)) |
2153 | return PTR_ERR(req); | 2162 | return PTR_ERR(req); |
diff --git a/net/9p/protocol.c b/net/9p/protocol.c index 3d33ecf13327..ab9127ec5b7a 100644 --- a/net/9p/protocol.c +++ b/net/9p/protocol.c | |||
@@ -85,6 +85,8 @@ pdu_write_u(struct p9_fcall *pdu, const char __user *udata, size_t size) | |||
85 | d - int32_t | 85 | d - int32_t |
86 | q - int64_t | 86 | q - int64_t |
87 | s - string | 87 | s - string |
88 | u - numeric uid | ||
89 | g - numeric gid | ||
88 | S - stat | 90 | S - stat |
89 | Q - qid | 91 | Q - qid |
90 | D - data blob (int32_t size followed by void *, results are not freed) | 92 | D - data blob (int32_t size followed by void *, results are not freed) |
@@ -163,6 +165,26 @@ p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt, | |||
163 | (*sptr)[len] = 0; | 165 | (*sptr)[len] = 0; |
164 | } | 166 | } |
165 | break; | 167 | break; |
168 | case 'u': { | ||
169 | kuid_t *uid = va_arg(ap, kuid_t *); | ||
170 | __le32 le_val; | ||
171 | if (pdu_read(pdu, &le_val, sizeof(le_val))) { | ||
172 | errcode = -EFAULT; | ||
173 | break; | ||
174 | } | ||
175 | *uid = make_kuid(&init_user_ns, | ||
176 | le32_to_cpu(le_val)); | ||
177 | } break; | ||
178 | case 'g': { | ||
179 | kgid_t *gid = va_arg(ap, kgid_t *); | ||
180 | __le32 le_val; | ||
181 | if (pdu_read(pdu, &le_val, sizeof(le_val))) { | ||
182 | errcode = -EFAULT; | ||
183 | break; | ||
184 | } | ||
185 | *gid = make_kgid(&init_user_ns, | ||
186 | le32_to_cpu(le_val)); | ||
187 | } break; | ||
166 | case 'Q':{ | 188 | case 'Q':{ |
167 | struct p9_qid *qid = | 189 | struct p9_qid *qid = |
168 | va_arg(ap, struct p9_qid *); | 190 | va_arg(ap, struct p9_qid *); |
@@ -177,11 +199,12 @@ p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt, | |||
177 | va_arg(ap, struct p9_wstat *); | 199 | va_arg(ap, struct p9_wstat *); |
178 | 200 | ||
179 | memset(stbuf, 0, sizeof(struct p9_wstat)); | 201 | memset(stbuf, 0, sizeof(struct p9_wstat)); |
180 | stbuf->n_uid = stbuf->n_gid = stbuf->n_muid = | 202 | stbuf->n_uid = stbuf->n_muid = INVALID_UID; |
181 | -1; | 203 | stbuf->n_gid = INVALID_GID; |
204 | |||
182 | errcode = | 205 | errcode = |
183 | p9pdu_readf(pdu, proto_version, | 206 | p9pdu_readf(pdu, proto_version, |
184 | "wwdQdddqssss?sddd", | 207 | "wwdQdddqssss?sugu", |
185 | &stbuf->size, &stbuf->type, | 208 | &stbuf->size, &stbuf->type, |
186 | &stbuf->dev, &stbuf->qid, | 209 | &stbuf->dev, &stbuf->qid, |
187 | &stbuf->mode, &stbuf->atime, | 210 | &stbuf->mode, &stbuf->atime, |
@@ -294,7 +317,7 @@ p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt, | |||
294 | memset(stbuf, 0, sizeof(struct p9_stat_dotl)); | 317 | memset(stbuf, 0, sizeof(struct p9_stat_dotl)); |
295 | errcode = | 318 | errcode = |
296 | p9pdu_readf(pdu, proto_version, | 319 | p9pdu_readf(pdu, proto_version, |
297 | "qQdddqqqqqqqqqqqqqqq", | 320 | "qQdugqqqqqqqqqqqqqqq", |
298 | &stbuf->st_result_mask, | 321 | &stbuf->st_result_mask, |
299 | &stbuf->qid, | 322 | &stbuf->qid, |
300 | &stbuf->st_mode, | 323 | &stbuf->st_mode, |
@@ -377,6 +400,20 @@ p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt, | |||
377 | errcode = -EFAULT; | 400 | errcode = -EFAULT; |
378 | } | 401 | } |
379 | break; | 402 | break; |
403 | case 'u': { | ||
404 | kuid_t uid = va_arg(ap, kuid_t); | ||
405 | __le32 val = cpu_to_le32( | ||
406 | from_kuid(&init_user_ns, uid)); | ||
407 | if (pdu_write(pdu, &val, sizeof(val))) | ||
408 | errcode = -EFAULT; | ||
409 | } break; | ||
410 | case 'g': { | ||
411 | kgid_t gid = va_arg(ap, kgid_t); | ||
412 | __le32 val = cpu_to_le32( | ||
413 | from_kgid(&init_user_ns, gid)); | ||
414 | if (pdu_write(pdu, &val, sizeof(val))) | ||
415 | errcode = -EFAULT; | ||
416 | } break; | ||
380 | case 'Q':{ | 417 | case 'Q':{ |
381 | const struct p9_qid *qid = | 418 | const struct p9_qid *qid = |
382 | va_arg(ap, const struct p9_qid *); | 419 | va_arg(ap, const struct p9_qid *); |
@@ -390,7 +427,7 @@ p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt, | |||
390 | va_arg(ap, const struct p9_wstat *); | 427 | va_arg(ap, const struct p9_wstat *); |
391 | errcode = | 428 | errcode = |
392 | p9pdu_writef(pdu, proto_version, | 429 | p9pdu_writef(pdu, proto_version, |
393 | "wwdQdddqssss?sddd", | 430 | "wwdQdddqssss?sugu", |
394 | stbuf->size, stbuf->type, | 431 | stbuf->size, stbuf->type, |
395 | stbuf->dev, &stbuf->qid, | 432 | stbuf->dev, &stbuf->qid, |
396 | stbuf->mode, stbuf->atime, | 433 | stbuf->mode, stbuf->atime, |
@@ -468,7 +505,7 @@ p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt, | |||
468 | struct p9_iattr_dotl *); | 505 | struct p9_iattr_dotl *); |
469 | 506 | ||
470 | errcode = p9pdu_writef(pdu, proto_version, | 507 | errcode = p9pdu_writef(pdu, proto_version, |
471 | "ddddqqqqq", | 508 | "ddugqqqqq", |
472 | p9attr->valid, | 509 | p9attr->valid, |
473 | p9attr->mode, | 510 | p9attr->mode, |
474 | p9attr->uid, | 511 | p9attr->uid, |
diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c index ee71ea26777a..1deb29af82fd 100644 --- a/net/ceph/ceph_common.c +++ b/net/ceph/ceph_common.c | |||
@@ -15,6 +15,8 @@ | |||
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/statfs.h> | 16 | #include <linux/statfs.h> |
17 | #include <linux/string.h> | 17 | #include <linux/string.h> |
18 | #include <linux/nsproxy.h> | ||
19 | #include <net/net_namespace.h> | ||
18 | 20 | ||
19 | 21 | ||
20 | #include <linux/ceph/ceph_features.h> | 22 | #include <linux/ceph/ceph_features.h> |
@@ -292,6 +294,9 @@ ceph_parse_options(char *options, const char *dev_name, | |||
292 | int err = -ENOMEM; | 294 | int err = -ENOMEM; |
293 | substring_t argstr[MAX_OPT_ARGS]; | 295 | substring_t argstr[MAX_OPT_ARGS]; |
294 | 296 | ||
297 | if (current->nsproxy->net_ns != &init_net) | ||
298 | return ERR_PTR(-EINVAL); | ||
299 | |||
295 | opt = kzalloc(sizeof(*opt), GFP_KERNEL); | 300 | opt = kzalloc(sizeof(*opt), GFP_KERNEL); |
296 | if (!opt) | 301 | if (!opt) |
297 | return ERR_PTR(-ENOMEM); | 302 | return ERR_PTR(-ENOMEM); |
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index b5c067bccc45..392adc41e2e5 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c | |||
@@ -412,7 +412,7 @@ rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred, | |||
412 | *entry, *new; | 412 | *entry, *new; |
413 | unsigned int nr; | 413 | unsigned int nr; |
414 | 414 | ||
415 | nr = hash_long(acred->uid, cache->hashbits); | 415 | nr = hash_long(from_kuid(&init_user_ns, acred->uid), cache->hashbits); |
416 | 416 | ||
417 | rcu_read_lock(); | 417 | rcu_read_lock(); |
418 | hlist_for_each_entry_rcu(entry, pos, &cache->hashtable[nr], cr_hash) { | 418 | hlist_for_each_entry_rcu(entry, pos, &cache->hashtable[nr], cr_hash) { |
@@ -519,8 +519,8 @@ rpcauth_bind_root_cred(struct rpc_task *task, int lookupflags) | |||
519 | { | 519 | { |
520 | struct rpc_auth *auth = task->tk_client->cl_auth; | 520 | struct rpc_auth *auth = task->tk_client->cl_auth; |
521 | struct auth_cred acred = { | 521 | struct auth_cred acred = { |
522 | .uid = 0, | 522 | .uid = GLOBAL_ROOT_UID, |
523 | .gid = 0, | 523 | .gid = GLOBAL_ROOT_GID, |
524 | }; | 524 | }; |
525 | 525 | ||
526 | dprintk("RPC: %5u looking up %s cred\n", | 526 | dprintk("RPC: %5u looking up %s cred\n", |
diff --git a/net/sunrpc/auth_generic.c b/net/sunrpc/auth_generic.c index 6ed6f201b022..b6badafc6494 100644 --- a/net/sunrpc/auth_generic.c +++ b/net/sunrpc/auth_generic.c | |||
@@ -18,8 +18,8 @@ | |||
18 | # define RPCDBG_FACILITY RPCDBG_AUTH | 18 | # define RPCDBG_FACILITY RPCDBG_AUTH |
19 | #endif | 19 | #endif |
20 | 20 | ||
21 | #define RPC_MACHINE_CRED_USERID ((uid_t)0) | 21 | #define RPC_MACHINE_CRED_USERID GLOBAL_ROOT_UID |
22 | #define RPC_MACHINE_CRED_GROUPID ((gid_t)0) | 22 | #define RPC_MACHINE_CRED_GROUPID GLOBAL_ROOT_GID |
23 | 23 | ||
24 | struct generic_cred { | 24 | struct generic_cred { |
25 | struct rpc_cred gc_base; | 25 | struct rpc_cred gc_base; |
@@ -96,7 +96,9 @@ generic_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) | |||
96 | 96 | ||
97 | dprintk("RPC: allocated %s cred %p for uid %d gid %d\n", | 97 | dprintk("RPC: allocated %s cred %p for uid %d gid %d\n", |
98 | gcred->acred.machine_cred ? "machine" : "generic", | 98 | gcred->acred.machine_cred ? "machine" : "generic", |
99 | gcred, acred->uid, acred->gid); | 99 | gcred, |
100 | from_kuid(&init_user_ns, acred->uid), | ||
101 | from_kgid(&init_user_ns, acred->gid)); | ||
100 | return &gcred->gc_base; | 102 | return &gcred->gc_base; |
101 | } | 103 | } |
102 | 104 | ||
@@ -129,8 +131,8 @@ machine_cred_match(struct auth_cred *acred, struct generic_cred *gcred, int flag | |||
129 | { | 131 | { |
130 | if (!gcred->acred.machine_cred || | 132 | if (!gcred->acred.machine_cred || |
131 | gcred->acred.principal != acred->principal || | 133 | gcred->acred.principal != acred->principal || |
132 | gcred->acred.uid != acred->uid || | 134 | !uid_eq(gcred->acred.uid, acred->uid) || |
133 | gcred->acred.gid != acred->gid) | 135 | !gid_eq(gcred->acred.gid, acred->gid)) |
134 | return 0; | 136 | return 0; |
135 | return 1; | 137 | return 1; |
136 | } | 138 | } |
@@ -147,8 +149,8 @@ generic_match(struct auth_cred *acred, struct rpc_cred *cred, int flags) | |||
147 | if (acred->machine_cred) | 149 | if (acred->machine_cred) |
148 | return machine_cred_match(acred, gcred, flags); | 150 | return machine_cred_match(acred, gcred, flags); |
149 | 151 | ||
150 | if (gcred->acred.uid != acred->uid || | 152 | if (!uid_eq(gcred->acred.uid, acred->uid) || |
151 | gcred->acred.gid != acred->gid || | 153 | !gid_eq(gcred->acred.gid, acred->gid) || |
152 | gcred->acred.machine_cred != 0) | 154 | gcred->acred.machine_cred != 0) |
153 | goto out_nomatch; | 155 | goto out_nomatch; |
154 | 156 | ||
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 911ef008b701..6ea29f4ed6c0 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
@@ -255,7 +255,7 @@ err: | |||
255 | 255 | ||
256 | struct gss_upcall_msg { | 256 | struct gss_upcall_msg { |
257 | atomic_t count; | 257 | atomic_t count; |
258 | uid_t uid; | 258 | kuid_t uid; |
259 | struct rpc_pipe_msg msg; | 259 | struct rpc_pipe_msg msg; |
260 | struct list_head list; | 260 | struct list_head list; |
261 | struct gss_auth *auth; | 261 | struct gss_auth *auth; |
@@ -302,11 +302,11 @@ gss_release_msg(struct gss_upcall_msg *gss_msg) | |||
302 | } | 302 | } |
303 | 303 | ||
304 | static struct gss_upcall_msg * | 304 | static struct gss_upcall_msg * |
305 | __gss_find_upcall(struct rpc_pipe *pipe, uid_t uid) | 305 | __gss_find_upcall(struct rpc_pipe *pipe, kuid_t uid) |
306 | { | 306 | { |
307 | struct gss_upcall_msg *pos; | 307 | struct gss_upcall_msg *pos; |
308 | list_for_each_entry(pos, &pipe->in_downcall, list) { | 308 | list_for_each_entry(pos, &pipe->in_downcall, list) { |
309 | if (pos->uid != uid) | 309 | if (!uid_eq(pos->uid, uid)) |
310 | continue; | 310 | continue; |
311 | atomic_inc(&pos->count); | 311 | atomic_inc(&pos->count); |
312 | dprintk("RPC: %s found msg %p\n", __func__, pos); | 312 | dprintk("RPC: %s found msg %p\n", __func__, pos); |
@@ -394,8 +394,11 @@ gss_upcall_callback(struct rpc_task *task) | |||
394 | 394 | ||
395 | static void gss_encode_v0_msg(struct gss_upcall_msg *gss_msg) | 395 | static void gss_encode_v0_msg(struct gss_upcall_msg *gss_msg) |
396 | { | 396 | { |
397 | gss_msg->msg.data = &gss_msg->uid; | 397 | uid_t uid = from_kuid(&init_user_ns, gss_msg->uid); |
398 | gss_msg->msg.len = sizeof(gss_msg->uid); | 398 | memcpy(gss_msg->databuf, &uid, sizeof(uid)); |
399 | gss_msg->msg.data = gss_msg->databuf; | ||
400 | gss_msg->msg.len = sizeof(uid); | ||
401 | BUG_ON(sizeof(uid) > UPCALL_BUF_LEN); | ||
399 | } | 402 | } |
400 | 403 | ||
401 | static void gss_encode_v1_msg(struct gss_upcall_msg *gss_msg, | 404 | static void gss_encode_v1_msg(struct gss_upcall_msg *gss_msg, |
@@ -408,7 +411,7 @@ static void gss_encode_v1_msg(struct gss_upcall_msg *gss_msg, | |||
408 | 411 | ||
409 | gss_msg->msg.len = sprintf(gss_msg->databuf, "mech=%s uid=%d ", | 412 | gss_msg->msg.len = sprintf(gss_msg->databuf, "mech=%s uid=%d ", |
410 | mech->gm_name, | 413 | mech->gm_name, |
411 | gss_msg->uid); | 414 | from_kuid(&init_user_ns, gss_msg->uid)); |
412 | p += gss_msg->msg.len; | 415 | p += gss_msg->msg.len; |
413 | if (clnt->cl_principal) { | 416 | if (clnt->cl_principal) { |
414 | len = sprintf(p, "target=%s ", clnt->cl_principal); | 417 | len = sprintf(p, "target=%s ", clnt->cl_principal); |
@@ -444,7 +447,7 @@ static void gss_encode_msg(struct gss_upcall_msg *gss_msg, | |||
444 | 447 | ||
445 | static struct gss_upcall_msg * | 448 | static struct gss_upcall_msg * |
446 | gss_alloc_msg(struct gss_auth *gss_auth, struct rpc_clnt *clnt, | 449 | gss_alloc_msg(struct gss_auth *gss_auth, struct rpc_clnt *clnt, |
447 | uid_t uid, const char *service_name) | 450 | kuid_t uid, const char *service_name) |
448 | { | 451 | { |
449 | struct gss_upcall_msg *gss_msg; | 452 | struct gss_upcall_msg *gss_msg; |
450 | int vers; | 453 | int vers; |
@@ -474,7 +477,7 @@ gss_setup_upcall(struct rpc_clnt *clnt, struct gss_auth *gss_auth, struct rpc_cr | |||
474 | struct gss_cred *gss_cred = container_of(cred, | 477 | struct gss_cred *gss_cred = container_of(cred, |
475 | struct gss_cred, gc_base); | 478 | struct gss_cred, gc_base); |
476 | struct gss_upcall_msg *gss_new, *gss_msg; | 479 | struct gss_upcall_msg *gss_new, *gss_msg; |
477 | uid_t uid = cred->cr_uid; | 480 | kuid_t uid = cred->cr_uid; |
478 | 481 | ||
479 | gss_new = gss_alloc_msg(gss_auth, clnt, uid, gss_cred->gc_principal); | 482 | gss_new = gss_alloc_msg(gss_auth, clnt, uid, gss_cred->gc_principal); |
480 | if (IS_ERR(gss_new)) | 483 | if (IS_ERR(gss_new)) |
@@ -516,7 +519,7 @@ gss_refresh_upcall(struct rpc_task *task) | |||
516 | int err = 0; | 519 | int err = 0; |
517 | 520 | ||
518 | dprintk("RPC: %5u %s for uid %u\n", | 521 | dprintk("RPC: %5u %s for uid %u\n", |
519 | task->tk_pid, __func__, cred->cr_uid); | 522 | task->tk_pid, __func__, from_kuid(&init_user_ns, cred->cr_uid)); |
520 | gss_msg = gss_setup_upcall(task->tk_client, gss_auth, cred); | 523 | gss_msg = gss_setup_upcall(task->tk_client, gss_auth, cred); |
521 | if (PTR_ERR(gss_msg) == -EAGAIN) { | 524 | if (PTR_ERR(gss_msg) == -EAGAIN) { |
522 | /* XXX: warning on the first, under the assumption we | 525 | /* XXX: warning on the first, under the assumption we |
@@ -548,7 +551,8 @@ gss_refresh_upcall(struct rpc_task *task) | |||
548 | gss_release_msg(gss_msg); | 551 | gss_release_msg(gss_msg); |
549 | out: | 552 | out: |
550 | dprintk("RPC: %5u %s for uid %u result %d\n", | 553 | dprintk("RPC: %5u %s for uid %u result %d\n", |
551 | task->tk_pid, __func__, cred->cr_uid, err); | 554 | task->tk_pid, __func__, |
555 | from_kuid(&init_user_ns, cred->cr_uid), err); | ||
552 | return err; | 556 | return err; |
553 | } | 557 | } |
554 | 558 | ||
@@ -561,7 +565,8 @@ gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred) | |||
561 | DEFINE_WAIT(wait); | 565 | DEFINE_WAIT(wait); |
562 | int err = 0; | 566 | int err = 0; |
563 | 567 | ||
564 | dprintk("RPC: %s for uid %u\n", __func__, cred->cr_uid); | 568 | dprintk("RPC: %s for uid %u\n", |
569 | __func__, from_kuid(&init_user_ns, cred->cr_uid)); | ||
565 | retry: | 570 | retry: |
566 | gss_msg = gss_setup_upcall(gss_auth->client, gss_auth, cred); | 571 | gss_msg = gss_setup_upcall(gss_auth->client, gss_auth, cred); |
567 | if (PTR_ERR(gss_msg) == -EAGAIN) { | 572 | if (PTR_ERR(gss_msg) == -EAGAIN) { |
@@ -603,7 +608,7 @@ out_intr: | |||
603 | gss_release_msg(gss_msg); | 608 | gss_release_msg(gss_msg); |
604 | out: | 609 | out: |
605 | dprintk("RPC: %s for uid %u result %d\n", | 610 | dprintk("RPC: %s for uid %u result %d\n", |
606 | __func__, cred->cr_uid, err); | 611 | __func__, from_kuid(&init_user_ns, cred->cr_uid), err); |
607 | return err; | 612 | return err; |
608 | } | 613 | } |
609 | 614 | ||
@@ -617,7 +622,8 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) | |||
617 | struct gss_upcall_msg *gss_msg; | 622 | struct gss_upcall_msg *gss_msg; |
618 | struct rpc_pipe *pipe = RPC_I(filp->f_dentry->d_inode)->pipe; | 623 | struct rpc_pipe *pipe = RPC_I(filp->f_dentry->d_inode)->pipe; |
619 | struct gss_cl_ctx *ctx; | 624 | struct gss_cl_ctx *ctx; |
620 | uid_t uid; | 625 | uid_t id; |
626 | kuid_t uid; | ||
621 | ssize_t err = -EFBIG; | 627 | ssize_t err = -EFBIG; |
622 | 628 | ||
623 | if (mlen > MSG_BUF_MAXSIZE) | 629 | if (mlen > MSG_BUF_MAXSIZE) |
@@ -632,12 +638,18 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) | |||
632 | goto err; | 638 | goto err; |
633 | 639 | ||
634 | end = (const void *)((char *)buf + mlen); | 640 | end = (const void *)((char *)buf + mlen); |
635 | p = simple_get_bytes(buf, end, &uid, sizeof(uid)); | 641 | p = simple_get_bytes(buf, end, &id, sizeof(id)); |
636 | if (IS_ERR(p)) { | 642 | if (IS_ERR(p)) { |
637 | err = PTR_ERR(p); | 643 | err = PTR_ERR(p); |
638 | goto err; | 644 | goto err; |
639 | } | 645 | } |
640 | 646 | ||
647 | uid = make_kuid(&init_user_ns, id); | ||
648 | if (!uid_valid(uid)) { | ||
649 | err = -EINVAL; | ||
650 | goto err; | ||
651 | } | ||
652 | |||
641 | err = -ENOMEM; | 653 | err = -ENOMEM; |
642 | ctx = gss_alloc_context(); | 654 | ctx = gss_alloc_context(); |
643 | if (ctx == NULL) | 655 | if (ctx == NULL) |
@@ -1058,7 +1070,8 @@ gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) | |||
1058 | int err = -ENOMEM; | 1070 | int err = -ENOMEM; |
1059 | 1071 | ||
1060 | dprintk("RPC: %s for uid %d, flavor %d\n", | 1072 | dprintk("RPC: %s for uid %d, flavor %d\n", |
1061 | __func__, acred->uid, auth->au_flavor); | 1073 | __func__, from_kuid(&init_user_ns, acred->uid), |
1074 | auth->au_flavor); | ||
1062 | 1075 | ||
1063 | if (!(cred = kzalloc(sizeof(*cred), GFP_NOFS))) | 1076 | if (!(cred = kzalloc(sizeof(*cred), GFP_NOFS))) |
1064 | goto out_err; | 1077 | goto out_err; |
@@ -1114,7 +1127,7 @@ out: | |||
1114 | } | 1127 | } |
1115 | if (gss_cred->gc_principal != NULL) | 1128 | if (gss_cred->gc_principal != NULL) |
1116 | return 0; | 1129 | return 0; |
1117 | return rc->cr_uid == acred->uid; | 1130 | return uid_eq(rc->cr_uid, acred->uid); |
1118 | } | 1131 | } |
1119 | 1132 | ||
1120 | /* | 1133 | /* |
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index 73e957386600..ecd1d58bf611 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c | |||
@@ -418,6 +418,7 @@ static int rsc_parse(struct cache_detail *cd, | |||
418 | { | 418 | { |
419 | /* contexthandle expiry [ uid gid N <n gids> mechname ...mechdata... ] */ | 419 | /* contexthandle expiry [ uid gid N <n gids> mechname ...mechdata... ] */ |
420 | char *buf = mesg; | 420 | char *buf = mesg; |
421 | int id; | ||
421 | int len, rv; | 422 | int len, rv; |
422 | struct rsc rsci, *rscp = NULL; | 423 | struct rsc rsci, *rscp = NULL; |
423 | time_t expiry; | 424 | time_t expiry; |
@@ -444,7 +445,7 @@ static int rsc_parse(struct cache_detail *cd, | |||
444 | goto out; | 445 | goto out; |
445 | 446 | ||
446 | /* uid, or NEGATIVE */ | 447 | /* uid, or NEGATIVE */ |
447 | rv = get_int(&mesg, &rsci.cred.cr_uid); | 448 | rv = get_int(&mesg, &id); |
448 | if (rv == -EINVAL) | 449 | if (rv == -EINVAL) |
449 | goto out; | 450 | goto out; |
450 | if (rv == -ENOENT) | 451 | if (rv == -ENOENT) |
@@ -452,8 +453,16 @@ static int rsc_parse(struct cache_detail *cd, | |||
452 | else { | 453 | else { |
453 | int N, i; | 454 | int N, i; |
454 | 455 | ||
456 | /* uid */ | ||
457 | rsci.cred.cr_uid = make_kuid(&init_user_ns, id); | ||
458 | if (!uid_valid(rsci.cred.cr_uid)) | ||
459 | goto out; | ||
460 | |||
455 | /* gid */ | 461 | /* gid */ |
456 | if (get_int(&mesg, &rsci.cred.cr_gid)) | 462 | if (get_int(&mesg, &id)) |
463 | goto out; | ||
464 | rsci.cred.cr_gid = make_kgid(&init_user_ns, id); | ||
465 | if (!gid_valid(rsci.cred.cr_gid)) | ||
457 | goto out; | 466 | goto out; |
458 | 467 | ||
459 | /* number of additional gid's */ | 468 | /* number of additional gid's */ |
@@ -467,11 +476,10 @@ static int rsc_parse(struct cache_detail *cd, | |||
467 | /* gid's */ | 476 | /* gid's */ |
468 | status = -EINVAL; | 477 | status = -EINVAL; |
469 | for (i=0; i<N; i++) { | 478 | for (i=0; i<N; i++) { |
470 | gid_t gid; | ||
471 | kgid_t kgid; | 479 | kgid_t kgid; |
472 | if (get_int(&mesg, &gid)) | 480 | if (get_int(&mesg, &id)) |
473 | goto out; | 481 | goto out; |
474 | kgid = make_kgid(&init_user_ns, gid); | 482 | kgid = make_kgid(&init_user_ns, id); |
475 | if (!gid_valid(kgid)) | 483 | if (!gid_valid(kgid)) |
476 | goto out; | 484 | goto out; |
477 | GROUP_AT(rsci.cred.cr_group_info, i) = kgid; | 485 | GROUP_AT(rsci.cred.cr_group_info, i) = kgid; |
diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c index 52c5abdee211..dc37021fc3e5 100644 --- a/net/sunrpc/auth_unix.c +++ b/net/sunrpc/auth_unix.c | |||
@@ -18,8 +18,8 @@ | |||
18 | 18 | ||
19 | struct unx_cred { | 19 | struct unx_cred { |
20 | struct rpc_cred uc_base; | 20 | struct rpc_cred uc_base; |
21 | gid_t uc_gid; | 21 | kgid_t uc_gid; |
22 | gid_t uc_gids[NFS_NGROUPS]; | 22 | kgid_t uc_gids[NFS_NGROUPS]; |
23 | }; | 23 | }; |
24 | #define uc_uid uc_base.cr_uid | 24 | #define uc_uid uc_base.cr_uid |
25 | 25 | ||
@@ -65,7 +65,8 @@ unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) | |||
65 | unsigned int i; | 65 | unsigned int i; |
66 | 66 | ||
67 | dprintk("RPC: allocating UNIX cred for uid %d gid %d\n", | 67 | dprintk("RPC: allocating UNIX cred for uid %d gid %d\n", |
68 | acred->uid, acred->gid); | 68 | from_kuid(&init_user_ns, acred->uid), |
69 | from_kgid(&init_user_ns, acred->gid)); | ||
69 | 70 | ||
70 | if (!(cred = kmalloc(sizeof(*cred), GFP_NOFS))) | 71 | if (!(cred = kmalloc(sizeof(*cred), GFP_NOFS))) |
71 | return ERR_PTR(-ENOMEM); | 72 | return ERR_PTR(-ENOMEM); |
@@ -79,13 +80,10 @@ unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) | |||
79 | groups = NFS_NGROUPS; | 80 | groups = NFS_NGROUPS; |
80 | 81 | ||
81 | cred->uc_gid = acred->gid; | 82 | cred->uc_gid = acred->gid; |
82 | for (i = 0; i < groups; i++) { | 83 | for (i = 0; i < groups; i++) |
83 | gid_t gid; | 84 | cred->uc_gids[i] = GROUP_AT(acred->group_info, i); |
84 | gid = from_kgid(&init_user_ns, GROUP_AT(acred->group_info, i)); | ||
85 | cred->uc_gids[i] = gid; | ||
86 | } | ||
87 | if (i < NFS_NGROUPS) | 85 | if (i < NFS_NGROUPS) |
88 | cred->uc_gids[i] = NOGROUP; | 86 | cred->uc_gids[i] = INVALID_GID; |
89 | 87 | ||
90 | return &cred->uc_base; | 88 | return &cred->uc_base; |
91 | } | 89 | } |
@@ -123,21 +121,17 @@ unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int flags) | |||
123 | unsigned int i; | 121 | unsigned int i; |
124 | 122 | ||
125 | 123 | ||
126 | if (cred->uc_uid != acred->uid || cred->uc_gid != acred->gid) | 124 | if (!uid_eq(cred->uc_uid, acred->uid) || !gid_eq(cred->uc_gid, acred->gid)) |
127 | return 0; | 125 | return 0; |
128 | 126 | ||
129 | if (acred->group_info != NULL) | 127 | if (acred->group_info != NULL) |
130 | groups = acred->group_info->ngroups; | 128 | groups = acred->group_info->ngroups; |
131 | if (groups > NFS_NGROUPS) | 129 | if (groups > NFS_NGROUPS) |
132 | groups = NFS_NGROUPS; | 130 | groups = NFS_NGROUPS; |
133 | for (i = 0; i < groups ; i++) { | 131 | for (i = 0; i < groups ; i++) |
134 | gid_t gid; | 132 | if (!gid_eq(cred->uc_gids[i], GROUP_AT(acred->group_info, i))) |
135 | gid = from_kgid(&init_user_ns, GROUP_AT(acred->group_info, i)); | ||
136 | if (cred->uc_gids[i] != gid) | ||
137 | return 0; | 133 | return 0; |
138 | } | 134 | if (groups < NFS_NGROUPS && gid_valid(cred->uc_gids[groups])) |
139 | if (groups < NFS_NGROUPS && | ||
140 | cred->uc_gids[groups] != NOGROUP) | ||
141 | return 0; | 135 | return 0; |
142 | return 1; | 136 | return 1; |
143 | } | 137 | } |
@@ -163,11 +157,11 @@ unx_marshal(struct rpc_task *task, __be32 *p) | |||
163 | */ | 157 | */ |
164 | p = xdr_encode_array(p, clnt->cl_nodename, clnt->cl_nodelen); | 158 | p = xdr_encode_array(p, clnt->cl_nodename, clnt->cl_nodelen); |
165 | 159 | ||
166 | *p++ = htonl((u32) cred->uc_uid); | 160 | *p++ = htonl((u32) from_kuid(&init_user_ns, cred->uc_uid)); |
167 | *p++ = htonl((u32) cred->uc_gid); | 161 | *p++ = htonl((u32) from_kgid(&init_user_ns, cred->uc_gid)); |
168 | hold = p++; | 162 | hold = p++; |
169 | for (i = 0; i < 16 && cred->uc_gids[i] != (gid_t) NOGROUP; i++) | 163 | for (i = 0; i < 16 && gid_valid(cred->uc_gids[i]); i++) |
170 | *p++ = htonl((u32) cred->uc_gids[i]); | 164 | *p++ = htonl((u32) from_kgid(&init_user_ns, cred->uc_gids[i])); |
171 | *hold = htonl(p - hold - 1); /* gid array length */ | 165 | *hold = htonl(p - hold - 1); /* gid array length */ |
172 | *base = htonl((p - base - 1) << 2); /* cred length */ | 166 | *base = htonl((p - base - 1) << 2); /* cred length */ |
173 | 167 | ||
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c index 4d0129203733..a1852e19ed0c 100644 --- a/net/sunrpc/svcauth_unix.c +++ b/net/sunrpc/svcauth_unix.c | |||
@@ -415,10 +415,15 @@ svcauth_unix_info_release(struct svc_xprt *xpt) | |||
415 | 415 | ||
416 | struct unix_gid { | 416 | struct unix_gid { |
417 | struct cache_head h; | 417 | struct cache_head h; |
418 | uid_t uid; | 418 | kuid_t uid; |
419 | struct group_info *gi; | 419 | struct group_info *gi; |
420 | }; | 420 | }; |
421 | 421 | ||
422 | static int unix_gid_hash(kuid_t uid) | ||
423 | { | ||
424 | return hash_long(from_kuid(&init_user_ns, uid), GID_HASHBITS); | ||
425 | } | ||
426 | |||
422 | static void unix_gid_put(struct kref *kref) | 427 | static void unix_gid_put(struct kref *kref) |
423 | { | 428 | { |
424 | struct cache_head *item = container_of(kref, struct cache_head, ref); | 429 | struct cache_head *item = container_of(kref, struct cache_head, ref); |
@@ -433,7 +438,7 @@ static int unix_gid_match(struct cache_head *corig, struct cache_head *cnew) | |||
433 | { | 438 | { |
434 | struct unix_gid *orig = container_of(corig, struct unix_gid, h); | 439 | struct unix_gid *orig = container_of(corig, struct unix_gid, h); |
435 | struct unix_gid *new = container_of(cnew, struct unix_gid, h); | 440 | struct unix_gid *new = container_of(cnew, struct unix_gid, h); |
436 | return orig->uid == new->uid; | 441 | return uid_eq(orig->uid, new->uid); |
437 | } | 442 | } |
438 | static void unix_gid_init(struct cache_head *cnew, struct cache_head *citem) | 443 | static void unix_gid_init(struct cache_head *cnew, struct cache_head *citem) |
439 | { | 444 | { |
@@ -465,7 +470,7 @@ static void unix_gid_request(struct cache_detail *cd, | |||
465 | char tuid[20]; | 470 | char tuid[20]; |
466 | struct unix_gid *ug = container_of(h, struct unix_gid, h); | 471 | struct unix_gid *ug = container_of(h, struct unix_gid, h); |
467 | 472 | ||
468 | snprintf(tuid, 20, "%u", ug->uid); | 473 | snprintf(tuid, 20, "%u", from_kuid(&init_user_ns, ug->uid)); |
469 | qword_add(bpp, blen, tuid); | 474 | qword_add(bpp, blen, tuid); |
470 | (*bpp)[-1] = '\n'; | 475 | (*bpp)[-1] = '\n'; |
471 | } | 476 | } |
@@ -475,13 +480,14 @@ static int unix_gid_upcall(struct cache_detail *cd, struct cache_head *h) | |||
475 | return sunrpc_cache_pipe_upcall(cd, h, unix_gid_request); | 480 | return sunrpc_cache_pipe_upcall(cd, h, unix_gid_request); |
476 | } | 481 | } |
477 | 482 | ||
478 | static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, uid_t uid); | 483 | static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, kuid_t uid); |
479 | 484 | ||
480 | static int unix_gid_parse(struct cache_detail *cd, | 485 | static int unix_gid_parse(struct cache_detail *cd, |
481 | char *mesg, int mlen) | 486 | char *mesg, int mlen) |
482 | { | 487 | { |
483 | /* uid expiry Ngid gid0 gid1 ... gidN-1 */ | 488 | /* uid expiry Ngid gid0 gid1 ... gidN-1 */ |
484 | int uid; | 489 | int id; |
490 | kuid_t uid; | ||
485 | int gids; | 491 | int gids; |
486 | int rv; | 492 | int rv; |
487 | int i; | 493 | int i; |
@@ -493,9 +499,12 @@ static int unix_gid_parse(struct cache_detail *cd, | |||
493 | return -EINVAL; | 499 | return -EINVAL; |
494 | mesg[mlen-1] = 0; | 500 | mesg[mlen-1] = 0; |
495 | 501 | ||
496 | rv = get_int(&mesg, &uid); | 502 | rv = get_int(&mesg, &id); |
497 | if (rv) | 503 | if (rv) |
498 | return -EINVAL; | 504 | return -EINVAL; |
505 | uid = make_kuid(&init_user_ns, id); | ||
506 | if (!uid_valid(uid)) | ||
507 | return -EINVAL; | ||
499 | ug.uid = uid; | 508 | ug.uid = uid; |
500 | 509 | ||
501 | expiry = get_expiry(&mesg); | 510 | expiry = get_expiry(&mesg); |
@@ -530,7 +539,7 @@ static int unix_gid_parse(struct cache_detail *cd, | |||
530 | ug.h.expiry_time = expiry; | 539 | ug.h.expiry_time = expiry; |
531 | ch = sunrpc_cache_update(cd, | 540 | ch = sunrpc_cache_update(cd, |
532 | &ug.h, &ugp->h, | 541 | &ug.h, &ugp->h, |
533 | hash_long(uid, GID_HASHBITS)); | 542 | unix_gid_hash(uid)); |
534 | if (!ch) | 543 | if (!ch) |
535 | err = -ENOMEM; | 544 | err = -ENOMEM; |
536 | else { | 545 | else { |
@@ -549,7 +558,7 @@ static int unix_gid_show(struct seq_file *m, | |||
549 | struct cache_detail *cd, | 558 | struct cache_detail *cd, |
550 | struct cache_head *h) | 559 | struct cache_head *h) |
551 | { | 560 | { |
552 | struct user_namespace *user_ns = current_user_ns(); | 561 | struct user_namespace *user_ns = &init_user_ns; |
553 | struct unix_gid *ug; | 562 | struct unix_gid *ug; |
554 | int i; | 563 | int i; |
555 | int glen; | 564 | int glen; |
@@ -565,7 +574,7 @@ static int unix_gid_show(struct seq_file *m, | |||
565 | else | 574 | else |
566 | glen = 0; | 575 | glen = 0; |
567 | 576 | ||
568 | seq_printf(m, "%u %d:", ug->uid, glen); | 577 | seq_printf(m, "%u %d:", from_kuid_munged(user_ns, ug->uid), glen); |
569 | for (i = 0; i < glen; i++) | 578 | for (i = 0; i < glen; i++) |
570 | seq_printf(m, " %d", from_kgid_munged(user_ns, GROUP_AT(ug->gi, i))); | 579 | seq_printf(m, " %d", from_kgid_munged(user_ns, GROUP_AT(ug->gi, i))); |
571 | seq_printf(m, "\n"); | 580 | seq_printf(m, "\n"); |
@@ -615,20 +624,20 @@ void unix_gid_cache_destroy(struct net *net) | |||
615 | cache_destroy_net(cd, net); | 624 | cache_destroy_net(cd, net); |
616 | } | 625 | } |
617 | 626 | ||
618 | static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, uid_t uid) | 627 | static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, kuid_t uid) |
619 | { | 628 | { |
620 | struct unix_gid ug; | 629 | struct unix_gid ug; |
621 | struct cache_head *ch; | 630 | struct cache_head *ch; |
622 | 631 | ||
623 | ug.uid = uid; | 632 | ug.uid = uid; |
624 | ch = sunrpc_cache_lookup(cd, &ug.h, hash_long(uid, GID_HASHBITS)); | 633 | ch = sunrpc_cache_lookup(cd, &ug.h, unix_gid_hash(uid)); |
625 | if (ch) | 634 | if (ch) |
626 | return container_of(ch, struct unix_gid, h); | 635 | return container_of(ch, struct unix_gid, h); |
627 | else | 636 | else |
628 | return NULL; | 637 | return NULL; |
629 | } | 638 | } |
630 | 639 | ||
631 | static struct group_info *unix_gid_find(uid_t uid, struct svc_rqst *rqstp) | 640 | static struct group_info *unix_gid_find(kuid_t uid, struct svc_rqst *rqstp) |
632 | { | 641 | { |
633 | struct unix_gid *ug; | 642 | struct unix_gid *ug; |
634 | struct group_info *gi; | 643 | struct group_info *gi; |
@@ -750,8 +759,8 @@ svcauth_null_accept(struct svc_rqst *rqstp, __be32 *authp) | |||
750 | } | 759 | } |
751 | 760 | ||
752 | /* Signal that mapping to nobody uid/gid is required */ | 761 | /* Signal that mapping to nobody uid/gid is required */ |
753 | cred->cr_uid = (uid_t) -1; | 762 | cred->cr_uid = INVALID_UID; |
754 | cred->cr_gid = (gid_t) -1; | 763 | cred->cr_gid = INVALID_GID; |
755 | cred->cr_group_info = groups_alloc(0); | 764 | cred->cr_group_info = groups_alloc(0); |
756 | if (cred->cr_group_info == NULL) | 765 | if (cred->cr_group_info == NULL) |
757 | return SVC_CLOSE; /* kmalloc failure - client must retry */ | 766 | return SVC_CLOSE; /* kmalloc failure - client must retry */ |
@@ -812,8 +821,10 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp) | |||
812 | argv->iov_base = (void*)((__be32*)argv->iov_base + slen); /* skip machname */ | 821 | argv->iov_base = (void*)((__be32*)argv->iov_base + slen); /* skip machname */ |
813 | argv->iov_len -= slen*4; | 822 | argv->iov_len -= slen*4; |
814 | 823 | ||
815 | cred->cr_uid = svc_getnl(argv); /* uid */ | 824 | cred->cr_uid = make_kuid(&init_user_ns, svc_getnl(argv)); /* uid */ |
816 | cred->cr_gid = svc_getnl(argv); /* gid */ | 825 | cred->cr_gid = make_kgid(&init_user_ns, svc_getnl(argv)); /* gid */ |
826 | if (!uid_valid(cred->cr_uid) || !gid_valid(cred->cr_gid)) | ||
827 | goto badcred; | ||
817 | slen = svc_getnl(argv); /* gids length */ | 828 | slen = svc_getnl(argv); /* gids length */ |
818 | if (slen > 16 || (len -= (slen + 2)*4) < 0) | 829 | if (slen > 16 || (len -= (slen + 2)*4) < 0) |
819 | goto badcred; | 830 | goto badcred; |