Skip to content

Commit dfec091

Browse files
Paolo Abenidavem330
authored andcommitted
dn_getsockoptdecnet: move nf_{get/set}sockopt outside sock lock
After commit 3f34cfa ("netfilter: on sockopt() acquire sock lock only in the required scope"), the caller of nf_{get/set}sockopt() must not hold any lock, but, in such changeset, I forgot to cope with DECnet. This commit addresses the issue moving the nf call outside the lock, in the dn_{get,set}sockopt() with the same schema currently used by ipv4 and ipv6. Also moves the unhandled sockopts of the end of the main switch statements, to improve code readability. Reported-by: Petr Vandrovec <[email protected]> BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=198791#c2 Fixes: 3f34cfa ("netfilter: on sockopt() acquire sock lock only in the required scope") Signed-off-by: Paolo Abeni <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 7dcf688 commit dfec091

File tree

1 file changed

+33
-29
lines changed

1 file changed

+33
-29
lines changed

net/decnet/af_decnet.c

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1338,6 +1338,12 @@ static int dn_setsockopt(struct socket *sock, int level, int optname, char __use
13381338
lock_sock(sk);
13391339
err = __dn_setsockopt(sock, level, optname, optval, optlen, 0);
13401340
release_sock(sk);
1341+
#ifdef CONFIG_NETFILTER
1342+
/* we need to exclude all possible ENOPROTOOPTs except default case */
1343+
if (err == -ENOPROTOOPT && optname != DSO_LINKINFO &&
1344+
optname != DSO_STREAM && optname != DSO_SEQPACKET)
1345+
err = nf_setsockopt(sk, PF_DECnet, optname, optval, optlen);
1346+
#endif
13411347

13421348
return err;
13431349
}
@@ -1445,15 +1451,6 @@ static int __dn_setsockopt(struct socket *sock, int level,int optname, char __us
14451451
dn_nsp_send_disc(sk, 0x38, 0, sk->sk_allocation);
14461452
break;
14471453

1448-
default:
1449-
#ifdef CONFIG_NETFILTER
1450-
return nf_setsockopt(sk, PF_DECnet, optname, optval, optlen);
1451-
#endif
1452-
case DSO_LINKINFO:
1453-
case DSO_STREAM:
1454-
case DSO_SEQPACKET:
1455-
return -ENOPROTOOPT;
1456-
14571454
case DSO_MAXWINDOW:
14581455
if (optlen != sizeof(unsigned long))
14591456
return -EINVAL;
@@ -1501,6 +1498,12 @@ static int __dn_setsockopt(struct socket *sock, int level,int optname, char __us
15011498
return -EINVAL;
15021499
scp->info_loc = u.info;
15031500
break;
1501+
1502+
case DSO_LINKINFO:
1503+
case DSO_STREAM:
1504+
case DSO_SEQPACKET:
1505+
default:
1506+
return -ENOPROTOOPT;
15041507
}
15051508

15061509
return 0;
@@ -1514,6 +1517,20 @@ static int dn_getsockopt(struct socket *sock, int level, int optname, char __use
15141517
lock_sock(sk);
15151518
err = __dn_getsockopt(sock, level, optname, optval, optlen, 0);
15161519
release_sock(sk);
1520+
#ifdef CONFIG_NETFILTER
1521+
if (err == -ENOPROTOOPT && optname != DSO_STREAM &&
1522+
optname != DSO_SEQPACKET && optname != DSO_CONACCEPT &&
1523+
optname != DSO_CONREJECT) {
1524+
int len;
1525+
1526+
if (get_user(len, optlen))
1527+
return -EFAULT;
1528+
1529+
err = nf_getsockopt(sk, PF_DECnet, optname, optval, &len);
1530+
if (err >= 0)
1531+
err = put_user(len, optlen);
1532+
}
1533+
#endif
15171534

15181535
return err;
15191536
}
@@ -1579,26 +1596,6 @@ static int __dn_getsockopt(struct socket *sock, int level,int optname, char __us
15791596
r_data = &link;
15801597
break;
15811598

1582-
default:
1583-
#ifdef CONFIG_NETFILTER
1584-
{
1585-
int ret, len;
1586-
1587-
if (get_user(len, optlen))
1588-
return -EFAULT;
1589-
1590-
ret = nf_getsockopt(sk, PF_DECnet, optname, optval, &len);
1591-
if (ret >= 0)
1592-
ret = put_user(len, optlen);
1593-
return ret;
1594-
}
1595-
#endif
1596-
case DSO_STREAM:
1597-
case DSO_SEQPACKET:
1598-
case DSO_CONACCEPT:
1599-
case DSO_CONREJECT:
1600-
return -ENOPROTOOPT;
1601-
16021599
case DSO_MAXWINDOW:
16031600
if (r_len > sizeof(unsigned long))
16041601
r_len = sizeof(unsigned long);
@@ -1630,6 +1627,13 @@ static int __dn_getsockopt(struct socket *sock, int level,int optname, char __us
16301627
r_len = sizeof(unsigned char);
16311628
r_data = &scp->info_rem;
16321629
break;
1630+
1631+
case DSO_STREAM:
1632+
case DSO_SEQPACKET:
1633+
case DSO_CONACCEPT:
1634+
case DSO_CONREJECT:
1635+
default:
1636+
return -ENOPROTOOPT;
16331637
}
16341638

16351639
if (r_data) {

0 commit comments

Comments
 (0)