[rh7] ve/net/core: allow to call setsockopt(SO_RCVBUFFORCE) from Containers

Submitted by Konstantin Khorenko on Nov. 5, 2020, 3:20 p.m.

Details

Message ID 20201105152053.13921-1-khorenko@virtuozzo.com
State New
Series "ve/net/core: allow to call setsockopt(SO_RCVBUFFORCE) from Containers"
Headers show

Commit Message

Konstantin Khorenko Nov. 5, 2020, 3:20 p.m.
"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(-)

Patch hide | download patch | download mbox

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).
 		 */

Comments

Konstantin Khorenko Nov. 5, 2020, 3:28 p.m.
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).
>  		 */
>