aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2017-06-26 17:02:54 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2017-06-26 17:02:54 -0400
commite5f699d443192001613df21f123c5c3483e55888 (patch)
tree4d4e8211ddf0c82c8bf124343715d1817ac6ebf6
parent8b9e04f282c76786fad1a031b38e279bfababd9c (diff)
ipmi: get rid of field-by-field __get_user()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--drivers/char/ipmi/ipmi_devintf.c87
1 files changed, 37 insertions, 50 deletions
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c
index 7007beba918b..2ffca4232686 100644
--- a/drivers/char/ipmi/ipmi_devintf.c
+++ b/drivers/char/ipmi/ipmi_devintf.c
@@ -704,62 +704,41 @@ struct compat_ipmi_req_settime {
704/* 704/*
705 * Define some helper functions for copying IPMI data 705 * Define some helper functions for copying IPMI data
706 */ 706 */
707static long get_compat_ipmi_msg(struct ipmi_msg *p64, 707static void get_compat_ipmi_msg(struct ipmi_msg *p64,
708 struct compat_ipmi_msg __user *p32) 708 struct compat_ipmi_msg *p32)
709{ 709{
710 compat_uptr_t tmp; 710 p64->netfn = p32->netfn;
711 711 p64->cmd = p32->cmd;
712 if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) || 712 p64->data_len = p32->data_len;
713 __get_user(p64->netfn, &p32->netfn) || 713 p64->data = compat_ptr(p32->data);
714 __get_user(p64->cmd, &p32->cmd) ||
715 __get_user(p64->data_len, &p32->data_len) ||
716 __get_user(tmp, &p32->data))
717 return -EFAULT;
718 p64->data = compat_ptr(tmp);
719 return 0;
720} 714}
721 715
722static long get_compat_ipmi_req(struct ipmi_req *p64, 716static void get_compat_ipmi_req(struct ipmi_req *p64,
723 struct compat_ipmi_req __user *p32) 717 struct compat_ipmi_req *p32)
724{ 718{
725 719 p64->addr = compat_ptr(p32->addr);
726 compat_uptr_t tmp; 720 p64->addr_len = p32->addr_len;
727 721 p64->msgid = p32->msgid;
728 if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) || 722 get_compat_ipmi_msg(&p64->msg, &p32->msg);
729 __get_user(tmp, &p32->addr) ||
730 __get_user(p64->addr_len, &p32->addr_len) ||
731 __get_user(p64->msgid, &p32->msgid) ||
732 get_compat_ipmi_msg(&p64->msg, &p32->msg))
733 return -EFAULT;
734 p64->addr = compat_ptr(tmp);
735 return 0;
736} 723}
737 724
738static long get_compat_ipmi_req_settime(struct ipmi_req_settime *p64, 725static void get_compat_ipmi_req_settime(struct ipmi_req_settime *p64,
739 struct compat_ipmi_req_settime __user *p32) 726 struct compat_ipmi_req_settime *p32)
740{ 727{
741 if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) || 728 get_compat_ipmi_req(&p64->req, &p32->req);
742 get_compat_ipmi_req(&p64->req, &p32->req) || 729 p64->retries = p32->retries;
743 __get_user(p64->retries, &p32->retries) || 730 p64->retry_time_ms = p32->retry_time_ms;
744 __get_user(p64->retry_time_ms, &p32->retry_time_ms))
745 return -EFAULT;
746 return 0;
747} 731}
748 732
749static long get_compat_ipmi_recv(struct ipmi_recv *p64, 733static void get_compat_ipmi_recv(struct ipmi_recv *p64,
750 struct compat_ipmi_recv __user *p32) 734 struct compat_ipmi_recv *p32)
751{ 735{
752 compat_uptr_t tmp; 736 memset(p64, 0, sizeof(struct ipmi_recv));
753 737 p64->recv_type = p32->recv_type;
754 if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) || 738 p64->addr = compat_ptr(p32->addr);
755 __get_user(p64->recv_type, &p32->recv_type) || 739 p64->addr_len = p32->addr_len;
756 __get_user(tmp, &p32->addr) || 740 p64->msgid = p32->msgid;
757 __get_user(p64->addr_len, &p32->addr_len) || 741 get_compat_ipmi_msg(&p64->msg, &p32->msg);
758 __get_user(p64->msgid, &p32->msgid) ||
759 get_compat_ipmi_msg(&p64->msg, &p32->msg))
760 return -EFAULT;
761 p64->addr = compat_ptr(tmp);
762 return 0;
763} 742}
764 743
765static int copyout_recv32(struct ipmi_recv *p64, void __user *to) 744static int copyout_recv32(struct ipmi_recv *p64, void __user *to)
@@ -789,10 +768,13 @@ static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd,
789 case COMPAT_IPMICTL_SEND_COMMAND: 768 case COMPAT_IPMICTL_SEND_COMMAND:
790 { 769 {
791 struct ipmi_req rp; 770 struct ipmi_req rp;
771 struct compat_ipmi_req r32;
792 772
793 if (get_compat_ipmi_req(&rp, compat_ptr(arg))) 773 if (copy_from_user(&r32, compat_ptr(arg), sizeof(r32)))
794 return -EFAULT; 774 return -EFAULT;
795 775
776 get_compat_ipmi_req(&rp, &r32);
777
796 return handle_send_req(priv->user, &rp, 778 return handle_send_req(priv->user, &rp,
797 priv->default_retries, 779 priv->default_retries,
798 priv->default_retry_time_ms); 780 priv->default_retry_time_ms);
@@ -800,10 +782,13 @@ static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd,
800 case COMPAT_IPMICTL_SEND_COMMAND_SETTIME: 782 case COMPAT_IPMICTL_SEND_COMMAND_SETTIME:
801 { 783 {
802 struct ipmi_req_settime sp; 784 struct ipmi_req_settime sp;
785 struct compat_ipmi_req_settime sp32;
803 786
804 if (get_compat_ipmi_req_settime(&sp, compat_ptr(arg))) 787 if (copy_from_user(&sp32, compat_ptr(arg), sizeof(sp32)))
805 return -EFAULT; 788 return -EFAULT;
806 789
790 get_compat_ipmi_req_settime(&sp, &sp32);
791
807 return handle_send_req(priv->user, &sp.req, 792 return handle_send_req(priv->user, &sp.req,
808 sp.retries, sp.retry_time_ms); 793 sp.retries, sp.retry_time_ms);
809 } 794 }
@@ -811,11 +796,13 @@ static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd,
811 case COMPAT_IPMICTL_RECEIVE_MSG_TRUNC: 796 case COMPAT_IPMICTL_RECEIVE_MSG_TRUNC:
812 { 797 {
813 struct ipmi_recv recv64; 798 struct ipmi_recv recv64;
799 struct compat_ipmi_recv recv32;
814 800
815 memset(&recv64, 0, sizeof(recv64)); 801 if (copy_from_user(&recv32, compat_ptr(arg), sizeof(recv32)))
816 if (get_compat_ipmi_recv(&recv64, compat_ptr(arg)))
817 return -EFAULT; 802 return -EFAULT;
818 803
804 get_compat_ipmi_recv(&recv64, &recv32);
805
819 return handle_recv(priv, 806 return handle_recv(priv,
820 cmd == COMPAT_IPMICTL_RECEIVE_MSG_TRUNC, 807 cmd == COMPAT_IPMICTL_RECEIVE_MSG_TRUNC,
821 &recv64, copyout_recv32, compat_ptr(arg)); 808 &recv64, copyout_recv32, compat_ptr(arg));