Commit affd9a8d authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.samba.org/sfrench/cifs-2.6

Pull cifs fixes from Jeff Layton.

* 'for-linus' of git://git.samba.org/sfrench/cifs-2.6:
  cifs: Do not lookup hashed negative dentry in cifs_atomic_open
  cifs: fix potential buffer overrun in cifs.idmap handling code
parents 487bda54 3798f47a
...@@ -224,6 +224,13 @@ sid_to_str(struct cifs_sid *sidptr, char *sidstr) ...@@ -224,6 +224,13 @@ sid_to_str(struct cifs_sid *sidptr, char *sidstr)
} }
} }
static void
cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src)
{
memcpy(dst, src, sizeof(*dst));
dst->num_subauth = min_t(u8, src->num_subauth, NUM_SUBAUTHS);
}
static void static void
id_rb_insert(struct rb_root *root, struct cifs_sid *sidptr, id_rb_insert(struct rb_root *root, struct cifs_sid *sidptr,
struct cifs_sid_id **psidid, char *typestr) struct cifs_sid_id **psidid, char *typestr)
...@@ -248,7 +255,7 @@ id_rb_insert(struct rb_root *root, struct cifs_sid *sidptr, ...@@ -248,7 +255,7 @@ id_rb_insert(struct rb_root *root, struct cifs_sid *sidptr,
} }
} }
memcpy(&(*psidid)->sid, sidptr, sizeof(struct cifs_sid)); cifs_copy_sid(&(*psidid)->sid, sidptr);
(*psidid)->time = jiffies - (SID_MAP_RETRY + 1); (*psidid)->time = jiffies - (SID_MAP_RETRY + 1);
(*psidid)->refcount = 0; (*psidid)->refcount = 0;
...@@ -354,7 +361,7 @@ id_to_sid(unsigned long cid, uint sidtype, struct cifs_sid *ssid) ...@@ -354,7 +361,7 @@ id_to_sid(unsigned long cid, uint sidtype, struct cifs_sid *ssid)
* any fields of the node after a reference is put . * any fields of the node after a reference is put .
*/ */
if (test_bit(SID_ID_MAPPED, &psidid->state)) { if (test_bit(SID_ID_MAPPED, &psidid->state)) {
memcpy(ssid, &psidid->sid, sizeof(struct cifs_sid)); cifs_copy_sid(ssid, &psidid->sid);
psidid->time = jiffies; /* update ts for accessing */ psidid->time = jiffies; /* update ts for accessing */
goto id_sid_out; goto id_sid_out;
} }
...@@ -370,14 +377,14 @@ id_to_sid(unsigned long cid, uint sidtype, struct cifs_sid *ssid) ...@@ -370,14 +377,14 @@ id_to_sid(unsigned long cid, uint sidtype, struct cifs_sid *ssid)
if (IS_ERR(sidkey)) { if (IS_ERR(sidkey)) {
rc = -EINVAL; rc = -EINVAL;
cFYI(1, "%s: Can't map and id to a SID", __func__); cFYI(1, "%s: Can't map and id to a SID", __func__);
} else if (sidkey->datalen < sizeof(struct cifs_sid)) {
rc = -EIO;
cFYI(1, "%s: Downcall contained malformed key "
"(datalen=%hu)", __func__, sidkey->datalen);
} else { } else {
lsid = (struct cifs_sid *)sidkey->payload.data; lsid = (struct cifs_sid *)sidkey->payload.data;
memcpy(&psidid->sid, lsid, cifs_copy_sid(&psidid->sid, lsid);
sidkey->datalen < sizeof(struct cifs_sid) ? cifs_copy_sid(ssid, &psidid->sid);
sidkey->datalen : sizeof(struct cifs_sid));
memcpy(ssid, &psidid->sid,
sidkey->datalen < sizeof(struct cifs_sid) ?
sidkey->datalen : sizeof(struct cifs_sid));
set_bit(SID_ID_MAPPED, &psidid->state); set_bit(SID_ID_MAPPED, &psidid->state);
key_put(sidkey); key_put(sidkey);
kfree(psidid->sidstr); kfree(psidid->sidstr);
...@@ -396,7 +403,7 @@ id_to_sid(unsigned long cid, uint sidtype, struct cifs_sid *ssid) ...@@ -396,7 +403,7 @@ id_to_sid(unsigned long cid, uint sidtype, struct cifs_sid *ssid)
return rc; return rc;
} }
if (test_bit(SID_ID_MAPPED, &psidid->state)) if (test_bit(SID_ID_MAPPED, &psidid->state))
memcpy(ssid, &psidid->sid, sizeof(struct cifs_sid)); cifs_copy_sid(ssid, &psidid->sid);
else else
rc = -EINVAL; rc = -EINVAL;
} }
...@@ -675,8 +682,6 @@ int compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid) ...@@ -675,8 +682,6 @@ int compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
static void copy_sec_desc(const struct cifs_ntsd *pntsd, static void copy_sec_desc(const struct cifs_ntsd *pntsd,
struct cifs_ntsd *pnntsd, __u32 sidsoffset) struct cifs_ntsd *pnntsd, __u32 sidsoffset)
{ {
int i;
struct cifs_sid *owner_sid_ptr, *group_sid_ptr; struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr; struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
...@@ -692,26 +697,14 @@ static void copy_sec_desc(const struct cifs_ntsd *pntsd, ...@@ -692,26 +697,14 @@ static void copy_sec_desc(const struct cifs_ntsd *pntsd,
owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
le32_to_cpu(pntsd->osidoffset)); le32_to_cpu(pntsd->osidoffset));
nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset); nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset);
cifs_copy_sid(nowner_sid_ptr, owner_sid_ptr);
nowner_sid_ptr->revision = owner_sid_ptr->revision;
nowner_sid_ptr->num_subauth = owner_sid_ptr->num_subauth;
for (i = 0; i < 6; i++)
nowner_sid_ptr->authority[i] = owner_sid_ptr->authority[i];
for (i = 0; i < 5; i++)
nowner_sid_ptr->sub_auth[i] = owner_sid_ptr->sub_auth[i];
/* copy group sid */ /* copy group sid */
group_sid_ptr = (struct cifs_sid *)((char *)pntsd + group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
le32_to_cpu(pntsd->gsidoffset)); le32_to_cpu(pntsd->gsidoffset));
ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset + ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset +
sizeof(struct cifs_sid)); sizeof(struct cifs_sid));
cifs_copy_sid(ngroup_sid_ptr, group_sid_ptr);
ngroup_sid_ptr->revision = group_sid_ptr->revision;
ngroup_sid_ptr->num_subauth = group_sid_ptr->num_subauth;
for (i = 0; i < 6; i++)
ngroup_sid_ptr->authority[i] = group_sid_ptr->authority[i];
for (i = 0; i < 5; i++)
ngroup_sid_ptr->sub_auth[i] = group_sid_ptr->sub_auth[i];
return; return;
} }
...@@ -1120,8 +1113,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, ...@@ -1120,8 +1113,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
kfree(nowner_sid_ptr); kfree(nowner_sid_ptr);
return rc; return rc;
} }
memcpy(owner_sid_ptr, nowner_sid_ptr, cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr);
sizeof(struct cifs_sid));
kfree(nowner_sid_ptr); kfree(nowner_sid_ptr);
*aclflag = CIFS_ACL_OWNER; *aclflag = CIFS_ACL_OWNER;
} }
...@@ -1139,8 +1131,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, ...@@ -1139,8 +1131,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
kfree(ngroup_sid_ptr); kfree(ngroup_sid_ptr);
return rc; return rc;
} }
memcpy(group_sid_ptr, ngroup_sid_ptr, cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr);
sizeof(struct cifs_sid));
kfree(ngroup_sid_ptr); kfree(ngroup_sid_ptr);
*aclflag = CIFS_ACL_GROUP; *aclflag = CIFS_ACL_GROUP;
} }
......
...@@ -398,7 +398,16 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry, ...@@ -398,7 +398,16 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
* in network traffic in the other paths. * in network traffic in the other paths.
*/ */
if (!(oflags & O_CREAT)) { if (!(oflags & O_CREAT)) {
struct dentry *res = cifs_lookup(inode, direntry, 0); struct dentry *res;
/*
* Check for hashed negative dentry. We have already revalidated
* the dentry and it is fine. No need to perform another lookup.
*/
if (!d_unhashed(direntry))
return -ENOENT;
res = cifs_lookup(inode, direntry, 0);
if (IS_ERR(res)) if (IS_ERR(res))
return PTR_ERR(res); return PTR_ERR(res);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment