net/compat.c
Source file repositories/reference/linux-study-clean/net/compat.c
File Facts
- System
- Linux kernel
- Corpus path
net/compat.c- Extension
.c- Size
- 14531 bytes
- Lines
- 519
- Domain
- Networking Core
- Bucket
- Sockets, Protocols, Packet Path, And Network Policy
- Inferred role
- Networking Core: implementation source
- Status
- source implementation candidate
Why This File Exists
Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.
- Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/gfp.hlinux/fs.hlinux/types.hlinux/file.hlinux/icmpv6.hlinux/socket.hlinux/syscalls.hlinux/filter.hlinux/compat.hlinux/security.hlinux/audit.hlinux/export.hnet/scm.hnet/sock.hnet/ip.hnet/ipv6.hlinux/uaccess.hnet/compat.h
Detected Declarations
function Copyrightfunction get_compat_msghdrfunction cmsghdr_from_user_compat_to_kernfunction put_cmsg_compatfunction scm_max_fds_compatfunction scm_detach_fds_compatfunction __compat_sys_sendmsgfunction __compat_sys_sendmmsgfunction __compat_sys_recvmsgfunction __compat_sys_recvfrom
Annotated Snippet
if (!save_addr) {
err = move_addr_to_kernel(compat_ptr(msg->msg_name),
kmsg->msg_namelen,
kmsg->msg_name);
if (err < 0)
return err;
}
} else {
kmsg->msg_name = NULL;
kmsg->msg_namelen = 0;
}
if (msg->msg_iovlen > UIO_MAXIOV)
return -EMSGSIZE;
kmsg->msg_ubuf = NULL;
return 0;
}
int get_compat_msghdr(struct msghdr *kmsg,
struct compat_msghdr __user *umsg,
struct sockaddr __user **save_addr,
struct iovec **iov)
{
struct compat_msghdr msg;
ssize_t err;
if (copy_from_user(&msg, umsg, sizeof(*umsg)))
return -EFAULT;
err = __get_compat_msghdr(kmsg, &msg, save_addr);
if (err)
return err;
err = import_iovec(save_addr ? ITER_DEST : ITER_SOURCE,
compat_ptr(msg.msg_iov), msg.msg_iovlen,
UIO_FASTIOV, iov, &kmsg->msg_iter);
return err < 0 ? err : 0;
}
/* Bleech... */
#define CMSG_COMPAT_ALIGN(len) ALIGN((len), sizeof(s32))
#define CMSG_COMPAT_DATA(cmsg) \
((void __user *)((char __user *)(cmsg) + sizeof(struct compat_cmsghdr)))
#define CMSG_COMPAT_SPACE(len) \
(sizeof(struct compat_cmsghdr) + CMSG_COMPAT_ALIGN(len))
#define CMSG_COMPAT_LEN(len) \
(sizeof(struct compat_cmsghdr) + (len))
#define CMSG_COMPAT_FIRSTHDR(msg) \
(((msg)->msg_controllen) >= sizeof(struct compat_cmsghdr) ? \
(struct compat_cmsghdr __user *)((msg)->msg_control_user) : \
(struct compat_cmsghdr __user *)NULL)
#define CMSG_COMPAT_OK(ucmlen, ucmsg, mhdr) \
((ucmlen) >= sizeof(struct compat_cmsghdr) && \
(ucmlen) <= (unsigned long) \
((mhdr)->msg_controllen - \
((char __user *)(ucmsg) - (char __user *)(mhdr)->msg_control_user)))
static inline struct compat_cmsghdr __user *cmsg_compat_nxthdr(struct msghdr *msg,
struct compat_cmsghdr __user *cmsg, int cmsg_len)
{
char __user *ptr = (char __user *)cmsg + CMSG_COMPAT_ALIGN(cmsg_len);
if ((unsigned long)(ptr + 1 - (char __user *)msg->msg_control_user) >
msg->msg_controllen)
return NULL;
return (struct compat_cmsghdr __user *)ptr;
}
/* There is a lot of hair here because the alignment rules (and
* thus placement) of cmsg headers and length are different for
* 32-bit apps. -DaveM
*/
int cmsghdr_from_user_compat_to_kern(struct msghdr *kmsg, struct sock *sk,
unsigned char *stackbuf, int stackbuf_size)
{
struct compat_cmsghdr __user *ucmsg;
struct cmsghdr *kcmsg, *kcmsg_base;
compat_size_t ucmlen;
__kernel_size_t kcmlen, tmp;
int err = -EFAULT;
BUILD_BUG_ON(sizeof(struct compat_cmsghdr) !=
CMSG_COMPAT_ALIGN(sizeof(struct compat_cmsghdr)));
kcmlen = 0;
kcmsg_base = kcmsg = (struct cmsghdr *)stackbuf;
ucmsg = CMSG_COMPAT_FIRSTHDR(kmsg);
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/gfp.h`, `linux/fs.h`, `linux/types.h`, `linux/file.h`, `linux/icmpv6.h`, `linux/socket.h`, `linux/syscalls.h`.
- Detected declarations: `function Copyright`, `function get_compat_msghdr`, `function cmsghdr_from_user_compat_to_kern`, `function put_cmsg_compat`, `function scm_max_fds_compat`, `function scm_detach_fds_compat`, `function __compat_sys_sendmsg`, `function __compat_sys_sendmmsg`, `function __compat_sys_recvmsg`, `function __compat_sys_recvfrom`.
- Atlas domain: Networking Core / Sockets, Protocols, Packet Path, And Network Policy.
- Implementation status: source implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.