diff options
author | Michael Bestas <mkbestas@lineageos.org> | 2020-05-10 01:30:22 +0300 |
---|---|---|
committer | Michael Bestas <mkbestas@lineageos.org> | 2020-05-14 20:02:37 +0300 |
commit | 5d60efc89fa6e5a6616bd9dfa2b0702756b7404e (patch) | |
tree | 87757b8f716c565352758d964f4fead762d7e139 /security | |
parent | 47adfb24dc4eabe3507c89902c5068f501b01b13 (diff) | |
parent | 96b09cba55905a34aa152a9689a43d6d3c78b04d (diff) |
Merge branch 'android-4.4-p' of https://android.googlesource.com/kernel/common into lineage-17.1-caf-msm8998
This brings LA.UM.8.4.r1-05400-8x98.0 up to date with
https://android.googlesource.com/kernel/common/ android-4.4-p at commit:
96b09cba55905 UPSTREAM: net: socket: set sock->sk to NULL after calling proto_ops::release()
Conflicts:
drivers/scsi/ufs/ufshcd.c
drivers/usb/gadget/composite.c
drivers/usb/gadget/function/f_fs.c
Change-Id: I3e79c0d20e3eb3246a50c9a1e815cdf030a4232e
Diffstat (limited to 'security')
-rw-r--r-- | security/keys/key.c | 2 | ||||
-rw-r--r-- | security/keys/keyctl.c | 4 | ||||
-rw-r--r-- | security/selinux/hooks.c | 69 |
3 files changed, 48 insertions, 27 deletions
diff --git a/security/keys/key.c b/security/keys/key.c index 03160f1f1aa2..b5c8324ecf62 100644 --- a/security/keys/key.c +++ b/security/keys/key.c @@ -376,7 +376,7 @@ int key_payload_reserve(struct key *key, size_t datalen) spin_lock(&key->user->lock); if (delta > 0 && - (key->user->qnbytes + delta >= maxbytes || + (key->user->qnbytes + delta > maxbytes || key->user->qnbytes + delta < key->user->qnbytes)) { ret = -EDQUOT; } diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index 2e741e1a8712..292b583e591b 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c @@ -853,8 +853,8 @@ long keyctl_chown_key(key_serial_t id, uid_t user, gid_t group) key_quota_root_maxbytes : key_quota_maxbytes; spin_lock(&newowner->lock); - if (newowner->qnkeys + 1 >= maxkeys || - newowner->qnbytes + key->quotalen >= maxbytes || + if (newowner->qnkeys + 1 > maxkeys || + newowner->qnbytes + key->quotalen > maxbytes || newowner->qnbytes + key->quotalen < newowner->qnbytes) goto quota_overrun; diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index f7e2cd8c3e53..534019901c0b 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -4826,38 +4826,59 @@ static int selinux_tun_dev_open(void *security) static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb) { - int err = 0; - u32 perm; + int rc = 0; + unsigned int msg_len; + unsigned int data_len = skb->len; + unsigned char *data = skb->data; struct nlmsghdr *nlh; struct sk_security_struct *sksec = sk->sk_security; + u16 sclass = sksec->sclass; + u32 perm; - if (skb->len < NLMSG_HDRLEN) { - err = -EINVAL; - goto out; - } - nlh = nlmsg_hdr(skb); + while (data_len >= nlmsg_total_size(0)) { + nlh = (struct nlmsghdr *)data; - err = selinux_nlmsg_lookup(sksec->sclass, nlh->nlmsg_type, &perm); - if (err) { - if (err == -EINVAL) { - printk(KERN_WARNING - "SELinux: unrecognized netlink message:" - " protocol=%hu nlmsg_type=%hu sclass=%s\n", - sk->sk_protocol, nlh->nlmsg_type, - secclass_map[sksec->sclass - 1].name); - if (!selinux_enforcing || security_get_allow_unknown()) - err = 0; + /* NOTE: the nlmsg_len field isn't reliably set by some netlink + * users which means we can't reject skb's with bogus + * length fields; our solution is to follow what + * netlink_rcv_skb() does and simply skip processing at + * messages with length fields that are clearly junk + */ + if (nlh->nlmsg_len < NLMSG_HDRLEN || nlh->nlmsg_len > data_len) + return 0; + + rc = selinux_nlmsg_lookup(sclass, nlh->nlmsg_type, &perm); + if (rc == 0) { + rc = sock_has_perm(current, sk, perm); + if (rc) + return rc; + } else if (rc == -EINVAL) { + /* -EINVAL is a missing msg/perm mapping */ + pr_warn_ratelimited("SELinux: unrecognized netlink" + " message: protocol=%hu nlmsg_type=%hu sclass=%s" + " pid=%d comm=%s\n", + sk->sk_protocol, nlh->nlmsg_type, + secclass_map[sclass - 1].name, + task_pid_nr(current), current->comm); + if (selinux_enforcing && !security_get_allow_unknown()) + return rc; + rc = 0; + } else if (rc == -ENOENT) { + /* -ENOENT is a missing socket/class mapping, ignore */ + rc = 0; + } else { + return rc; } - /* Ignore */ - if (err == -ENOENT) - err = 0; - goto out; + /* move to the next message after applying netlink padding */ + msg_len = NLMSG_ALIGN(nlh->nlmsg_len); + if (msg_len >= data_len) + return 0; + data_len -= msg_len; + data += msg_len; } - err = sock_has_perm(current, sk, perm); -out: - return err; + return rc; } #ifdef CONFIG_NETFILTER |