cifs: make cifs_copy_sid handle a source sid with variable size subauth arrays
authorJeff Layton <jlayton@redhat.com>
Sun, 25 Nov 2012 13:00:37 +0000 (08:00 -0500)
committerSteve French <smfrench@gmail.com>
Wed, 5 Dec 2012 19:13:11 +0000 (13:13 -0600)
...and lift the restriction in id_to_sid upcall that the size must be
at least as big as a full cifs_sid.

Reviewed-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <smfrench@gmail.com>
fs/cifs/cifsacl.c
fs/cifs/cifsacl.h

index 5a312eb45a926d0bc4221c0e78c74134c6c317bd..141a944c9dfdb4699c7c2620652921934fb1e3f9 100644 (file)
@@ -277,8 +277,14 @@ compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
 static void
 cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src)
 {
-       memcpy(dst, src, sizeof(*dst));
+       int i;
+
+       dst->revision = src->revision;
        dst->num_subauth = min_t(u8, src->num_subauth, NUM_SUBAUTHS);
+       for (i = 0; i < NUM_AUTHS; ++i)
+               dst->authority[i] = src->authority[i];
+       for (i = 0; i < dst->num_subauth; ++i)
+               dst->sub_auth[i] = src->sub_auth[i];
 }
 
 static void
@@ -427,7 +433,7 @@ 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)) {
+               } else if (sidkey->datalen < CIFS_SID_BASE_SIZE) {
                        rc = -EIO;
                        cFYI(1, "%s: Downcall contained malformed key "
                                "(datalen=%hu)", __func__, sidkey->datalen);
index 18c7521273a7afabc4189afbd823c359a020b869..7e52f19f996f0266d84ba4624740fe27ef35e400 100644 (file)
@@ -64,6 +64,9 @@ struct cifs_sid {
        __le32 sub_auth[NUM_SUBAUTHS]; /* sub_auth[num_subauth] */
 } __attribute__((packed));
 
+/* size of a struct cifs_sid, sans sub_auth array */
+#define CIFS_SID_BASE_SIZE (1 + 1 + NUM_AUTHS)
+
 struct cifs_acl {
        __le16 revision; /* revision level */
        __le16 size;