// SPDX-License-Identifier: GPL-2.0-or-later
/*
* linux/ipc/msgutil.c
* Copyright (C) 1999, 2004 Manfred Spraul
*/ #include <linux/spinlock.h>
#include <linux/init.h>
#include <linux/security.h>
#include <linux/slab.h>
#include <linux/ipc.h>
#include <linux/msg.h>
#include <linux/ipc_namespace.h>
#include <linux/utsname.h>
#include <linux/proc_ns.h>
#include <linux/uaccess.h>
#include <linux/sched.h> #include "util.h" DEFINE_SPINLOCK(mq_lock); /*
* The next 2 defines are here bc this is the only file
* compiled when either CONFIG_SYSVIPC and CONFIG_POSIX_MQUEUE
* and not CONFIG_IPC_NS.
*/
struct ipc_namespace init_ipc_ns = {
.count = REFCOUNT_INIT(1),
.user_ns = &init_user_ns,
.ns.inum = PROC_IPC_INIT_INO,
#ifdef CONFIG_IPC_NS
.ns.ops = &ipcns_operations,
#endif
}; struct msg_msgseg {
struct msg_msgseg *next;
/* the next part of the message follows immediately */
}; #define DATALEN_MSG ((size_t)PAGE_SIZE-sizeof(struct msg_msg))
#define DATALEN_SEG ((size_t)PAGE_SIZE-sizeof(struct msg_msgseg)) static struct msg_msg *alloc_msg(size_t len)
{
struct msg_msg *msg;
struct msg_msgseg **pseg;
size_t alen; alen = min(len, DATALEN_MSG);
msg = kmalloc(sizeof(*msg) + alen, GFP_KERNEL_ACCOUNT);
if (msg == NULL)
return NULL; msg->next = NULL;
msg->security = NULL; len -= alen;
pseg = &msg->next;
while (len > 0) {
struct msg_msgseg *seg; cond_resched(); alen = min(len, DATALEN_SEG);
seg = kmalloc(sizeof(*seg) + alen, GFP_KERNEL_ACCOUNT);
if (seg == NULL)
goto out_err;
*pseg = seg;
seg->next = NULL;
pseg = &seg->next;
len -= alen;
} return msg; out_err:
free_msg(msg);
return NULL;
} struct msg_msg *load_msg(const void __user *src, size_t len)
{
struct msg_msg *msg;
struct msg_msgseg *seg;
int err = -EFAULT;
size_t alen; msg = alloc_msg(len);
if (msg == NULL)
return ERR_PTR(-ENOMEM); alen = min(len, DATALEN_MSG);
if (copy_from_user(msg + 1, src, alen))
goto out_err; for (seg = msg->next; seg != NULL; seg = seg->next) {
len -= alen;
src = (char __user *)src + alen;
alen = min(len, DATALEN_SEG);
if (copy_from_user(seg + 1, src, alen))
goto out_err;
} err = security_msg_msg_alloc(msg);
if (err)
goto out_err; return msg; out_err:
free_msg(msg);
return ERR_PTR(err);
}
#ifdef CONFIG_CHECKPOINT_RESTORE
struct msg_msg *copy_msg(struct msg_msg *src, struct msg_msg *dst)
{
struct msg_msgseg *dst_pseg, *src_pseg;
size_t len = src->m_ts;
size_t alen; if (src->m_ts > dst->m_ts)
return ERR_PTR(-EINVAL); alen = min(len, DATALEN_MSG);
memcpy(dst + 1, src + 1, alen); for (dst_pseg = dst->next, src_pseg = src->next;
src_pseg != NULL;
dst_pseg = dst_pseg->next, src_pseg = src_pseg->next) { len -= alen;
alen = min(len, DATALEN_SEG);
memcpy(dst_pseg + 1, src_pseg + 1, alen);
} dst->m_type = src->m_type;
dst->m_ts = src->m_ts; return dst;
}
#else
struct msg_msg *copy_msg(struct msg_msg *src, struct msg_msg *dst)
{
return ERR_PTR(-ENOSYS);
}
#endif
int store_msg(void __user *dest, struct msg_msg *msg, size_t len)
{
size_t alen;
struct msg_msgseg *seg; alen = min(len, DATALEN_MSG);
if (copy_to_user(dest, msg + 1, alen))
return -1; for (seg = msg->next; seg != NULL; seg = seg->next) {
len -= alen;
dest = (char __user *)dest + alen;
alen = min(len, DATALEN_SEG);
if (copy_to_user(dest, seg + 1, alen))
return -1;
}
return 0;
} void free_msg(struct msg_msg *msg)
{
struct msg_msgseg *seg; security_msg_msg_free(msg); seg = msg->next;
kfree(msg);
while (seg != NULL) {
struct msg_msgseg *tmp = seg->next; cond_resched();
kfree(seg);
seg = tmp;
}
}

  

IPC之msgutil.c源码解读的更多相关文章

  1. IPC之mqueue.c源码解读

    队列的意思应该大家都清楚,不过还有有一些细节的地方不知道,下面是一个队列的源码,因该说这是队列的一部分,不是全部.而且是linux中队列,其他各种OS中队列大同小异. /* * POSIX messa ...

  2. IPC之ipc_sysctl.c源码解读

    // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2007 * * Author: Eric Biederman <ebie ...

  3. IPC之util.h源码解读

    /* SPDX-License-Identifier: GPL-2.0 */ /* * linux/ipc/util.h * Copyright (C) 1999 Christoph Rohland ...

  4. IPC之util.c源码解读

    // SPDX-License-Identifier: GPL-2.0 /* * linux/ipc/util.c * Copyright (C) 1992 Krishna Balasubramani ...

  5. IPC之syscall.c源码解读

    // SPDX-License-Identifier: GPL-2.0 /* * sys_ipc() is the old de-multiplexer for the SysV IPC calls. ...

  6. IPC之shm.c源码解读

    // SPDX-License-Identifier: GPL-2.0 /* * linux/ipc/shm.c * Copyright (C) 1992, 1993 Krishna Balasubr ...

  7. IPC之sem.c源码解读

    // SPDX-License-Identifier: GPL-2.0 /* * linux/ipc/sem.c * Copyright (C) 1992 Krishna Balasubramania ...

  8. IPC之namespace.c源码解读

    // SPDX-License-Identifier: GPL-2.0 /* * linux/ipc/namespace.c * Copyright (C) 2006 Pavel Emelyanov ...

  9. IPC之msg.c源码解读

    // SPDX-License-Identifier: GPL-2.0 /* * linux/ipc/msg.c * Copyright (C) 1992 Krishna Balasubramania ...

随机推荐

  1. Cloudera Manager 常见异常

    1. Cloudera Management Service服务全部无法启动 观察到的现象: (1)cm service 组件无法启动,启动时服务请求超时终止:(2)主机信息也无法获取到,一直提示“无 ...

  2. React Native创建项目等待时间长解决

    1. 初始化工程 在终端输入命令 :react-native init AwesomeProject 从命令上看,看起来是初始化一个工程,于是, 1分钟...... 10分钟...... 1小时... ...

  3. 一些常见的MySQL配置

    目录 配置 参考 配置 [mysqld] port = 3306 socket = /mysql/log/mysql_3306.sock # mysql的目录(即mysql的文件所在目录) # bas ...

  4. AspxGridView 弹框选择器 JS

    function Dictionary() { this.data = new Array(); this.put = function (key, value) { this.data[key] = ...

  5. fastadmin model关联模型 关联查询问题

    一对一关联 public function getGoodName(){ return $this->belongsTo('app\api\model\goods\Good','goods_go ...

  6. PYTHON 100days学习笔记008-1:数据结构补充

    目录 Day008_01:数据结构补充 1.列表list 1.1 将列表当作堆栈使用 1.2 将列表当作队列使用 1.3 列表推导式 1.4 嵌套列表解析 1.5 del语句 2.元组和序列 3.集合 ...

  7. 关于mac配置vs code的C++环境问题

    在配置完成后,编译通过了但是在终端输出一直不出现很奇怪,求问大家这是啥问题 以下是我的配置

  8. PAT B1048 数字加密 (20)

    AC代码 #include <cstdio> #include <cstring> #include <algorithm> #include <iostre ...

  9. 【计数】Simple Addition Expression

    [来源] 2008年哈尔滨区域赛 [题目链接]: http://acm.hdu.edu.cn/showproblem.php?pid=2451 [参考博客]: HDU 2451 Simple Addi ...

  10. X86逆向12:内存补丁的制作

    本章我们将学习各种打补丁的方式,补丁在软件的破解过程中非常的重要,比如软件无法脱壳我们就只能通过打补丁的方式来破解程序,补丁原理就是当程序运行起来会被释放到内存并解码,然后补丁就通过地址或特征码定位到 ...