Skip to content

Commit d9be15a

Browse files
UbuntuDong Sunchao
authored andcommitted
fix-bug:restrict SO_PASS{CRED,SEC} dump to supported socket families while kernel>=6.16.0
Linux 6.16+ restricts SO_PASSCRED and SO_PASSSEC to AF_UNIX, AF_NETLINK, and AF_BLUETOOTH. This patch updates criu/sockets.c to check the socket family via getsockopt(SO_DOMAIN) before dumping these options, avoiding EOPNOTSUPP errors. Test logic updated to skip SO_PASSCRED and SO_PASSSEC validation when unsupported. Signed-off-by: Dong Sunchao <[email protected]>
1 parent 17a5c6e commit d9be15a

File tree

2 files changed

+26
-8
lines changed

2 files changed

+26
-8
lines changed

criu/sockets.c

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -635,8 +635,9 @@ int restore_socket_opts(int sk, SkOptsEntry *soe)
635635
int do_dump_opt(int sk, int level, int name, void *val, int len)
636636
{
637637
socklen_t aux = len;
638+
int result = getsockopt(sk, level, name, val, &aux);
638639

639-
if (getsockopt(sk, level, name, val, &aux) < 0) {
640+
if (result < 0 && errno != -ENOPROTOOPT) {
640641
pr_perror("Can't get %d:%d opt", level, name);
641642
return -1;
642643
}
@@ -654,6 +655,7 @@ int dump_socket_opts(int sk, SkOptsEntry *soe)
654655
int ret = 0, val;
655656
struct timeval tv;
656657
struct linger so_linger = { 0, 0 };
658+
int family;
657659

658660
ret |= dump_opt(sk, SOL_SOCKET, SO_SNDBUF, &soe->so_sndbuf);
659661
ret |= dump_opt(sk, SOL_SOCKET, SO_RCVBUF, &soe->so_rcvbuf);
@@ -688,13 +690,24 @@ int dump_socket_opts(int sk, SkOptsEntry *soe)
688690
soe->so_reuseport = val ? true : false;
689691
soe->has_so_reuseport = true;
690692

691-
ret |= dump_opt(sk, SOL_SOCKET, SO_PASSCRED, &val);
692-
soe->has_so_passcred = true;
693-
soe->so_passcred = val ? true : false;
693+
if (dump_opt(sk, SOL_SOCKET, SO_DOMAIN, &family))
694+
return -1;
695+
696+
switch (family) {
697+
case AF_UNIX:
694698

695-
ret |= dump_opt(sk, SOL_SOCKET, SO_PASSSEC, &val);
696-
soe->has_so_passsec = true;
697-
soe->so_passsec = val ? true : false;
699+
case AF_NETLINK:
700+
ret |= dump_opt(sk, SOL_SOCKET, SO_PASSCRED, &val);
701+
soe->has_so_passcred = true;
702+
soe->so_passcred = val ? true : false;
703+
704+
ret |= dump_opt(sk, SOL_SOCKET, SO_PASSSEC, &val);
705+
soe->has_so_passsec = true;
706+
soe->so_passsec = val ? true : false;
707+
break;
708+
default:
709+
break;
710+
}
698711

699712
ret |= dump_opt(sk, SOL_SOCKET, SO_DONTROUTE, &val);
700713
soe->has_so_dontroute = true;

test/zdtm/static/sock_opts00.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,13 @@ int main(int argc, char **argv)
8383
pr_perror("can't verify %s", vname[i].name);
8484
return 1;
8585
}
86-
86+
//for kernel version >= 6.16.0 Restrict
87+
//SO_PASS{CRED,PIDFD,SEC} to AF_{UNIX,NETLINK,BLUETOOTH}
8788
if (val[i] != rval) {
89+
if (vname[i].opt == SO_PASSCRED || vname[i].opt == SO_PASSSEC) {
90+
continue;
91+
}
92+
8893
errno = 0;
8994
fail("%s changed: %d -> %d", vname[i].name, val[i], rval);
9095
return 1;

0 commit comments

Comments
 (0)