aboutsummaryrefslogtreecommitdiffstats
path: root/net/netlink/af_netlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/netlink/af_netlink.c')
-rw-r--r--net/netlink/af_netlink.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 320d0423a240..795424396aff 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -683,6 +683,9 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr,
683 struct netlink_sock *nlk = nlk_sk(sk); 683 struct netlink_sock *nlk = nlk_sk(sk);
684 struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr; 684 struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr;
685 685
686 if (alen < sizeof(addr->sa_family))
687 return -EINVAL;
688
686 if (addr->sa_family == AF_UNSPEC) { 689 if (addr->sa_family == AF_UNSPEC) {
687 sk->sk_state = NETLINK_UNCONNECTED; 690 sk->sk_state = NETLINK_UNCONNECTED;
688 nlk->dst_pid = 0; 691 nlk->dst_pid = 0;
@@ -1093,6 +1096,7 @@ static inline int do_one_set_err(struct sock *sk,
1093 struct netlink_set_err_data *p) 1096 struct netlink_set_err_data *p)
1094{ 1097{
1095 struct netlink_sock *nlk = nlk_sk(sk); 1098 struct netlink_sock *nlk = nlk_sk(sk);
1099 int ret = 0;
1096 1100
1097 if (sk == p->exclude_sk) 1101 if (sk == p->exclude_sk)
1098 goto out; 1102 goto out;
@@ -1104,10 +1108,15 @@ static inline int do_one_set_err(struct sock *sk,
1104 !test_bit(p->group - 1, nlk->groups)) 1108 !test_bit(p->group - 1, nlk->groups))
1105 goto out; 1109 goto out;
1106 1110
1111 if (p->code == ENOBUFS && nlk->flags & NETLINK_RECV_NO_ENOBUFS) {
1112 ret = 1;
1113 goto out;
1114 }
1115
1107 sk->sk_err = p->code; 1116 sk->sk_err = p->code;
1108 sk->sk_error_report(sk); 1117 sk->sk_error_report(sk);
1109out: 1118out:
1110 return 0; 1119 return ret;
1111} 1120}
1112 1121
1113/** 1122/**
@@ -1116,12 +1125,16 @@ out:
1116 * @pid: the PID of a process that we want to skip (if any) 1125 * @pid: the PID of a process that we want to skip (if any)
1117 * @groups: the broadcast group that will notice the error 1126 * @groups: the broadcast group that will notice the error
1118 * @code: error code, must be negative (as usual in kernelspace) 1127 * @code: error code, must be negative (as usual in kernelspace)
1128 *
1129 * This function returns the number of broadcast listeners that have set the
1130 * NETLINK_RECV_NO_ENOBUFS socket option.
1119 */ 1131 */
1120void netlink_set_err(struct sock *ssk, u32 pid, u32 group, int code) 1132int netlink_set_err(struct sock *ssk, u32 pid, u32 group, int code)
1121{ 1133{
1122 struct netlink_set_err_data info; 1134 struct netlink_set_err_data info;
1123 struct hlist_node *node; 1135 struct hlist_node *node;
1124 struct sock *sk; 1136 struct sock *sk;
1137 int ret = 0;
1125 1138
1126 info.exclude_sk = ssk; 1139 info.exclude_sk = ssk;
1127 info.pid = pid; 1140 info.pid = pid;
@@ -1132,9 +1145,10 @@ void netlink_set_err(struct sock *ssk, u32 pid, u32 group, int code)
1132 read_lock(&nl_table_lock); 1145 read_lock(&nl_table_lock);
1133 1146
1134 sk_for_each_bound(sk, node, &nl_table[ssk->sk_protocol].mc_list) 1147 sk_for_each_bound(sk, node, &nl_table[ssk->sk_protocol].mc_list)
1135 do_one_set_err(sk, &info); 1148 ret += do_one_set_err(sk, &info);
1136 1149
1137 read_unlock(&nl_table_lock); 1150 read_unlock(&nl_table_lock);
1151 return ret;
1138} 1152}
1139EXPORT_SYMBOL(netlink_set_err); 1153EXPORT_SYMBOL(netlink_set_err);
1140 1154