struct msg_msg *load_msg(const void __user *src, int len) { struct msg_msg *msg; struct msg_msgseg *seg; int err = -EFAULT; int 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); }
struct msg_msg *sysv_msg_load(int (*load)(void * dst, int len, int offset, void * data), int len, void * data) { struct msg_msg *msg; struct msg_msgseg **pseg; int err; int alen; int offset = 0; alen = len; if (alen > DATALEN_MSG) alen = DATALEN_MSG; msg = kmalloc(sizeof(*msg) + alen, GFP_KERNEL_UBC); if (msg == NULL) return ERR_PTR(-ENOMEM); msg->next = NULL; msg->security = NULL; if (load(msg + 1, alen, offset, data)) { err = -EFAULT; goto out_err; } len -= alen; offset += alen; pseg = &msg->next; while (len > 0) { struct msg_msgseg *seg; alen = len; if (alen > DATALEN_SEG) alen = DATALEN_SEG; seg = kmalloc(sizeof(*seg) + alen, GFP_KERNEL_UBC); if (seg == NULL) { err = -ENOMEM; goto out_err; } *pseg = seg; seg->next = NULL; if (load(seg + 1, alen, offset, data)) { err = -EFAULT; goto out_err; } pseg = &seg->next; len -= alen; offset += alen; } err = security_msg_msg_alloc(msg); if (err) goto out_err; return msg; out_err: free_msg(msg); return ERR_PTR(err); }
struct msg_msg *load_msg(const void __user *src, size_t len) { struct msg_msg *msg; struct msg_msgseg **pseg; int err; size_t alen; alen = len; if (alen > DATALEN_MSG) alen = DATALEN_MSG; msg = kmalloc(sizeof(*msg) + alen, GFP_KERNEL); if (msg == NULL) return ERR_PTR(-ENOMEM); msg->next = NULL; msg->security = NULL; if (copy_from_user(msg + 1, src, alen)) { err = -EFAULT; goto out_err; } len -= alen; src = ((char __user *)src) + alen; pseg = &msg->next; while (len > 0) { struct msg_msgseg *seg; alen = len; if (alen > DATALEN_SEG) alen = DATALEN_SEG; seg = kmalloc(sizeof(*seg) + alen, GFP_KERNEL); if (seg == NULL) { err = -ENOMEM; goto out_err; } *pseg = seg; seg->next = NULL; if (copy_from_user(seg + 1, src, alen)) { err = -EFAULT; goto out_err; } pseg = &seg->next; len -= alen; src = ((char __user *)src) + alen; } err = security_msg_msg_alloc(msg); if (err) goto out_err; return msg; out_err: free_msg(msg); return ERR_PTR(err); }
struct msg_msg *kernel_load_msg(const void __user *src, int len) { struct msg_msg *msg; struct msg_msgseg **pseg; int err; int alen; alen = len; if (alen > DATALEN_MSG) alen = DATALEN_MSG; msg = (struct msg_msg *)kmalloc(sizeof(*msg) + alen, GFP_ATOMIC); if (msg == NULL) return ERR_PTR(-ENOMEM); msg->next = NULL; msg->security = NULL; #if 0 if (copy_from_user(msg + 1, src, alen)) { err = -EFAULT; goto out_err; } #endif memcpy(msg+1,src,alen); len -= alen; //src = ((char __user *)src) + alen; src = ((char*)src) + alen; pseg = &msg->next; while (len > 0) { struct msg_msgseg *seg; alen = len; if (alen > DATALEN_SEG) alen = DATALEN_SEG; seg = (struct msg_msgseg *)kmalloc(sizeof(*seg) + alen, GFP_ATOMIC); if (seg == NULL) { err = -ENOMEM; goto out_err; } *pseg = seg; seg->next = NULL; #if 0 if (copy_from_user(seg + 1, src, alen)) { err = -EFAULT; goto out_err; } #endif memcpy(seg+1,src,alen); pseg = &seg->next; len -= alen; //src = ((char __user *)src) + alen; src = ((char *)src) + alen; } err = security_msg_msg_alloc(msg); if (err) goto out_err; return msg; out_err: free_msg(msg); return ERR_PTR(err); }