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
This commit is contained in:
Коммит
affd9a8dbc
|
@ -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
|
||||
id_rb_insert(struct rb_root *root, struct cifs_sid *sidptr,
|
||||
struct cifs_sid_id **psidid, char *typestr)
|
||||
|
@ -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)->refcount = 0;
|
||||
|
||||
|
@ -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 .
|
||||
*/
|
||||
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 */
|
||||
goto id_sid_out;
|
||||
}
|
||||
|
@ -370,14 +377,14 @@ id_to_sid(unsigned long cid, uint sidtype, struct cifs_sid *ssid)
|
|||
if (IS_ERR(sidkey)) {
|
||||
rc = -EINVAL;
|
||||
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 {
|
||||
lsid = (struct cifs_sid *)sidkey->payload.data;
|
||||
memcpy(&psidid->sid, lsid,
|
||||
sidkey->datalen < sizeof(struct cifs_sid) ?
|
||||
sidkey->datalen : sizeof(struct cifs_sid));
|
||||
memcpy(ssid, &psidid->sid,
|
||||
sidkey->datalen < sizeof(struct cifs_sid) ?
|
||||
sidkey->datalen : sizeof(struct cifs_sid));
|
||||
cifs_copy_sid(&psidid->sid, lsid);
|
||||
cifs_copy_sid(ssid, &psidid->sid);
|
||||
set_bit(SID_ID_MAPPED, &psidid->state);
|
||||
key_put(sidkey);
|
||||
kfree(psidid->sidstr);
|
||||
|
@ -396,7 +403,7 @@ id_to_sid(unsigned long cid, uint sidtype, struct cifs_sid *ssid)
|
|||
return rc;
|
||||
}
|
||||
if (test_bit(SID_ID_MAPPED, &psidid->state))
|
||||
memcpy(ssid, &psidid->sid, sizeof(struct cifs_sid));
|
||||
cifs_copy_sid(ssid, &psidid->sid);
|
||||
else
|
||||
rc = -EINVAL;
|
||||
}
|
||||
|
@ -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,
|
||||
struct cifs_ntsd *pnntsd, __u32 sidsoffset)
|
||||
{
|
||||
int i;
|
||||
|
||||
struct cifs_sid *owner_sid_ptr, *group_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,
|
|||
owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
|
||||
le32_to_cpu(pntsd->osidoffset));
|
||||
nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset);
|
||||
|
||||
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];
|
||||
cifs_copy_sid(nowner_sid_ptr, owner_sid_ptr);
|
||||
|
||||
/* copy group sid */
|
||||
group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
|
||||
le32_to_cpu(pntsd->gsidoffset));
|
||||
ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset +
|
||||
sizeof(struct cifs_sid));
|
||||
|
||||
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];
|
||||
cifs_copy_sid(ngroup_sid_ptr, group_sid_ptr);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -1120,8 +1113,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
|
|||
kfree(nowner_sid_ptr);
|
||||
return rc;
|
||||
}
|
||||
memcpy(owner_sid_ptr, nowner_sid_ptr,
|
||||
sizeof(struct cifs_sid));
|
||||
cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr);
|
||||
kfree(nowner_sid_ptr);
|
||||
*aclflag = CIFS_ACL_OWNER;
|
||||
}
|
||||
|
@ -1139,8 +1131,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
|
|||
kfree(ngroup_sid_ptr);
|
||||
return rc;
|
||||
}
|
||||
memcpy(group_sid_ptr, ngroup_sid_ptr,
|
||||
sizeof(struct cifs_sid));
|
||||
cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr);
|
||||
kfree(ngroup_sid_ptr);
|
||||
*aclflag = CIFS_ACL_GROUP;
|
||||
}
|
||||
|
|
|
@ -398,7 +398,16 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
|
|||
* in network traffic in the other paths.
|
||||
*/
|
||||
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))
|
||||
return PTR_ERR(res);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче