Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

lsm: Add LSM hook security_unix_find

Add an LSM hook security_unix_find.

This hook is called to check the path of a named UNIX socket before a
connection is initiated. The peer socket may be inspected as well.

Why existing hooks are unsuitable:

Existing socket hooks, security_unix_stream_connect(),
security_unix_may_send(), and security_socket_connect() don't provide
TOCTOU-free / namespace independent access to the paths of sockets.

(1) We cannot resolve the path from the struct sockaddr in existing hooks.
This requires another path lookup. A change in the path between the
two lookups will cause a TOCTOU bug.

(2) We cannot use the struct path from the listening socket, because it
may be bound to a path in a different namespace than the caller,
resulting in a path that cannot be referenced at policy creation time.

Consumers of the hook wishing to reference @other are responsible
for acquiring the unix_state_lock and checking for the SOCK_DEAD flag
therein, ensuring the socket hasn't died since lookup.

Cc: Günther Noack <gnoack3000@gmail.com>
Cc: Tingmao Wang <m@maowtm.org>
Cc: Mickaël Salaün <mic@digikod.net>
Cc: Paul Moore <paul@paul-moore.com>
Signed-off-by: Justin Suess <utilityemal77@gmail.com>
Signed-off-by: Günther Noack <gnoack3000@gmail.com>
Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
Acked-by: Paul Moore <paul@paul-moore.com>
Link: https://lore.kernel.org/r/20260327164838.38231-2-gnoack3000@gmail.com
Signed-off-by: Mickaël Salaün <mic@digikod.net>

authored by

Justin Suess and committed by
Mickaël Salaün
eb25e202 64617ec0

+43 -3
+5
include/linux/lsm_hook_defs.h
··· 317 317 LSM_HOOK(int, 0, watch_key, struct key *key) 318 318 #endif /* CONFIG_SECURITY && CONFIG_KEY_NOTIFICATIONS */ 319 319 320 + #if defined(CONFIG_SECURITY_NETWORK) && defined(CONFIG_SECURITY_PATH) 321 + LSM_HOOK(int, 0, unix_find, const struct path *path, struct sock *other, 322 + int flags) 323 + #endif /* CONFIG_SECURITY_NETWORK && CONFIG_SECURITY_PATH */ 324 + 320 325 #ifdef CONFIG_SECURITY_NETWORK 321 326 LSM_HOOK(int, 0, unix_stream_connect, struct sock *sock, struct sock *other, 322 327 struct sock *newsk)
+11
include/linux/security.h
··· 1932 1932 } 1933 1933 #endif /* CONFIG_SECURITY_NETWORK */ 1934 1934 1935 + #if defined(CONFIG_SECURITY_NETWORK) && defined(CONFIG_SECURITY_PATH) 1936 + 1937 + int security_unix_find(const struct path *path, struct sock *other, int flags); 1938 + 1939 + #else /* CONFIG_SECURITY_NETWORK && CONFIG_SECURITY_PATH */ 1940 + static inline int security_unix_find(const struct path *path, struct sock *other, int flags) 1941 + { 1942 + return 0; 1943 + } 1944 + #endif /* CONFIG_SECURITY_NETWORK && CONFIG_SECURITY_PATH */ 1945 + 1935 1946 #ifdef CONFIG_SECURITY_INFINIBAND 1936 1947 int security_ib_pkey_access(void *sec, u64 subnet_prefix, u16 pkey); 1937 1948 int security_ib_endport_manage_subnet(void *sec, const char *name, u8 port_num);
+7 -3
net/unix/af_unix.c
··· 1231 1231 goto path_put; 1232 1232 1233 1233 err = -EPROTOTYPE; 1234 - if (sk->sk_type == type) 1235 - touch_atime(&path); 1236 - else 1234 + if (sk->sk_type != type) 1237 1235 goto sock_put; 1236 + 1237 + err = security_unix_find(&path, sk, flags); 1238 + if (err) 1239 + goto sock_put; 1240 + 1241 + touch_atime(&path); 1238 1242 1239 1243 path_put(&path); 1240 1244
+20
security/security.c
··· 4732 4732 4733 4733 #endif /* CONFIG_SECURITY_NETWORK */ 4734 4734 4735 + #if defined(CONFIG_SECURITY_NETWORK) && defined(CONFIG_SECURITY_PATH) 4736 + /** 4737 + * security_unix_find() - Check if a named AF_UNIX socket can connect 4738 + * @path: path of the socket being connected to 4739 + * @other: peer sock 4740 + * @flags: flags associated with the socket 4741 + * 4742 + * This hook is called to check permissions before connecting to a named 4743 + * AF_UNIX socket. The caller does not hold any locks on @other. 4744 + * 4745 + * Return: Returns 0 if permission is granted. 4746 + */ 4747 + int security_unix_find(const struct path *path, struct sock *other, int flags) 4748 + { 4749 + return call_int_hook(unix_find, path, other, flags); 4750 + } 4751 + EXPORT_SYMBOL(security_unix_find); 4752 + 4753 + #endif /* CONFIG_SECURITY_NETWORK && CONFIG_SECURITY_PATH */ 4754 + 4735 4755 #ifdef CONFIG_SECURITY_INFINIBAND 4736 4756 /** 4737 4757 * security_ib_pkey_access() - Check if access to an IB pkey is allowed