diff options
| author | 2018-07-25 22:58:17 +0200 | |
|---|---|---|
| committer | 2018-08-10 21:19:56 +0200 | |
| commit | 76b863124231fb48882ea8c7d46f21583f3b3dff (patch) | |
| tree | 8365bd10edc101f2abded142f790bdc6ed895458 | |
| parent | net: sk_buff: introduce skb_memzero_explicit (diff) | |
| download | linux-dev-tg/skb_memzero.tar.xz linux-dev-tg/skb_memzero.zip | |
[WIP] net: Introduce SO_ZERO_ON_FREEtg/skb_memzero
This option causes all skbs owned by the socket to be zeored out by
skb_memzero_explicit once it's freed. This is useful if the skb contains
secrets that should be cleared from memory as soon as possible.
Signed-off-by: Thomas Gschwantner <tharre3@gmail.com>
| -rw-r--r-- | arch/alpha/include/uapi/asm/socket.h | 2 | ||||
| -rw-r--r-- | arch/ia64/include/uapi/asm/socket.h | 2 | ||||
| -rw-r--r-- | arch/mips/include/uapi/asm/socket.h | 2 | ||||
| -rw-r--r-- | arch/parisc/include/uapi/asm/socket.h | 2 | ||||
| -rw-r--r-- | arch/s390/include/uapi/asm/socket.h | 2 | ||||
| -rw-r--r-- | arch/sparc/include/uapi/asm/socket.h | 2 | ||||
| -rw-r--r-- | arch/xtensa/include/uapi/asm/socket.h | 2 | ||||
| -rw-r--r-- | include/linux/skbuff.h | 12 | ||||
| -rw-r--r-- | include/net/sock.h | 1 | ||||
| -rw-r--r-- | include/uapi/asm-generic/socket.h | 2 | ||||
| -rw-r--r-- | net/core/skbuff.c | 5 | ||||
| -rw-r--r-- | net/core/sock.c | 16 | ||||
| -rw-r--r-- | net/netlink/af_netlink.c | 6 | ||||
| -rw-r--r-- | net/unix/af_unix.c | 10 |
14 files changed, 66 insertions, 0 deletions
diff --git a/arch/alpha/include/uapi/asm/socket.h b/arch/alpha/include/uapi/asm/socket.h index be14f16149d5..ffe83d1e504a 100644 --- a/arch/alpha/include/uapi/asm/socket.h +++ b/arch/alpha/include/uapi/asm/socket.h @@ -112,4 +112,6 @@ #define SO_ZEROCOPY 60 +#define SO_ZERO_ON_FREE 61 + #endif /* _UAPI_ASM_SOCKET_H */ diff --git a/arch/ia64/include/uapi/asm/socket.h b/arch/ia64/include/uapi/asm/socket.h index 3efba40adc54..d1d01a2e744f 100644 --- a/arch/ia64/include/uapi/asm/socket.h +++ b/arch/ia64/include/uapi/asm/socket.h @@ -114,4 +114,6 @@ #define SO_ZEROCOPY 60 +#define SO_ZERO_ON_FREE 61 + #endif /* _ASM_IA64_SOCKET_H */ diff --git a/arch/mips/include/uapi/asm/socket.h b/arch/mips/include/uapi/asm/socket.h index 49c3d4795963..82d73b40029c 100644 --- a/arch/mips/include/uapi/asm/socket.h +++ b/arch/mips/include/uapi/asm/socket.h @@ -123,4 +123,6 @@ #define SO_ZEROCOPY 60 +#define SO_ZERO_ON_FREE 61 + #endif /* _UAPI_ASM_SOCKET_H */ diff --git a/arch/parisc/include/uapi/asm/socket.h b/arch/parisc/include/uapi/asm/socket.h index 1d0fdc3b5d22..5f208ee3c717 100644 --- a/arch/parisc/include/uapi/asm/socket.h +++ b/arch/parisc/include/uapi/asm/socket.h @@ -104,4 +104,6 @@ #define SO_ZEROCOPY 0x4035 +#define SO_ZERO_ON_FREE 0x4036 + #endif /* _UAPI_ASM_SOCKET_H */ diff --git a/arch/s390/include/uapi/asm/socket.h b/arch/s390/include/uapi/asm/socket.h index 3510c0fd06f4..cd2fc7aad853 100644 --- a/arch/s390/include/uapi/asm/socket.h +++ b/arch/s390/include/uapi/asm/socket.h @@ -111,4 +111,6 @@ #define SO_ZEROCOPY 60 +#define SO_ZERO_ON_FREE 61 + #endif /* _ASM_SOCKET_H */ diff --git a/arch/sparc/include/uapi/asm/socket.h b/arch/sparc/include/uapi/asm/socket.h index d58520c2e6ff..9c886b9ba9cd 100644 --- a/arch/sparc/include/uapi/asm/socket.h +++ b/arch/sparc/include/uapi/asm/socket.h @@ -101,6 +101,8 @@ #define SO_ZEROCOPY 0x003e +#define SO_ZERO_ON_FREE 0x003f + /* Security levels - as per NRL IPv6 - don't actually do anything */ #define SO_SECURITY_AUTHENTICATION 0x5001 #define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002 diff --git a/arch/xtensa/include/uapi/asm/socket.h b/arch/xtensa/include/uapi/asm/socket.h index 75a07b8119a9..3d63e4da7c3a 100644 --- a/arch/xtensa/include/uapi/asm/socket.h +++ b/arch/xtensa/include/uapi/asm/socket.h @@ -116,4 +116,6 @@ #define SO_ZEROCOPY 60 +#define SO_ZERO_ON_FREE 61 + #endif /* _XTENSA_SOCKET_H */ diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 0f8b0433b943..6cdcce4fad22 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -641,6 +641,7 @@ typedef unsigned char *sk_buff_data_t; * @no_fcs: Request NIC to treat last 4 bytes as Ethernet FCS * @csum_not_inet: use CRC32c to resolve CHECKSUM_PARTIAL * @dst_pending_confirm: need to confirm neighbour + * @zero_on_free: zero all data when freeing skb * @napi_id: id of the NAPI struct this skb came from * @secmark: security marking * @mark: Generic packet mark @@ -792,6 +793,8 @@ struct sk_buff { __u8 tc_from_ingress:1; #endif + __u8 zero_on_free:1; + #ifdef CONFIG_NET_SCHED __u16 tc_index; /* traffic control index */ #endif @@ -1052,6 +1055,15 @@ int __must_check skb_to_sgvec_nomark(struct sk_buff *skb, struct scatterlist *sg int __must_check skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len); void skb_memzero_explicit(struct sk_buff *skb); + +/** + * skb_memzero_on_free - Zero out skb once it is freed + * @skb: buffer to zero out + */ +static inline void skb_memzero_on_free(struct sk_buff *skb) +{ + skb->zero_on_free = 1; +} int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer); int __skb_pad(struct sk_buff *skb, int pad, bool free_on_error); diff --git a/include/net/sock.h b/include/net/sock.h index b3b75419eafe..a6e6e64c3e21 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -783,6 +783,7 @@ enum sock_flags { SOCK_FILTER_LOCKED, /* Filter cannot be changed anymore */ SOCK_SELECT_ERR_QUEUE, /* Wake select on error queue */ SOCK_RCU_FREE, /* wait rcu grace period in sk_destruct() */ + SOCK_ZERO_ON_FREE, }; #define SK_FLAGS_TIMESTAMP ((1UL << SOCK_TIMESTAMP) | (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE)) diff --git a/include/uapi/asm-generic/socket.h b/include/uapi/asm-generic/socket.h index 0ae758c90e54..73ad6f3f41ed 100644 --- a/include/uapi/asm-generic/socket.h +++ b/include/uapi/asm-generic/socket.h @@ -107,4 +107,6 @@ #define SO_ZEROCOPY 60 +#define SO_ZERO_ON_FREE 61 + #endif /* __ASM_GENERIC_SOCKET_H */ diff --git a/net/core/skbuff.c b/net/core/skbuff.c index df926fc0dc0b..023568142c52 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -560,6 +560,11 @@ static void skb_release_data(struct sk_buff *skb) &shinfo->dataref)) return; + if (unlikely(skb->zero_on_free)) { + pr_warn("Zeroing memory...\n"); + skb_memzero_explicit(skb); + } + for (i = 0; i < shinfo->nr_frags; i++) __skb_frag_unref(&shinfo->frags[i]); diff --git a/net/core/sock.c b/net/core/sock.c index bc2d7a37297f..2210a7e26f6c 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -472,8 +472,15 @@ int __sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) __skb_queue_tail(list, skb); spin_unlock_irqrestore(&list->lock, flags); + if (sock_flag(sk, SOCK_ZERO_ON_FREE)) { + /* if (test_bit(SOCK_ZERO_ON_FREE, &sk->sk_flags)) { */ + pr_warn("zero_on_free __sock_queue_rcv_skb\n"); + skb_memzero_on_free(skb); + } + if (!sock_flag(sk, SOCK_DEAD)) sk->sk_data_ready(sk); + return 0; } EXPORT_SYMBOL(__sock_queue_rcv_skb); @@ -1070,6 +1077,11 @@ set_rcvbuf: } break; + case SO_ZERO_ON_FREE: + pr_warn("Set SOCK_ZERO_ON_FREE\n"); + sock_valbool_flag(sk, SOCK_ZERO_ON_FREE, valbool); + break; + default: ret = -ENOPROTOOPT; break; @@ -1403,6 +1415,10 @@ int sock_getsockopt(struct socket *sock, int level, int optname, v.val = sock_flag(sk, SOCK_ZEROCOPY); break; + case SO_ZERO_ON_FREE: + v.val = sock_flag(sk, SOCK_ZERO_ON_FREE); + break; + default: /* We implement the SO_SNDLOWAT etc to not be settable * (1003.1g 7). diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 393573a99a5a..11f967ce8d69 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -1989,6 +1989,12 @@ static int netlink_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, } scm_recv(sock, msg, &scm, flags); + + /* if (test_bit(SOCK_ZERO_ON_FREE, &sock->flags)) { */ + if (sock_flag(sk, SOCK_ZERO_ON_FREE)) { + pr_warn("zero_on_free af_netlink\n"); + skb_memzero_on_free(skb); + } out: netlink_rcv_wake(sk); return err ? : copied; diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index e5473c03d667..f6b620cdfb64 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -1836,6 +1836,11 @@ static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg, if (err < 0) return err; + if (sock_flag(sk, SOCK_ZERO_ON_FREE)) { + pr_warn("zero_on_free af_unix sendmsg\n"); + skb_memzero_on_free(skb); + } + err = -EOPNOTSUPP; if (msg->msg_flags&MSG_OOB) goto out_err; @@ -2170,6 +2175,11 @@ static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg, scm_recv(sock, msg, &scm, flags); + if (sock_flag(sk, SOCK_ZERO_ON_FREE)) { + pr_warn("zero_on_free af_unix\n"); + skb_memzero_on_free(skb); + } + out_free: skb_free_datagram(sk, skb); mutex_unlock(&u->iolock); |
