aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/audit.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/audit.c')
-rw-r--r--kernel/audit.c35
1 files changed, 18 insertions, 17 deletions
diff --git a/kernel/audit.c b/kernel/audit.c
index 01082a1d2bc5..ce77e81a0e71 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -937,28 +937,29 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
937} 937}
938 938
939/* 939/*
940 * Get message from skb (based on rtnetlink_rcv_skb). Each message is 940 * Get message from skb. Each message is processed by audit_receive_msg.
941 * processed by audit_receive_msg. Malformed skbs with wrong length are 941 * Malformed skbs with wrong length are discarded silently.
942 * discarded silently.
943 */ 942 */
944static void audit_receive_skb(struct sk_buff *skb) 943static void audit_receive_skb(struct sk_buff *skb)
945{ 944{
946 int err; 945 struct nlmsghdr *nlh;
947 struct nlmsghdr *nlh; 946 /*
948 u32 rlen; 947 * len MUST be signed for NLMSG_NEXT to be able to dec it below 0
948 * if the nlmsg_len was not aligned
949 */
950 int len;
951 int err;
949 952
950 while (skb->len >= NLMSG_SPACE(0)) { 953 nlh = nlmsg_hdr(skb);
951 nlh = nlmsg_hdr(skb); 954 len = skb->len;
952 if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len) 955
953 return; 956 while (NLMSG_OK(nlh, len)) {
954 rlen = NLMSG_ALIGN(nlh->nlmsg_len); 957 err = audit_receive_msg(skb, nlh);
955 if (rlen > skb->len) 958 /* if err or if this message says it wants a response */
956 rlen = skb->len; 959 if (err || (nlh->nlmsg_flags & NLM_F_ACK))
957 if ((err = audit_receive_msg(skb, nlh))) {
958 netlink_ack(skb, nlh, err); 960 netlink_ack(skb, nlh, err);
959 } else if (nlh->nlmsg_flags & NLM_F_ACK) 961
960 netlink_ack(skb, nlh, 0); 962 nlh = NLMSG_NEXT(nlh, len);
961 skb_pull(skb, rlen);
962 } 963 }
963} 964}
964 965