From 005fa288badb89864baebbf279cf768d92cf4d4d Mon Sep 17 00:00:00 2001 From: Tomasz Grobelny Date: Sat, 4 Dec 2010 13:39:13 +0100 Subject: [PATCH] --- yaml --- r: 224818 b: refs/heads/master c: 04910265078f08a73208beab70ed2a3cce4a919f h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/net/dccp/dccp.h | 1 + trunk/net/dccp/proto.c | 4 ++++ trunk/net/dccp/qpolicy.c | 23 +++++++++++++++++------ 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/[refs] b/[refs] index 6e6566ac3eab..c52e97782930 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 871a2c16c21b988688b4ab1a78eadd969765c0a3 +refs/heads/master: 04910265078f08a73208beab70ed2a3cce4a919f diff --git a/trunk/net/dccp/dccp.h b/trunk/net/dccp/dccp.h index d008da91cec2..48ad5d9da7cb 100644 --- a/trunk/net/dccp/dccp.h +++ b/trunk/net/dccp/dccp.h @@ -251,6 +251,7 @@ extern bool dccp_qpolicy_full(struct sock *sk); extern void dccp_qpolicy_drop(struct sock *sk, struct sk_buff *skb); extern struct sk_buff *dccp_qpolicy_top(struct sock *sk); extern struct sk_buff *dccp_qpolicy_pop(struct sock *sk); +extern bool dccp_qpolicy_param_ok(struct sock *sk, __be32 param); /* * TX Packet Output and TX Timers diff --git a/trunk/net/dccp/proto.c b/trunk/net/dccp/proto.c index d6a224982bb5..152975d942d9 100644 --- a/trunk/net/dccp/proto.c +++ b/trunk/net/dccp/proto.c @@ -726,6 +726,10 @@ static int dccp_msghdr_parse(struct msghdr *msg, struct sk_buff *skb) if (cmsg->cmsg_level != SOL_DCCP) continue; + if (cmsg->cmsg_type <= DCCP_SCM_QPOLICY_MAX && + !dccp_qpolicy_param_ok(skb->sk, cmsg->cmsg_type)) + return -EINVAL; + switch (cmsg->cmsg_type) { case DCCP_SCM_PRIORITY: if (cmsg->cmsg_len != CMSG_LEN(sizeof(__u32))) diff --git a/trunk/net/dccp/qpolicy.c b/trunk/net/dccp/qpolicy.c index 4b0fd6b11f6d..63c30bfa4703 100644 --- a/trunk/net/dccp/qpolicy.c +++ b/trunk/net/dccp/qpolicy.c @@ -73,17 +73,20 @@ static struct dccp_qpolicy_operations { void (*push) (struct sock *sk, struct sk_buff *skb); bool (*full) (struct sock *sk); struct sk_buff* (*top) (struct sock *sk); + __be32 params; } qpol_table[DCCPQ_POLICY_MAX] = { [DCCPQ_POLICY_SIMPLE] = { - .push = qpolicy_simple_push, - .full = qpolicy_simple_full, - .top = qpolicy_simple_top, + .push = qpolicy_simple_push, + .full = qpolicy_simple_full, + .top = qpolicy_simple_top, + .params = 0, }, [DCCPQ_POLICY_PRIO] = { - .push = qpolicy_simple_push, - .full = qpolicy_prio_full, - .top = qpolicy_prio_best_skb, + .push = qpolicy_simple_push, + .full = qpolicy_prio_full, + .top = qpolicy_prio_best_skb, + .params = DCCP_SCM_PRIORITY, }, }; @@ -124,3 +127,11 @@ struct sk_buff *dccp_qpolicy_pop(struct sock *sk) } return skb; } + +bool dccp_qpolicy_param_ok(struct sock *sk, __be32 param) +{ + /* check if exactly one bit is set */ + if (!param || (param & (param - 1))) + return false; + return (qpol_table[dccp_sk(sk)->dccps_qpolicy].params & param) == param; +}