Message ID | 20201105152053.13921-1-khorenko@virtuozzo.com |
---|---|
State | New |
Series | "ve/net/core: allow to call setsockopt(SO_RCVBUFFORCE) from Containers" |
Headers | show |
diff --git a/net/core/sock.c b/net/core/sock.c index 07ea42f976cf..44e91c8c0f0a 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -793,6 +793,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname, goto set_sndbuf; case SO_RCVBUF: +unpriv_rcvbuf: /* Don't error on this BSD doesn't and if you think * about it this is right. Otherwise apps have to * play 'guess the biggest size' games. RCVBUF/SNDBUF @@ -824,11 +825,15 @@ int sock_setsockopt(struct socket *sock, int level, int optname, break; case SO_RCVBUFFORCE: - if (!capable(CAP_NET_ADMIN)) { + if (!ve_capable(CAP_NET_ADMIN)) { ret = -EPERM; break; } + /* nft utility uses this sockopt in CentOS 8 env */ + if (!ve_is_super(get_exec_env())) + goto unpriv_rcvbuf; + /* No negative values (to prevent underflow, as val will be * multiplied by 2). */
On 11/05/2020 06:20 PM, Konstantin Khorenko wrote: > "nft" util (in CentOS 8 environment) does use setsockopt(SO_RCVBUFFORCE) > unconditionally, so we have to allow it from inside a Container. > > At the same time we don't want to allow a Container to set too much > memory for a socket, so just threat SO_RCVBUFFORCE like SO_RCVBUF if > called inside a Container. > > Simple rule to test: > > # NFT=/usr/sbin/nft ./run-tests.sh -v -g testcases/nft-f/0011manydefines_0 > > which fails inside a Container because of not enough rcb buffer because > of failed > setsockopt(3, SOL_SOCKET, SO_RCVBUFFORCE, [10561584], 4) = -1 > EPERM (Operation not permitted) https://jira.sw.ru/browse/PSBM-121791 > Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com> > --- > net/core/sock.c | 7 ++++++- > 1 file changed, 6 insertions(+), 1 deletion(-) > > diff --git a/net/core/sock.c b/net/core/sock.c > index 07ea42f976cf..44e91c8c0f0a 100644 > --- a/net/core/sock.c > +++ b/net/core/sock.c > @@ -793,6 +793,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname, > goto set_sndbuf; > > case SO_RCVBUF: > +unpriv_rcvbuf: > /* Don't error on this BSD doesn't and if you think > * about it this is right. Otherwise apps have to > * play 'guess the biggest size' games. RCVBUF/SNDBUF > @@ -824,11 +825,15 @@ int sock_setsockopt(struct socket *sock, int level, int optname, > break; > > case SO_RCVBUFFORCE: > - if (!capable(CAP_NET_ADMIN)) { > + if (!ve_capable(CAP_NET_ADMIN)) { > ret = -EPERM; > break; > } > > + /* nft utility uses this sockopt in CentOS 8 env */ > + if (!ve_is_super(get_exec_env())) > + goto unpriv_rcvbuf; > + > /* No negative values (to prevent underflow, as val will be > * multiplied by 2). > */ >
"nft" util (in CentOS 8 environment) does use setsockopt(SO_RCVBUFFORCE) unconditionally, so we have to allow it from inside a Container. At the same time we don't want to allow a Container to set too much memory for a socket, so just threat SO_RCVBUFFORCE like SO_RCVBUF if called inside a Container. Simple rule to test: # NFT=/usr/sbin/nft ./run-tests.sh -v -g testcases/nft-f/0011manydefines_0 which fails inside a Container because of not enough rcb buffer because of failed setsockopt(3, SOL_SOCKET, SO_RCVBUFFORCE, [10561584], 4) = -1 EPERM (Operation not permitted) Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com> --- net/core/sock.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)