Commit 8ac6ed5857c8d583e0dc2ab2165966ab143930ad
Committed by
Linus Torvalds
1 parent
852028af86
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
ipc: implement MSG_COPY as a new receive mode
Teach the helper routines about MSG_COPY so that msgtyp is preserved as the message number to copy. The security functions affected by this change were audited and no additional changes are necessary. Signed-off-by: Peter Hurley <peter@hurleysoftware.com> Acked-by: Stanislav Kinsbursky <skinsbursky@parallels.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 1 changed file with 9 additions and 13 deletions Side-by-side Diff
ipc/msg.c
... | ... | @@ -66,6 +66,7 @@ |
66 | 66 | #define SEARCH_EQUAL 2 |
67 | 67 | #define SEARCH_NOTEQUAL 3 |
68 | 68 | #define SEARCH_LESSEQUAL 4 |
69 | +#define SEARCH_NUMBER 5 | |
69 | 70 | |
70 | 71 | #define msg_ids(ns) ((ns)->ids[IPC_MSG_IDS]) |
71 | 72 | |
... | ... | @@ -583,6 +584,7 @@ |
583 | 584 | switch(mode) |
584 | 585 | { |
585 | 586 | case SEARCH_ANY: |
587 | + case SEARCH_NUMBER: | |
586 | 588 | return 1; |
587 | 589 | case SEARCH_LESSEQUAL: |
588 | 590 | if (msg->m_type <=type) |
... | ... | @@ -738,6 +740,8 @@ |
738 | 740 | |
739 | 741 | static inline int convert_mode(long *msgtyp, int msgflg) |
740 | 742 | { |
743 | + if (msgflg & MSG_COPY) | |
744 | + return SEARCH_NUMBER; | |
741 | 745 | /* |
742 | 746 | * find message of correct type. |
743 | 747 | * msgtyp = 0 => get first. |
744 | 748 | |
... | ... | @@ -774,14 +778,10 @@ |
774 | 778 | * This function creates new kernel message structure, large enough to store |
775 | 779 | * bufsz message bytes. |
776 | 780 | */ |
777 | -static inline struct msg_msg *prepare_copy(void __user *buf, size_t bufsz, | |
778 | - int msgflg, long *msgtyp, | |
779 | - unsigned long *copy_number) | |
781 | +static inline struct msg_msg *prepare_copy(void __user *buf, size_t bufsz) | |
780 | 782 | { |
781 | 783 | struct msg_msg *copy; |
782 | 784 | |
783 | - *copy_number = *msgtyp; | |
784 | - *msgtyp = 0; | |
785 | 785 | /* |
786 | 786 | * Create dummy message to copy real message to. |
787 | 787 | */ |
... | ... | @@ -797,9 +797,7 @@ |
797 | 797 | free_msg(copy); |
798 | 798 | } |
799 | 799 | #else |
800 | -static inline struct msg_msg *prepare_copy(void __user *buf, size_t bufsz, | |
801 | - int msgflg, long *msgtyp, | |
802 | - unsigned long *copy_number) | |
800 | +static inline struct msg_msg *prepare_copy(void __user *buf, size_t bufsz) | |
803 | 801 | { |
804 | 802 | return ERR_PTR(-ENOSYS); |
805 | 803 | } |
806 | 804 | |
... | ... | @@ -818,15 +816,13 @@ |
818 | 816 | int mode; |
819 | 817 | struct ipc_namespace *ns; |
820 | 818 | struct msg_msg *copy = NULL; |
821 | - unsigned long copy_number = 0; | |
822 | 819 | |
823 | 820 | ns = current->nsproxy->ipc_ns; |
824 | 821 | |
825 | 822 | if (msqid < 0 || (long) bufsz < 0) |
826 | 823 | return -EINVAL; |
827 | 824 | if (msgflg & MSG_COPY) { |
828 | - copy = prepare_copy(buf, min_t(size_t, bufsz, ns->msg_ctlmax), | |
829 | - msgflg, &msgtyp, ©_number); | |
825 | + copy = prepare_copy(buf, min_t(size_t, bufsz, ns->msg_ctlmax)); | |
830 | 826 | if (IS_ERR(copy)) |
831 | 827 | return PTR_ERR(copy); |
832 | 828 | } |
... | ... | @@ -861,8 +857,8 @@ |
861 | 857 | if (mode == SEARCH_LESSEQUAL && |
862 | 858 | walk_msg->m_type != 1) { |
863 | 859 | msgtyp = walk_msg->m_type - 1; |
864 | - } else if (msgflg & MSG_COPY) { | |
865 | - if (copy_number == msg_counter) | |
860 | + } else if (mode == SEARCH_NUMBER) { | |
861 | + if (msgtyp == msg_counter) | |
866 | 862 | break; |
867 | 863 | msg = ERR_PTR(-EAGAIN); |
868 | 864 | } else |