aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/cifsacl.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index f4508ee4e80d..751d34bd825c 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -49,6 +49,20 @@ cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
49{ 49{
50 char *payload; 50 char *payload;
51 51
52 /*
53 * If the payload is less than or equal to the size of a pointer, then
54 * an allocation here is wasteful. Just copy the data directly to the
55 * payload.value union member instead.
56 *
57 * With this however, you must check the datalen before trying to
58 * dereference payload.data!
59 */
60 if (prep->datalen <= sizeof(void *)) {
61 key->payload.value = 0;
62 memcpy(&key->payload.value, prep->data, prep->datalen);
63 key->datalen = prep->datalen;
64 return 0;
65 }
52 payload = kmalloc(prep->datalen, GFP_KERNEL); 66 payload = kmalloc(prep->datalen, GFP_KERNEL);
53 if (!payload) 67 if (!payload)
54 return -ENOMEM; 68 return -ENOMEM;
@@ -62,7 +76,8 @@ cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
62static inline void 76static inline void
63cifs_idmap_key_destroy(struct key *key) 77cifs_idmap_key_destroy(struct key *key)
64{ 78{
65 kfree(key->payload.data); 79 if (key->datalen > sizeof(void *))
80 kfree(key->payload.data);
66} 81}
67 82
68static struct key_type cifs_idmap_key_type = { 83static struct key_type cifs_idmap_key_type = {
@@ -245,7 +260,7 @@ sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
245 * probably a safe assumption but might be better to check based on 260 * probably a safe assumption but might be better to check based on
246 * sidtype. 261 * sidtype.
247 */ 262 */
248 if (sidkey->datalen < sizeof(uid_t)) { 263 if (sidkey->datalen != sizeof(uid_t)) {
249 rc = -EIO; 264 rc = -EIO;
250 cFYI(1, "%s: Downcall contained malformed key " 265 cFYI(1, "%s: Downcall contained malformed key "
251 "(datalen=%hu)", __func__, sidkey->datalen); 266 "(datalen=%hu)", __func__, sidkey->datalen);
@@ -253,9 +268,9 @@ sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
253 } 268 }
254 269
255 if (sidtype == SIDOWNER) 270 if (sidtype == SIDOWNER)
256 fuid = *(uid_t *)sidkey->payload.value; 271 memcpy(&fuid, &sidkey->payload.value, sizeof(uid_t));
257 else 272 else
258 fgid = *(gid_t *)sidkey->payload.value; 273 memcpy(&fgid, &sidkey->payload.value, sizeof(gid_t));
259 274
260out_key_put: 275out_key_put:
261 key_put(sidkey); 276 key_put(sidkey);