Skip to content

Commit d545cac

Browse files
lcolittidavem330
authored andcommitted
net: inet: diag: expose the socket mark to privileged processes.
This adds the capability for a process that has CAP_NET_ADMIN on a socket to see the socket mark in socket dumps. Commit a52e95a ("net: diag: allow socket bytecode filters to match socket marks") recently gave privileged processes the ability to filter socket dumps based on mark. This patch is complementary: it ensures that the mark is also passed to userspace in the socket's netlink attributes. It is useful for tools like ss which display information about sockets. Tested: https://android-review.googlesource.com/270210 Signed-off-by: Lorenzo Colitti <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 74f13c8 commit d545cac

File tree

5 files changed

+56
-28
lines changed

5 files changed

+56
-28
lines changed

include/linux/inet_diag.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk,
3737
struct sk_buff *skb, const struct inet_diag_req_v2 *req,
3838
struct user_namespace *user_ns,
3939
u32 pid, u32 seq, u16 nlmsg_flags,
40-
const struct nlmsghdr *unlh);
40+
const struct nlmsghdr *unlh, bool net_admin);
4141
void inet_diag_dump_icsk(struct inet_hashinfo *h, struct sk_buff *skb,
4242
struct netlink_callback *cb,
4343
const struct inet_diag_req_v2 *r,
@@ -56,7 +56,7 @@ void inet_diag_msg_common_fill(struct inet_diag_msg *r, struct sock *sk);
5656

5757
int inet_diag_msg_attrs_fill(struct sock *sk, struct sk_buff *skb,
5858
struct inet_diag_msg *r, int ext,
59-
struct user_namespace *user_ns);
59+
struct user_namespace *user_ns, bool net_admin);
6060

6161
extern int inet_diag_register(const struct inet_diag_handler *handler);
6262
extern void inet_diag_unregister(const struct inet_diag_handler *handler);

include/uapi/linux/inet_diag.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ enum {
123123
INET_DIAG_LOCALS,
124124
INET_DIAG_PEERS,
125125
INET_DIAG_PAD,
126+
INET_DIAG_MARK,
126127
__INET_DIAG_MAX,
127128
};
128129

net/ipv4/inet_diag.c

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ static size_t inet_sk_attr_size(void)
9999
+ nla_total_size(1) /* INET_DIAG_SHUTDOWN */
100100
+ nla_total_size(1) /* INET_DIAG_TOS */
101101
+ nla_total_size(1) /* INET_DIAG_TCLASS */
102+
+ nla_total_size(4) /* INET_DIAG_MARK */
102103
+ nla_total_size(sizeof(struct inet_diag_meminfo))
103104
+ nla_total_size(sizeof(struct inet_diag_msg))
104105
+ nla_total_size(SK_MEMINFO_VARS * sizeof(u32))
@@ -109,7 +110,8 @@ static size_t inet_sk_attr_size(void)
109110

110111
int inet_diag_msg_attrs_fill(struct sock *sk, struct sk_buff *skb,
111112
struct inet_diag_msg *r, int ext,
112-
struct user_namespace *user_ns)
113+
struct user_namespace *user_ns,
114+
bool net_admin)
113115
{
114116
const struct inet_sock *inet = inet_sk(sk);
115117

@@ -136,6 +138,9 @@ int inet_diag_msg_attrs_fill(struct sock *sk, struct sk_buff *skb,
136138
}
137139
#endif
138140

141+
if (net_admin && nla_put_u32(skb, INET_DIAG_MARK, sk->sk_mark))
142+
goto errout;
143+
139144
r->idiag_uid = from_kuid_munged(user_ns, sock_i_uid(sk));
140145
r->idiag_inode = sock_i_ino(sk);
141146

@@ -149,7 +154,8 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk,
149154
struct sk_buff *skb, const struct inet_diag_req_v2 *req,
150155
struct user_namespace *user_ns,
151156
u32 portid, u32 seq, u16 nlmsg_flags,
152-
const struct nlmsghdr *unlh)
157+
const struct nlmsghdr *unlh,
158+
bool net_admin)
153159
{
154160
const struct tcp_congestion_ops *ca_ops;
155161
const struct inet_diag_handler *handler;
@@ -175,7 +181,7 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk,
175181
r->idiag_timer = 0;
176182
r->idiag_retrans = 0;
177183

178-
if (inet_diag_msg_attrs_fill(sk, skb, r, ext, user_ns))
184+
if (inet_diag_msg_attrs_fill(sk, skb, r, ext, user_ns, net_admin))
179185
goto errout;
180186

181187
if (ext & (1 << (INET_DIAG_MEMINFO - 1))) {
@@ -274,10 +280,11 @@ static int inet_csk_diag_fill(struct sock *sk,
274280
const struct inet_diag_req_v2 *req,
275281
struct user_namespace *user_ns,
276282
u32 portid, u32 seq, u16 nlmsg_flags,
277-
const struct nlmsghdr *unlh)
283+
const struct nlmsghdr *unlh,
284+
bool net_admin)
278285
{
279-
return inet_sk_diag_fill(sk, inet_csk(sk), skb, req,
280-
user_ns, portid, seq, nlmsg_flags, unlh);
286+
return inet_sk_diag_fill(sk, inet_csk(sk), skb, req, user_ns,
287+
portid, seq, nlmsg_flags, unlh, net_admin);
281288
}
282289

283290
static int inet_twsk_diag_fill(struct sock *sk,
@@ -319,8 +326,9 @@ static int inet_twsk_diag_fill(struct sock *sk,
319326

320327
static int inet_req_diag_fill(struct sock *sk, struct sk_buff *skb,
321328
u32 portid, u32 seq, u16 nlmsg_flags,
322-
const struct nlmsghdr *unlh)
329+
const struct nlmsghdr *unlh, bool net_admin)
323330
{
331+
struct request_sock *reqsk = inet_reqsk(sk);
324332
struct inet_diag_msg *r;
325333
struct nlmsghdr *nlh;
326334
long tmo;
@@ -334,7 +342,7 @@ static int inet_req_diag_fill(struct sock *sk, struct sk_buff *skb,
334342
inet_diag_msg_common_fill(r, sk);
335343
r->idiag_state = TCP_SYN_RECV;
336344
r->idiag_timer = 1;
337-
r->idiag_retrans = inet_reqsk(sk)->num_retrans;
345+
r->idiag_retrans = reqsk->num_retrans;
338346

339347
BUILD_BUG_ON(offsetof(struct inet_request_sock, ir_cookie) !=
340348
offsetof(struct sock, sk_cookie));
@@ -346,6 +354,10 @@ static int inet_req_diag_fill(struct sock *sk, struct sk_buff *skb,
346354
r->idiag_uid = 0;
347355
r->idiag_inode = 0;
348356

357+
if (net_admin && nla_put_u32(skb, INET_DIAG_MARK,
358+
inet_rsk(reqsk)->ir_mark))
359+
return -EMSGSIZE;
360+
349361
nlmsg_end(skb, nlh);
350362
return 0;
351363
}
@@ -354,18 +366,18 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb,
354366
const struct inet_diag_req_v2 *r,
355367
struct user_namespace *user_ns,
356368
u32 portid, u32 seq, u16 nlmsg_flags,
357-
const struct nlmsghdr *unlh)
369+
const struct nlmsghdr *unlh, bool net_admin)
358370
{
359371
if (sk->sk_state == TCP_TIME_WAIT)
360372
return inet_twsk_diag_fill(sk, skb, portid, seq,
361373
nlmsg_flags, unlh);
362374

363375
if (sk->sk_state == TCP_NEW_SYN_RECV)
364376
return inet_req_diag_fill(sk, skb, portid, seq,
365-
nlmsg_flags, unlh);
377+
nlmsg_flags, unlh, net_admin);
366378

367379
return inet_csk_diag_fill(sk, skb, r, user_ns, portid, seq,
368-
nlmsg_flags, unlh);
380+
nlmsg_flags, unlh, net_admin);
369381
}
370382

371383
struct sock *inet_diag_find_one_icsk(struct net *net,
@@ -435,7 +447,8 @@ int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo,
435447
err = sk_diag_fill(sk, rep, req,
436448
sk_user_ns(NETLINK_CB(in_skb).sk),
437449
NETLINK_CB(in_skb).portid,
438-
nlh->nlmsg_seq, 0, nlh);
450+
nlh->nlmsg_seq, 0, nlh,
451+
netlink_net_capable(in_skb, CAP_NET_ADMIN));
439452
if (err < 0) {
440453
WARN_ON(err == -EMSGSIZE);
441454
nlmsg_free(rep);
@@ -796,15 +809,17 @@ static int inet_csk_diag_dump(struct sock *sk,
796809
struct sk_buff *skb,
797810
struct netlink_callback *cb,
798811
const struct inet_diag_req_v2 *r,
799-
const struct nlattr *bc)
812+
const struct nlattr *bc,
813+
bool net_admin)
800814
{
801815
if (!inet_diag_bc_sk(bc, sk))
802816
return 0;
803817

804818
return inet_csk_diag_fill(sk, skb, r,
805819
sk_user_ns(NETLINK_CB(cb->skb).sk),
806820
NETLINK_CB(cb->skb).portid,
807-
cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh);
821+
cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh,
822+
net_admin);
808823
}
809824

810825
static void twsk_build_assert(void)
@@ -840,6 +855,7 @@ void inet_diag_dump_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *skb,
840855
struct net *net = sock_net(skb->sk);
841856
int i, num, s_i, s_num;
842857
u32 idiag_states = r->idiag_states;
858+
bool net_admin = netlink_net_capable(cb->skb, CAP_NET_ADMIN);
843859

844860
if (idiag_states & TCPF_SYN_RECV)
845861
idiag_states |= TCPF_NEW_SYN_RECV;
@@ -880,7 +896,8 @@ void inet_diag_dump_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *skb,
880896
cb->args[3] > 0)
881897
goto next_listen;
882898

883-
if (inet_csk_diag_dump(sk, skb, cb, r, bc) < 0) {
899+
if (inet_csk_diag_dump(sk, skb, cb, r,
900+
bc, net_admin) < 0) {
884901
spin_unlock_bh(&ilb->lock);
885902
goto done;
886903
}
@@ -948,7 +965,7 @@ void inet_diag_dump_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *skb,
948965
sk_user_ns(NETLINK_CB(cb->skb).sk),
949966
NETLINK_CB(cb->skb).portid,
950967
cb->nlh->nlmsg_seq, NLM_F_MULTI,
951-
cb->nlh);
968+
cb->nlh, net_admin);
952969
if (res < 0) {
953970
spin_unlock_bh(lock);
954971
goto done;

net/ipv4/udp_diag.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,15 @@
2020
static int sk_diag_dump(struct sock *sk, struct sk_buff *skb,
2121
struct netlink_callback *cb,
2222
const struct inet_diag_req_v2 *req,
23-
struct nlattr *bc)
23+
struct nlattr *bc, bool net_admin)
2424
{
2525
if (!inet_diag_bc_sk(bc, sk))
2626
return 0;
2727

2828
return inet_sk_diag_fill(sk, NULL, skb, req,
2929
sk_user_ns(NETLINK_CB(cb->skb).sk),
3030
NETLINK_CB(cb->skb).portid,
31-
cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh);
31+
cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh, net_admin);
3232
}
3333

3434
static int udp_dump_one(struct udp_table *tbl, struct sk_buff *in_skb,
@@ -76,7 +76,8 @@ static int udp_dump_one(struct udp_table *tbl, struct sk_buff *in_skb,
7676
err = inet_sk_diag_fill(sk, NULL, rep, req,
7777
sk_user_ns(NETLINK_CB(in_skb).sk),
7878
NETLINK_CB(in_skb).portid,
79-
nlh->nlmsg_seq, 0, nlh);
79+
nlh->nlmsg_seq, 0, nlh,
80+
netlink_net_capable(in_skb, CAP_NET_ADMIN));
8081
if (err < 0) {
8182
WARN_ON(err == -EMSGSIZE);
8283
kfree_skb(rep);
@@ -97,6 +98,7 @@ static void udp_dump(struct udp_table *table, struct sk_buff *skb,
9798
struct netlink_callback *cb,
9899
const struct inet_diag_req_v2 *r, struct nlattr *bc)
99100
{
101+
bool net_admin = netlink_net_capable(cb->skb, CAP_NET_ADMIN);
100102
struct net *net = sock_net(skb->sk);
101103
int num, s_num, slot, s_slot;
102104

@@ -132,7 +134,7 @@ static void udp_dump(struct udp_table *table, struct sk_buff *skb,
132134
r->id.idiag_dport)
133135
goto next;
134136

135-
if (sk_diag_dump(sk, skb, cb, r, bc) < 0) {
137+
if (sk_diag_dump(sk, skb, cb, r, bc, net_admin) < 0) {
136138
spin_unlock_bh(&hslot->lock);
137139
goto done;
138140
}

net/sctp/sctp_diag.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,8 @@ static int inet_sctp_diag_fill(struct sock *sk, struct sctp_association *asoc,
106106
const struct inet_diag_req_v2 *req,
107107
struct user_namespace *user_ns,
108108
int portid, u32 seq, u16 nlmsg_flags,
109-
const struct nlmsghdr *unlh)
109+
const struct nlmsghdr *unlh,
110+
bool net_admin)
110111
{
111112
struct sctp_endpoint *ep = sctp_sk(sk)->ep;
112113
struct list_head *addr_list;
@@ -133,7 +134,7 @@ static int inet_sctp_diag_fill(struct sock *sk, struct sctp_association *asoc,
133134
r->idiag_retrans = 0;
134135
}
135136

136-
if (inet_diag_msg_attrs_fill(sk, skb, r, ext, user_ns))
137+
if (inet_diag_msg_attrs_fill(sk, skb, r, ext, user_ns, net_admin))
137138
goto errout;
138139

139140
if (ext & (1 << (INET_DIAG_SKMEMINFO - 1))) {
@@ -203,6 +204,7 @@ struct sctp_comm_param {
203204
struct netlink_callback *cb;
204205
const struct inet_diag_req_v2 *r;
205206
const struct nlmsghdr *nlh;
207+
bool net_admin;
206208
};
207209

208210
static size_t inet_assoc_attr_size(struct sctp_association *asoc)
@@ -219,6 +221,7 @@ static size_t inet_assoc_attr_size(struct sctp_association *asoc)
219221
+ nla_total_size(1) /* INET_DIAG_SHUTDOWN */
220222
+ nla_total_size(1) /* INET_DIAG_TOS */
221223
+ nla_total_size(1) /* INET_DIAG_TCLASS */
224+
+ nla_total_size(4) /* INET_DIAG_MARK */
222225
+ nla_total_size(addrlen * asoc->peer.transport_count)
223226
+ nla_total_size(addrlen * addrcnt)
224227
+ nla_total_size(sizeof(struct inet_diag_meminfo))
@@ -256,7 +259,8 @@ static int sctp_tsp_dump_one(struct sctp_transport *tsp, void *p)
256259
err = inet_sctp_diag_fill(sk, assoc, rep, req,
257260
sk_user_ns(NETLINK_CB(in_skb).sk),
258261
NETLINK_CB(in_skb).portid,
259-
nlh->nlmsg_seq, 0, nlh);
262+
nlh->nlmsg_seq, 0, nlh,
263+
commp->net_admin);
260264
release_sock(sk);
261265
if (err < 0) {
262266
WARN_ON(err == -EMSGSIZE);
@@ -310,7 +314,8 @@ static int sctp_tsp_dump(struct sctp_transport *tsp, void *p)
310314
sk_user_ns(NETLINK_CB(cb->skb).sk),
311315
NETLINK_CB(cb->skb).portid,
312316
cb->nlh->nlmsg_seq,
313-
NLM_F_MULTI, cb->nlh) < 0) {
317+
NLM_F_MULTI, cb->nlh,
318+
commp->net_admin) < 0) {
314319
cb->args[3] = 1;
315320
err = 2;
316321
goto release;
@@ -320,7 +325,8 @@ static int sctp_tsp_dump(struct sctp_transport *tsp, void *p)
320325
if (inet_sctp_diag_fill(sk, assoc, skb, r,
321326
sk_user_ns(NETLINK_CB(cb->skb).sk),
322327
NETLINK_CB(cb->skb).portid,
323-
cb->nlh->nlmsg_seq, 0, cb->nlh) < 0) {
328+
cb->nlh->nlmsg_seq, 0, cb->nlh,
329+
commp->net_admin) < 0) {
324330
err = 2;
325331
goto release;
326332
}
@@ -375,7 +381,7 @@ static int sctp_ep_dump(struct sctp_endpoint *ep, void *p)
375381
sk_user_ns(NETLINK_CB(cb->skb).sk),
376382
NETLINK_CB(cb->skb).portid,
377383
cb->nlh->nlmsg_seq, NLM_F_MULTI,
378-
cb->nlh) < 0) {
384+
cb->nlh, commp->net_admin) < 0) {
379385
err = 2;
380386
goto out;
381387
}
@@ -412,6 +418,7 @@ static int sctp_diag_dump_one(struct sk_buff *in_skb,
412418
.skb = in_skb,
413419
.r = req,
414420
.nlh = nlh,
421+
.net_admin = netlink_net_capable(in_skb, CAP_NET_ADMIN),
415422
};
416423

417424
if (req->sdiag_family == AF_INET) {
@@ -447,6 +454,7 @@ static void sctp_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
447454
.skb = skb,
448455
.cb = cb,
449456
.r = r,
457+
.net_admin = netlink_net_capable(cb->skb, CAP_NET_ADMIN),
450458
};
451459

452460
/* eps hashtable dumps

0 commit comments

Comments
 (0)