cregit-Linux how code gets into the kernel

Release 4.7 ipc/msgutil.c

Directory: ipc
/*
 * linux/ipc/msgutil.c
 * Copyright (C) 1999, 2004 Manfred Spraul
 *
 * This file is released under GNU General Public Licence version 2 or
 * (at your option) any later version.
 *
 * See the file COPYING for more details.
 */

#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 "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		= ATOMIC_INIT(1),
	.user_ns = &init_user_ns,
	.ns.inum = PROC_IPC_INIT_INO,
#ifdef CONFIG_IPC_NS
	.ns.ops = &ipcns_operations,
#endif
};


atomic_t nr_ipc_ns = ATOMIC_INIT(1);


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); if (msg == NULL) return NULL; msg->next = NULL; msg->security = NULL; len -= alen; pseg = &msg->next; while (len > 0) { struct msg_msgseg *seg; alen = min(len, DATALEN_SEG); seg = kmalloc(sizeof(*seg) + alen, GFP_KERNEL); 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; }

Contributors

PersonTokensPropCommitsCommitProp
andrew mortonandrew morton10967.28%125.00%
peter hurleypeter hurley5131.48%250.00%
mathias krausemathias krause21.23%125.00%
Total162100.00%4100.00%


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); }

Contributors

PersonTokensPropCommitsCommitProp
peter hurleypeter hurley10863.53%360.00%
andrew mortonandrew morton6035.29%120.00%
mathias krausemathias krause21.18%120.00%
Total170100.00%5100.00%

#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; }

Contributors

PersonTokensPropCommitsCommitProp
stanislav kinsburskystanislav kinsbursky11777.48%125.00%
peter hurleypeter hurley3221.19%250.00%
mathias krausemathias krause21.32%125.00%
Total151100.00%4100.00%

#else
struct msg_msg *copy_msg(struct msg_msg *src, struct msg_msg *dst) { return ERR_PTR(-ENOSYS); }

Contributors

PersonTokensPropCommitsCommitProp
stanislav kinsburskystanislav kinsbursky24100.00%1100.00%
Total24100.00%1100.00%

#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; }

Contributors

PersonTokensPropCommitsCommitProp
andrew mortonandrew morton8674.14%120.00%
peter hurleypeter hurley2723.28%240.00%
mathias krausemathias krause21.72%120.00%
al viroal viro10.86%120.00%
Total116100.00%5100.00%


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; kfree(seg); seg = tmp; } }

Contributors

PersonTokensPropCommitsCommitProp
andrew mortonandrew morton57100.00%1100.00%
Total57100.00%1100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
andrew mortonandrew morton34943.90%15.26%
peter hurleypeter hurley21827.42%421.05%
stanislav kinsburskystanislav kinsbursky14818.62%210.53%
serge hallynserge hallyn364.53%315.79%
al viroal viro253.14%421.05%
mathias krausemathias krause101.26%15.26%
eric w. biedermaneric w. biederman60.75%15.26%
david howellsdavid howells10.13%15.26%
hosung junghosung jung10.13%15.26%
uwe zeisbergeruwe zeisberger10.13%15.26%
Total795100.00%19100.00%
Directory: ipc
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
{% endraw %}