Hi Everyone, I'm trying to run through the example at https://www.kernel.org/doc/html/latest/networking/tls.html#kernel-tls . I'm working on Fedora 31 x86_64 (fully patched). Running my program results in: $ ./ktls setsockopt failed, 2, No such file or directory I observed: $ cat /proc/sys/net/ipv4/tcp_available_ulp $ Is there a way to enable ULP at boot? Or is this a kernel config option? Or maybe I am doing something else wrong? Below is the sample code. Jeff ============================== #include <stdio.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <sys/socket.h> #include <sys/types.h> #include <linux/tls.h> #include <netinet/ip.h> #include <netinet/tcp.h> int main() { int sock = socket(AF_INET, SOCK_STREAM, 0); if (sock == -1) { printf("socket failed, %d, %s\n", errno, strerror(errno)); return 1; } if (setsockopt(sock, SOL_TCP, TCP_ULP, "tls", sizeof("tls")) == -1 ) { printf("setsockopt failed, %d, %s\n", errno, strerror(errno)); return 1; } close (sock); return 0; }
Hello, I think you need to load "tls" kernel module first. Regards, Alex On Fri, Nov 29, 2019 at 11:37 AM Jeffrey Walton <noloader@gmail.com> wrote:
Hi Everyone,
I'm trying to run through the example at https://www.kernel.org/doc/html/latest/networking/tls.html#kernel-tls .
I'm working on Fedora 31 x86_64 (fully patched). Running my program results in:
$ ./ktls setsockopt failed, 2, No such file or directory
I observed:
$ cat /proc/sys/net/ipv4/tcp_available_ulp $
Is there a way to enable ULP at boot? Or is this a kernel config option? Or maybe I am doing something else wrong?
Below is the sample code.
Jeff
==============================
#include <stdio.h> #include <unistd.h> #include <errno.h> #include <string.h>
#include <sys/socket.h> #include <sys/types.h>
#include <linux/tls.h> #include <netinet/ip.h> #include <netinet/tcp.h>
int main() { int sock = socket(AF_INET, SOCK_STREAM, 0); if (sock == -1) { printf("socket failed, %d, %s\n", errno, strerror(errno)); return 1; }
if (setsockopt(sock, SOL_TCP, TCP_ULP, "tls", sizeof("tls")) == -1 ) { printf("setsockopt failed, %d, %s\n", errno, strerror(errno)); return 1; }
close (sock); return 0; }
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
On Fri, Nov 29, 2019 at 02:36:10PM -0500, Jeffrey Walton wrote:
I'm trying to run through the example at https://www.kernel.org/doc/html/latest/networking/tls.html#kernel-tls .
I'm working on Fedora 31 x86_64 (fully patched). Running my program results in:
$ ./ktls setsockopt failed, 2, No such file or directory
I observed:
$ cat /proc/sys/net/ipv4/tcp_available_ulp $
Is there a way to enable ULP at boot? Or is this a kernel config option? Or maybe I am doing something else wrong?
strace gives me: ... socket(AF_INET, SOCK_STREAM, IPPROTO_IP) = 3 setsockopt(3, SOL_TCP, TCP_ULP, [7564404], 4) = -1 ENOENT (No such file or directory) fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0x2), ...}) = 0 brk(NULL) = 0x55d76b14e000 brk(0x55d76b16f000) = 0x55d76b16f000 write(1, "setsockopt failed, 2, No such fi"..., 48setsockopt failed, 2, No such file or directory ) = 48 exit_group(1) = ? +++ exited with 1 +++ $ grep TLS /boot/config-4.19.0-6-amd64 CONFIG_HAVE_COPY_THREAD_TLS=y # CONFIG_TLS is not set # CONFIG_VIDEO_IVTV_DEPRECATED_IOCTLS is not set So you probably need to rebuild the kernel with CONFIG_TLS to get this working. -- Valentin
On Fri, Nov 29, 2019 at 2:48 PM Valentin Vidić <vvidic@valentin-vidic.from.hr> wrote:
On Fri, Nov 29, 2019 at 02:36:10PM -0500, Jeffrey Walton wrote:
I'm trying to run through the example at https://www.kernel.org/doc/html/latest/networking/tls.html#kernel-tls .
I'm working on Fedora 31 x86_64 (fully patched). Running my program results in:
$ ./ktls setsockopt failed, 2, No such file or directory
I observed:
$ cat /proc/sys/net/ipv4/tcp_available_ulp $
Is there a way to enable ULP at boot? Or is this a kernel config option? Or maybe I am doing something else wrong?
strace gives me:
... socket(AF_INET, SOCK_STREAM, IPPROTO_IP) = 3 setsockopt(3, SOL_TCP, TCP_ULP, [7564404], 4) = -1 ENOENT (No such file or directory) fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0x2), ...}) = 0 brk(NULL) = 0x55d76b14e000 brk(0x55d76b16f000) = 0x55d76b16f000 write(1, "setsockopt failed, 2, No such fi"..., 48setsockopt failed, 2, No such file or directory ) = 48 exit_group(1) = ? +++ exited with 1 +++
$ grep TLS /boot/config-4.19.0-6-amd64 CONFIG_HAVE_COPY_THREAD_TLS=y # CONFIG_TLS is not set # CONFIG_VIDEO_IVTV_DEPRECATED_IOCTLS is not set
So you probably need to rebuild the kernel with CONFIG_TLS to get this working.
Thanks Valentin. Here's what I am seeing: $ grep TLS /boot/config-5.3.12-300.fc31.x86_64 CONFIG_HAVE_COPY_THREAD_TLS=y CONFIG_TLS=m ... I believe the 'm' means a loadable module. But: $ insmod tls insmod: ERROR: could not load module tls: No such file or directory Jeff
On Fri, Nov 29, 2019 at 2:57 PM Jeffrey Walton <noloader@gmail.com> wrote:
On Fri, Nov 29, 2019 at 2:48 PM Valentin Vidić <vvidic@valentin-vidic.from.hr> wrote:
On Fri, Nov 29, 2019 at 02:36:10PM -0500, Jeffrey Walton wrote:
I'm trying to run through the example at https://www.kernel.org/doc/html/latest/networking/tls.html#kernel-tls .
I'm working on Fedora 31 x86_64 (fully patched). Running my program results in:
$ ./ktls setsockopt failed, 2, No such file or directory
I observed:
$ cat /proc/sys/net/ipv4/tcp_available_ulp $
Is there a way to enable ULP at boot? Or is this a kernel config option? Or maybe I am doing something else wrong?
strace gives me:
... socket(AF_INET, SOCK_STREAM, IPPROTO_IP) = 3 setsockopt(3, SOL_TCP, TCP_ULP, [7564404], 4) = -1 ENOENT (No such file or directory) fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0x2), ...}) = 0 brk(NULL) = 0x55d76b14e000 brk(0x55d76b16f000) = 0x55d76b16f000 write(1, "setsockopt failed, 2, No such fi"..., 48setsockopt failed, 2, No such file or directory ) = 48 exit_group(1) = ? +++ exited with 1 +++
$ grep TLS /boot/config-4.19.0-6-amd64 CONFIG_HAVE_COPY_THREAD_TLS=y # CONFIG_TLS is not set # CONFIG_VIDEO_IVTV_DEPRECATED_IOCTLS is not set
So you probably need to rebuild the kernel with CONFIG_TLS to get this working.
Thanks Valentin.
Here's what I am seeing:
$ grep TLS /boot/config-5.3.12-300.fc31.x86_64 CONFIG_HAVE_COPY_THREAD_TLS=y CONFIG_TLS=m ...
I believe the 'm' means a loadable module. But:
$ insmod tls insmod: ERROR: could not load module tls: No such file or directory
My bad, I needed modprobe, not insmod. So now I am at: $ gcc -Wall -g2 -O1 ktls.c -o ktls $ ./ktls setsockopt failed, 524, Unknown error 524 Jeff
On Fri, Nov 29, 2019 at 3:04 PM Jeffrey Walton <noloader@gmail.com> wrote:
... So now I am at:
$ gcc -Wall -g2 -O1 ktls.c -o ktls $ ./ktls setsockopt failed, 524, Unknown error 524
Now open in the Fedora bug tracker: https://bugzilla.redhat.com/show_bug.cgi?id=1778348
Hello, I think reason is here: https://github.com/torvalds/linux/blob/386403a115f95997c2715691226e11a7b5cff... You need to setsockopt() ULP ktls on CONNECTION socket. Regards, Alex On Sat, Nov 30, 2019 at 7:39 AM Jeffrey Walton <noloader@gmail.com> wrote:
On Fri, Nov 29, 2019 at 3:04 PM Jeffrey Walton <noloader@gmail.com> wrote:
... So now I am at:
$ gcc -Wall -g2 -O1 ktls.c -o ktls $ ./ktls setsockopt failed, 524, Unknown error 524
Now open in the Fedora bug tracker: https://bugzilla.redhat.com/show_bug.cgi?id=1778348
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
On Fri, 29 Nov 2019 23:37:35 -0500, Jeffrey Walton said: repl: bad addresses: Valentin VidiD <vvidic@valentin-vidic.from.hr> -- no mailbox in address, only a phrase (Valentin VidiD)
On Fri, Nov 29, 2019 at 3:04 PM Jeffrey Walton <noloader@gmail.com> wrote:
... So now I am at:
$ gcc -Wall -g2 -O1 ktls.c -o ktls $ ./ktls setsockopt failed, 524, Unknown error 524
Now open in the Fedora bug tracker: https://bugzilla.redhat.com/show_bug.cgi?id=1778348
Looks like the 'unknown error' issue is a glibc strerror() problem. On the kernel side, git blame says: [/usr/src/linux-next] git blame include/linux/errno.h | grep -C 5 524 ^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 22) ^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 23) /* Defined for the NFSv3 protocol */ ^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 24) #define EBADHANDLE 521 /* Illegal NFS file handle */ ^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 25) #define ENOTSYNC 522 /* Update synchronization mismatch */ ^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 26) #define EBADCOOKIE 523 /* Cookie is stale */ ^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 27) #define ENOTSUPP 524 /* Operation is not supported */ ^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 28) #define ETOOSMALL 525 /* Buffer or request is too small */ ^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 29) #define ESERVERFAULT 526 /* An untranslatable error occurred */ So I'm mystified why glibc's strerror() doesn't handle it. Though I think Alexander is correct on why the kernel returns ENOTSUPP. I've updated the bugzilla entry.
"Valdis Klētnieks" <valdis.kletnieks@vt.edu> writes:
On Fri, 29 Nov 2019 23:37:35 -0500, Jeffrey Walton said:
repl: bad addresses: Valentin VidiD <vvidic@valentin-vidic.from.hr> -- no mailbox in address, only a phrase (Valentin VidiD)
On Fri, Nov 29, 2019 at 3:04 PM Jeffrey Walton <noloader@gmail.com> wrote:
... So now I am at:
$ gcc -Wall -g2 -O1 ktls.c -o ktls $ ./ktls setsockopt failed, 524, Unknown error 524
Now open in the Fedora bug tracker: https://bugzilla.redhat.com/show_bug.cgi?id=1778348
Looks like the 'unknown error' issue is a glibc strerror() problem. On the kernel side, git blame says:
[/usr/src/linux-next] git blame include/linux/errno.h | grep -C 5 524 ^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 22) ^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 23) /* Defined for the NFSv3 protocol */ ^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 24) #define EBADHANDLE 521 /* Illegal NFS file handle */ ^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 25) #define ENOTSYNC 522 /* Update synchronization mismatch */ ^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 26) #define EBADCOOKIE 523 /* Cookie is stale */ ^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 27) #define ENOTSUPP 524 /* Operation is not supported */ ^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 28) #define ETOOSMALL 525 /* Buffer or request is too small */ ^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 29) #define ESERVERFAULT 526 /* An untranslatable error occurred */
So I'm mystified why glibc's strerror() doesn't handle it. Though I think Alexander is correct on why the kernel returns ENOTSUPP.
include/linux/errno.h is kernel internal only. The UAPI header is uapi/linux/errno.h, which is an alias for uapi/asm/errno.h. There is no 524 in include/uapi/asm-generic/errno.h or include/uapi/asm-generic/errno-base.h The codes in include/linux/errno.h should be translated for userspace. This does look like a bug in the kernel tls code. Bjørn
On Sat, 30 Nov 2019 09:13:35 +0100, Bj�rn Mork said:
include/linux/errno.h is kernel internal only. The UAPI header is uapi/linux/errno.h, which is an alias for uapi/asm/errno.h. There is no 524 in include/uapi/asm-generic/errno.h or include/uapi/asm-generic/errno-base.h
The codes in include/linux/errno.h should be translated for userspace. This does look like a bug in the kernel tls code.
Hmm... git grep ENOTSUPP has 1,516 hits. I haven't checked if it gets translated in one place, or if it gets done in a kazillion places.
"Valdis Klētnieks" <valdis.kletnieks@vt.edu> writes:
On Sat, 30 Nov 2019 09:13:35 +0100, Bjrn Mork said:
include/linux/errno.h is kernel internal only. The UAPI header is uapi/linux/errno.h, which is an alias for uapi/asm/errno.h. There is no 524 in include/uapi/asm-generic/errno.h or include/uapi/asm-generic/errno-base.h
The codes in include/linux/errno.h should be translated for userspace. This does look like a bug in the kernel tls code.
Hmm... git grep ENOTSUPP has 1,516 hits. I haven't checked if it gets translated in one place, or if it gets done in a kazillion places.
Definitely more than one, but probably less than a kazillion. I believe the userspace wrappers usually translates errors from the lower levels to something conforming to the documented userspace API. My version of setsockopt(2) says RETURN VALUE On success, zero is returned for the standard options. On error, -1 is returned, and errno is set appropriately. Netfilter allows the programmer to define custom socket op‐ tions with associated handlers; for such options, the re‐ turn value on success is the value returned by the handler. ERRORS EBADF The argument sockfd is not a valid file descrip‐ tor. EFAULT The address pointed to by optval is not in a valid part of the process address space. For getsockopt(), this error may also be returned if optlen is not in a valid part of the process ad‐ dress space. EINVAL optlen invalid in setsockopt(). In some cases this error can also occur for an invalid value in optval (e.g., for the IP_ADD_MEMBERSHIP option described in ip(7)). ENOPROTOOPT The option is unknown at the level indicated. ENOTSOCK The file descriptor sockfd does not refer to a socket. If you look at e.g. udp_lib_setsockopt() you'll see that it conforms strictly to this. I don't know why do_tcp_setsockopt() doesn't. Bjørn
On Sat, 30 Nov 2019 11:10:50 +0100, Bj�rn Mork said:
My version of setsockopt(2) says (...) ERRORS EBADF The argument sockfd is not a valid file descrip‐ tor.
Note that there is no general *guarantee* that a syscall cannot return any values other than the ones in the manpage.
If you look at e.g. udp_lib_setsockopt() you'll see that it conforms strictly to this. I don't know why do_tcp_setsockopt() doesn't.
Probably because those are the only errors that the UDP version can hit, but the TCP case can hit cases like "socket must be in a connected state" and possibly other error codes. Now, I admit wondering why it uses ENOTSUPP rather than ENOTCONN for this particular case.
ENOTSUPP is not available in userspace: setsockopt failed, 524, Unknown error 524 Signed-off-by: Valentin Vidic <vvidic@valentin-vidic.from.hr> --- net/tls/tls_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c index bdca31ffe6da..5830b8e02a36 100644 --- a/net/tls/tls_main.c +++ b/net/tls/tls_main.c @@ -496,7 +496,7 @@ static int do_tls_setsockopt_conf(struct sock *sk, char __user *optval, /* check version */ if (crypto_info->version != TLS_1_2_VERSION && crypto_info->version != TLS_1_3_VERSION) { - rc = -ENOTSUPP; + rc = -EINVAL; goto err_crypto_info; } @@ -723,7 +723,7 @@ static int tls_init(struct sock *sk) * share the ulp context. */ if (sk->sk_state != TCP_ESTABLISHED) - return -ENOTSUPP; + return -ENOTCONN; /* allocate tls context */ write_lock_bh(&sk->sk_callback_lock); -- 2.20.1
On Sat, Nov 30, 2019 at 7:55 AM Valentin Vidic <vvidic@valentin-vidic.from.hr> wrote:
ENOTSUPP is not available in userspace:
setsockopt failed, 524, Unknown error 524
Signed-off-by: Valentin Vidic <vvidic@valentin-vidic.from.hr> --- net/tls/tls_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c index bdca31ffe6da..5830b8e02a36 100644 --- a/net/tls/tls_main.c +++ b/net/tls/tls_main.c @@ -496,7 +496,7 @@ static int do_tls_setsockopt_conf(struct sock *sk, char __user *optval, /* check version */ if (crypto_info->version != TLS_1_2_VERSION && crypto_info->version != TLS_1_3_VERSION) { - rc = -ENOTSUPP; + rc = -EINVAL; goto err_crypto_info; }
A quick comment... ENOTSUP is available in <errno.h> [0] if you want to stay in the "not supported" path. When searching for "Unknown error 524", I read another kernel module switched to EOPNOTSUPP [1] According to [2], EOPNOTSUPP is not as bad because there is a userland message. Personally, I am mostly indifferent. [0] http://man7.org/linux/man-pages/man3/errno.3.html [1] https://lkml.org/lkml/2019/5/16/883 [2] https://patchwork.ozlabs.org/patch/309627/ Jeff
On Sat, Nov 30, 2019 at 08:15:56AM -0500, Jeffrey Walton wrote:
On Sat, Nov 30, 2019 at 7:55 AM Valentin Vidic <vvidic@valentin-vidic.from.hr> wrote:
ENOTSUPP is not available in userspace:
setsockopt failed, 524, Unknown error 524
Signed-off-by: Valentin Vidic <vvidic@valentin-vidic.from.hr> --- net/tls/tls_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c index bdca31ffe6da..5830b8e02a36 100644 --- a/net/tls/tls_main.c +++ b/net/tls/tls_main.c @@ -496,7 +496,7 @@ static int do_tls_setsockopt_conf(struct sock *sk, char __user *optval, /* check version */ if (crypto_info->version != TLS_1_2_VERSION && crypto_info->version != TLS_1_3_VERSION) { - rc = -ENOTSUPP; + rc = -EINVAL; goto err_crypto_info; }
A quick comment... ENOTSUP is available in <errno.h> [0] if you want to stay in the "not supported" path.
For this case I put EINVAL because other similar checks in do_tls_setsockopt_conf already use that (for example invalid value for crypto_info->cipher_type). -- Valentin
participants (6)
-
Alexander Mihalicyn -
Bjørn Mork -
Jeffrey Walton -
Valdis Klētnieks -
Valentin Vidic -
Valentin Vidić