Linux Audio

Check our new training course

Loading...
v3.1
  1/*
  2 * linux/ipc/msgutil.c
  3 * Copyright (C) 1999, 2004 Manfred Spraul
  4 *
  5 * This file is released under GNU General Public Licence version 2 or
  6 * (at your option) any later version.
  7 *
  8 * See the file COPYING for more details.
  9 */
 10
 11#include <linux/spinlock.h>
 12#include <linux/init.h>
 13#include <linux/security.h>
 14#include <linux/slab.h>
 15#include <linux/ipc.h>
 16#include <linux/ipc_namespace.h>
 17#include <asm/uaccess.h>
 18
 19#include "util.h"
 20
 21DEFINE_SPINLOCK(mq_lock);
 22
 23/*
 24 * The next 2 defines are here bc this is the only file
 25 * compiled when either CONFIG_SYSVIPC and CONFIG_POSIX_MQUEUE
 26 * and not CONFIG_IPC_NS.
 27 */
 28struct ipc_namespace init_ipc_ns = {
 29	.count		= ATOMIC_INIT(1),
 30#ifdef CONFIG_POSIX_MQUEUE
 31	.mq_queues_max   = DFLT_QUEUESMAX,
 32	.mq_msg_max      = DFLT_MSGMAX,
 33	.mq_msgsize_max  = DFLT_MSGSIZEMAX,
 34#endif
 35	.user_ns = &init_user_ns,
 36};
 37
 38atomic_t nr_ipc_ns = ATOMIC_INIT(1);
 39
 40struct msg_msgseg {
 41	struct msg_msgseg* next;
 42	/* the next part of the message follows immediately */
 43};
 44
 45#define DATALEN_MSG	(PAGE_SIZE-sizeof(struct msg_msg))
 46#define DATALEN_SEG	(PAGE_SIZE-sizeof(struct msg_msgseg))
 47
 48struct msg_msg *load_msg(const void __user *src, int len)
 49{
 50	struct msg_msg *msg;
 51	struct msg_msgseg **pseg;
 52	int err;
 53	int alen;
 54
 55	alen = len;
 56	if (alen > DATALEN_MSG)
 57		alen = DATALEN_MSG;
 58
 59	msg = kmalloc(sizeof(*msg) + alen, GFP_KERNEL);
 60	if (msg == NULL)
 61		return ERR_PTR(-ENOMEM);
 62
 63	msg->next = NULL;
 64	msg->security = NULL;
 65
 66	if (copy_from_user(msg + 1, src, alen)) {
 67		err = -EFAULT;
 68		goto out_err;
 69	}
 70
 71	len -= alen;
 72	src = ((char __user *)src) + alen;
 73	pseg = &msg->next;
 74	while (len > 0) {
 75		struct msg_msgseg *seg;
 76		alen = len;
 77		if (alen > DATALEN_SEG)
 78			alen = DATALEN_SEG;
 79		seg = kmalloc(sizeof(*seg) + alen,
 80						 GFP_KERNEL);
 81		if (seg == NULL) {
 82			err = -ENOMEM;
 83			goto out_err;
 84		}
 85		*pseg = seg;
 86		seg->next = NULL;
 87		if (copy_from_user(seg + 1, src, alen)) {
 88			err = -EFAULT;
 89			goto out_err;
 90		}
 91		pseg = &seg->next;
 92		len -= alen;
 93		src = ((char __user *)src) + alen;
 94	}
 95
 96	err = security_msg_msg_alloc(msg);
 97	if (err)
 98		goto out_err;
 99
100	return msg;
101
102out_err:
103	free_msg(msg);
104	return ERR_PTR(err);
105}
106
107int store_msg(void __user *dest, struct msg_msg *msg, int len)
108{
109	int alen;
110	struct msg_msgseg *seg;
111
112	alen = len;
113	if (alen > DATALEN_MSG)
114		alen = DATALEN_MSG;
115	if (copy_to_user(dest, msg + 1, alen))
116		return -1;
117
118	len -= alen;
119	dest = ((char __user *)dest) + alen;
120	seg = msg->next;
121	while (len > 0) {
122		alen = len;
123		if (alen > DATALEN_SEG)
124			alen = DATALEN_SEG;
125		if (copy_to_user(dest, seg + 1, alen))
126			return -1;
127		len -= alen;
128		dest = ((char __user *)dest) + alen;
129		seg = seg->next;
130	}
131	return 0;
132}
133
134void free_msg(struct msg_msg *msg)
135{
136	struct msg_msgseg *seg;
137
138	security_msg_msg_free(msg);
139
140	seg = msg->next;
141	kfree(msg);
142	while (seg != NULL) {
143		struct msg_msgseg *tmp = seg->next;
144		kfree(seg);
145		seg = tmp;
146	}
147}
v3.1
  1/*
  2 * linux/ipc/msgutil.c
  3 * Copyright (C) 1999, 2004 Manfred Spraul
  4 *
  5 * This file is released under GNU General Public Licence version 2 or
  6 * (at your option) any later version.
  7 *
  8 * See the file COPYING for more details.
  9 */
 10
 11#include <linux/spinlock.h>
 12#include <linux/init.h>
 13#include <linux/security.h>
 14#include <linux/slab.h>
 15#include <linux/ipc.h>
 16#include <linux/ipc_namespace.h>
 17#include <asm/uaccess.h>
 18
 19#include "util.h"
 20
 21DEFINE_SPINLOCK(mq_lock);
 22
 23/*
 24 * The next 2 defines are here bc this is the only file
 25 * compiled when either CONFIG_SYSVIPC and CONFIG_POSIX_MQUEUE
 26 * and not CONFIG_IPC_NS.
 27 */
 28struct ipc_namespace init_ipc_ns = {
 29	.count		= ATOMIC_INIT(1),
 30#ifdef CONFIG_POSIX_MQUEUE
 31	.mq_queues_max   = DFLT_QUEUESMAX,
 32	.mq_msg_max      = DFLT_MSGMAX,
 33	.mq_msgsize_max  = DFLT_MSGSIZEMAX,
 34#endif
 35	.user_ns = &init_user_ns,
 36};
 37
 38atomic_t nr_ipc_ns = ATOMIC_INIT(1);
 39
 40struct msg_msgseg {
 41	struct msg_msgseg* next;
 42	/* the next part of the message follows immediately */
 43};
 44
 45#define DATALEN_MSG	(PAGE_SIZE-sizeof(struct msg_msg))
 46#define DATALEN_SEG	(PAGE_SIZE-sizeof(struct msg_msgseg))
 47
 48struct msg_msg *load_msg(const void __user *src, int len)
 49{
 50	struct msg_msg *msg;
 51	struct msg_msgseg **pseg;
 52	int err;
 53	int alen;
 54
 55	alen = len;
 56	if (alen > DATALEN_MSG)
 57		alen = DATALEN_MSG;
 58
 59	msg = kmalloc(sizeof(*msg) + alen, GFP_KERNEL);
 60	if (msg == NULL)
 61		return ERR_PTR(-ENOMEM);
 62
 63	msg->next = NULL;
 64	msg->security = NULL;
 65
 66	if (copy_from_user(msg + 1, src, alen)) {
 67		err = -EFAULT;
 68		goto out_err;
 69	}
 70
 71	len -= alen;
 72	src = ((char __user *)src) + alen;
 73	pseg = &msg->next;
 74	while (len > 0) {
 75		struct msg_msgseg *seg;
 76		alen = len;
 77		if (alen > DATALEN_SEG)
 78			alen = DATALEN_SEG;
 79		seg = kmalloc(sizeof(*seg) + alen,
 80						 GFP_KERNEL);
 81		if (seg == NULL) {
 82			err = -ENOMEM;
 83			goto out_err;
 84		}
 85		*pseg = seg;
 86		seg->next = NULL;
 87		if (copy_from_user(seg + 1, src, alen)) {
 88			err = -EFAULT;
 89			goto out_err;
 90		}
 91		pseg = &seg->next;
 92		len -= alen;
 93		src = ((char __user *)src) + alen;
 94	}
 95
 96	err = security_msg_msg_alloc(msg);
 97	if (err)
 98		goto out_err;
 99
100	return msg;
101
102out_err:
103	free_msg(msg);
104	return ERR_PTR(err);
105}
106
107int store_msg(void __user *dest, struct msg_msg *msg, int len)
108{
109	int alen;
110	struct msg_msgseg *seg;
111
112	alen = len;
113	if (alen > DATALEN_MSG)
114		alen = DATALEN_MSG;
115	if (copy_to_user(dest, msg + 1, alen))
116		return -1;
117
118	len -= alen;
119	dest = ((char __user *)dest) + alen;
120	seg = msg->next;
121	while (len > 0) {
122		alen = len;
123		if (alen > DATALEN_SEG)
124			alen = DATALEN_SEG;
125		if (copy_to_user(dest, seg + 1, alen))
126			return -1;
127		len -= alen;
128		dest = ((char __user *)dest) + alen;
129		seg = seg->next;
130	}
131	return 0;
132}
133
134void free_msg(struct msg_msg *msg)
135{
136	struct msg_msgseg *seg;
137
138	security_msg_msg_free(msg);
139
140	seg = msg->next;
141	kfree(msg);
142	while (seg != NULL) {
143		struct msg_msgseg *tmp = seg->next;
144		kfree(seg);
145		seg = tmp;
146	}
147}