Commit 1c54ff97bbde07f4a05dfae719ff2d1d13911265

Authored by aurel32
1 parent a0a83536

linux-user: fix and cleanup IPCOP_msg* ipc calls handling

Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5483 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 116 additions and 55 deletions
linux-user/syscall.c
@@ -1611,7 +1611,6 @@ static abi_long do_socketcall(int num, abi_ulong vptr) @@ -1611,7 +1611,6 @@ static abi_long do_socketcall(int num, abi_ulong vptr)
1611 } 1611 }
1612 #endif 1612 #endif
1613 1613
1614 -#ifdef TARGET_NR_ipc  
1615 #define N_SHM_REGIONS 32 1614 #define N_SHM_REGIONS 32
1616 1615
1617 static struct shm_region { 1616 static struct shm_region {
@@ -1845,20 +1844,26 @@ static inline abi_long do_semctl(int first, int second, int third, @@ -1845,20 +1844,26 @@ static inline abi_long do_semctl(int first, int second, int third,
1845 1844
1846 struct target_msqid_ds 1845 struct target_msqid_ds
1847 { 1846 {
1848 - struct target_ipc_perm msg_perm;  
1849 - abi_ulong msg_stime;  
1850 - abi_ulong __unused1;  
1851 - abi_ulong msg_rtime;  
1852 - abi_ulong __unused2;  
1853 - abi_ulong msg_ctime;  
1854 - abi_ulong __unused3;  
1855 - abi_ulong __msg_cbytes;  
1856 - abi_ulong msg_qnum;  
1857 - abi_ulong msg_qbytes;  
1858 - abi_ulong msg_lspid;  
1859 - abi_ulong msg_lrpid;  
1860 - abi_ulong __unused4;  
1861 - abi_ulong __unused5; 1847 + struct target_ipc_perm msg_perm;
  1848 + abi_ulong msg_stime;
  1849 +#if TARGET_ABI_BITS == 32
  1850 + abi_ulong __unused1;
  1851 +#endif
  1852 + abi_ulong msg_rtime;
  1853 +#if TARGET_ABI_BITS == 32
  1854 + abi_ulong __unused2;
  1855 +#endif
  1856 + abi_ulong msg_ctime;
  1857 +#if TARGET_ABI_BITS == 32
  1858 + abi_ulong __unused3;
  1859 +#endif
  1860 + abi_ulong __msg_cbytes;
  1861 + abi_ulong msg_qnum;
  1862 + abi_ulong msg_qbytes;
  1863 + abi_ulong msg_lspid;
  1864 + abi_ulong msg_lrpid;
  1865 + abi_ulong __unused4;
  1866 + abi_ulong __unused5;
1862 }; 1867 };
1863 1868
1864 static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md, 1869 static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
@@ -1868,7 +1873,8 @@ static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md, @@ -1868,7 +1873,8 @@ static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
1868 1873
1869 if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1)) 1874 if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
1870 return -TARGET_EFAULT; 1875 return -TARGET_EFAULT;
1871 - target_to_host_ipc_perm(&(host_md->msg_perm),target_addr); 1876 + if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
  1877 + return -TARGET_EFAULT;
1872 host_md->msg_stime = tswapl(target_md->msg_stime); 1878 host_md->msg_stime = tswapl(target_md->msg_stime);
1873 host_md->msg_rtime = tswapl(target_md->msg_rtime); 1879 host_md->msg_rtime = tswapl(target_md->msg_rtime);
1874 host_md->msg_ctime = tswapl(target_md->msg_ctime); 1880 host_md->msg_ctime = tswapl(target_md->msg_ctime);
@@ -1888,7 +1894,8 @@ static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr, @@ -1888,7 +1894,8 @@ static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
1888 1894
1889 if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0)) 1895 if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
1890 return -TARGET_EFAULT; 1896 return -TARGET_EFAULT;
1891 - host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)); 1897 + if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
  1898 + return -TARGET_EFAULT;
1892 target_md->msg_stime = tswapl(host_md->msg_stime); 1899 target_md->msg_stime = tswapl(host_md->msg_stime);
1893 target_md->msg_rtime = tswapl(host_md->msg_rtime); 1900 target_md->msg_rtime = tswapl(host_md->msg_rtime);
1894 target_md->msg_ctime = tswapl(host_md->msg_ctime); 1901 target_md->msg_ctime = tswapl(host_md->msg_ctime);
@@ -1901,26 +1908,69 @@ static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr, @@ -1901,26 +1908,69 @@ static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
1901 return 0; 1908 return 0;
1902 } 1909 }
1903 1910
1904 -static inline abi_long do_msgctl(int first, int second, abi_long ptr) 1911 +struct target_msginfo {
  1912 + int msgpool;
  1913 + int msgmap;
  1914 + int msgmax;
  1915 + int msgmnb;
  1916 + int msgmni;
  1917 + int msgssz;
  1918 + int msgtql;
  1919 + unsigned short int msgseg;
  1920 +};
  1921 +
  1922 +static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
  1923 + struct msginfo *host_msginfo)
  1924 +{
  1925 + struct target_msginfo *target_msginfo;
  1926 + if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
  1927 + return -TARGET_EFAULT;
  1928 + __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
  1929 + __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
  1930 + __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
  1931 + __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
  1932 + __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
  1933 + __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
  1934 + __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
  1935 + __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
  1936 + unlock_user_struct(target_msginfo, target_addr, 1);
  1937 +}
  1938 +
  1939 +static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
1905 { 1940 {
1906 struct msqid_ds dsarg; 1941 struct msqid_ds dsarg;
1907 - int cmd = second&0xff;  
1908 - abi_long ret = 0;  
1909 - switch( cmd ) { 1942 + struct msginfo msginfo;
  1943 + abi_long ret = -TARGET_EINVAL;
  1944 +
  1945 + cmd &= 0xff;
  1946 +
  1947 + switch (cmd) {
1910 case IPC_STAT: 1948 case IPC_STAT:
1911 case IPC_SET: 1949 case IPC_SET:
1912 - target_to_host_msqid_ds(&dsarg,ptr);  
1913 - ret = get_errno(msgctl(first, cmd, &dsarg));  
1914 - host_to_target_msqid_ds(ptr,&dsarg);  
1915 - default:  
1916 - ret = get_errno(msgctl(first, cmd, &dsarg)); 1950 + case MSG_STAT:
  1951 + if (target_to_host_msqid_ds(&dsarg,ptr))
  1952 + return -TARGET_EFAULT;
  1953 + ret = get_errno(msgctl(msgid, cmd, &dsarg));
  1954 + if (host_to_target_msqid_ds(ptr,&dsarg))
  1955 + return -TARGET_EFAULT;
  1956 + break;
  1957 + case IPC_RMID:
  1958 + ret = get_errno(msgctl(msgid, cmd, NULL));
  1959 + break;
  1960 + case IPC_INFO:
  1961 + case MSG_INFO:
  1962 + ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
  1963 + if (host_to_target_msginfo(ptr, &msginfo))
  1964 + return -TARGET_EFAULT;
  1965 + break;
1917 } 1966 }
  1967 +
1918 return ret; 1968 return ret;
1919 } 1969 }
1920 1970
1921 struct target_msgbuf { 1971 struct target_msgbuf {
1922 - abi_ulong mtype;  
1923 - char mtext[1]; 1972 + abi_long mtype;
  1973 + char mtext[1];
1924 }; 1974 };
1925 1975
1926 static inline abi_long do_msgsnd(int msqid, abi_long msgp, 1976 static inline abi_long do_msgsnd(int msqid, abi_long msgp,
@@ -1933,8 +1983,8 @@ static inline abi_long do_msgsnd(int msqid, abi_long msgp, @@ -1933,8 +1983,8 @@ static inline abi_long do_msgsnd(int msqid, abi_long msgp,
1933 if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0)) 1983 if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
1934 return -TARGET_EFAULT; 1984 return -TARGET_EFAULT;
1935 host_mb = malloc(msgsz+sizeof(long)); 1985 host_mb = malloc(msgsz+sizeof(long));
1936 - host_mb->mtype = tswapl(target_mb->mtype);  
1937 - memcpy(host_mb->mtext,target_mb->mtext,msgsz); 1986 + host_mb->mtype = (abi_long) tswapl(target_mb->mtype);
  1987 + memcpy(host_mb->mtext, target_mb->mtext, msgsz);
1938 ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg)); 1988 ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
1939 free(host_mb); 1989 free(host_mb);
1940 unlock_user_struct(target_mb, msgp, 0); 1990 unlock_user_struct(target_mb, msgp, 0);
@@ -1943,7 +1993,7 @@ static inline abi_long do_msgsnd(int msqid, abi_long msgp, @@ -1943,7 +1993,7 @@ static inline abi_long do_msgsnd(int msqid, abi_long msgp,
1943 } 1993 }
1944 1994
1945 static inline abi_long do_msgrcv(int msqid, abi_long msgp, 1995 static inline abi_long do_msgrcv(int msqid, abi_long msgp,
1946 - unsigned int msgsz, int msgtype, 1996 + unsigned int msgsz, abi_long msgtyp,
1947 int msgflg) 1997 int msgflg)
1948 { 1998 {
1949 struct target_msgbuf *target_mb; 1999 struct target_msgbuf *target_mb;
@@ -1953,8 +2003,10 @@ static inline abi_long do_msgrcv(int msqid, abi_long msgp, @@ -1953,8 +2003,10 @@ static inline abi_long do_msgrcv(int msqid, abi_long msgp,
1953 2003
1954 if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0)) 2004 if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
1955 return -TARGET_EFAULT; 2005 return -TARGET_EFAULT;
  2006 +
1956 host_mb = malloc(msgsz+sizeof(long)); 2007 host_mb = malloc(msgsz+sizeof(long));
1957 - ret = get_errno(msgrcv(msqid, host_mb, msgsz, 1, msgflg)); 2008 + ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapl(msgtyp), msgflg));
  2009 +
1958 if (ret > 0) { 2010 if (ret > 0) {
1959 abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong); 2011 abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
1960 target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0); 2012 target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
@@ -1962,9 +2014,10 @@ static inline abi_long do_msgrcv(int msqid, abi_long msgp, @@ -1962,9 +2014,10 @@ static inline abi_long do_msgrcv(int msqid, abi_long msgp,
1962 ret = -TARGET_EFAULT; 2014 ret = -TARGET_EFAULT;
1963 goto end; 2015 goto end;
1964 } 2016 }
1965 - memcpy(target_mb->mtext, host_mb->mtext, ret); 2017 + memcpy(target_mb->mtext, host_mb->mtext, ret);
1966 unlock_user(target_mtext, target_mtext_addr, ret); 2018 unlock_user(target_mtext, target_mtext_addr, ret);
1967 } 2019 }
  2020 +
1968 target_mb->mtype = tswapl(host_mb->mtype); 2021 target_mb->mtype = tswapl(host_mb->mtype);
1969 free(host_mb); 2022 free(host_mb);
1970 2023
@@ -1974,6 +2027,7 @@ end: @@ -1974,6 +2027,7 @@ end:
1974 return ret; 2027 return ret;
1975 } 2028 }
1976 2029
  2030 +#ifdef TARGET_NR_ipc
1977 /* ??? This only works with linear mappings. */ 2031 /* ??? This only works with linear mappings. */
1978 /* do_ipc() must return target values and target errnos. */ 2032 /* do_ipc() must return target values and target errnos. */
1979 static abi_long do_ipc(unsigned int call, int first, 2033 static abi_long do_ipc(unsigned int call, int first,
@@ -2006,34 +2060,41 @@ static abi_long do_ipc(unsigned int call, int first, @@ -2006,34 +2060,41 @@ static abi_long do_ipc(unsigned int call, int first,
2006 ret = -TARGET_ENOSYS; 2060 ret = -TARGET_ENOSYS;
2007 break; 2061 break;
2008 2062
2009 - case IPCOP_msgget:  
2010 - ret = get_errno(msgget(first, second));  
2011 - break; 2063 + case IPCOP_msgget:
  2064 + ret = get_errno(msgget(first, second));
  2065 + break;
2012 2066
2013 - case IPCOP_msgsnd:  
2014 - ret = do_msgsnd(first, ptr, second, third);  
2015 - break; 2067 + case IPCOP_msgsnd:
  2068 + ret = do_msgsnd(first, ptr, second, third);
  2069 + break;
2016 2070
2017 - case IPCOP_msgctl:  
2018 - ret = do_msgctl(first, second, ptr);  
2019 - break; 2071 + case IPCOP_msgctl:
  2072 + ret = do_msgctl(first, second, ptr);
  2073 + break;
2020 2074
2021 - case IPCOP_msgrcv:  
2022 - {  
2023 - /* XXX: this code is not correct */  
2024 - struct ipc_kludge  
2025 - {  
2026 - void *__unbounded msgp;  
2027 - long int msgtyp;  
2028 - }; 2075 + case IPCOP_msgrcv:
  2076 + switch (version) {
  2077 + case 0:
  2078 + {
  2079 + struct target_ipc_kludge {
  2080 + abi_long msgp;
  2081 + abi_long msgtyp;
  2082 + } *tmp;
2029 2083
2030 - struct ipc_kludge *foo = (struct ipc_kludge *)g2h(ptr);  
2031 - struct msgbuf *msgp = (struct msgbuf *) foo->msgp; 2084 + if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
  2085 + ret = -TARGET_EFAULT;
  2086 + break;
  2087 + }
2032 2088
2033 - ret = do_msgrcv(first, (long)msgp, second, 0, third); 2089 + ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
2034 2090
2035 - }  
2036 - break; 2091 + unlock_user_struct(tmp, ptr, 0);
  2092 + break;
  2093 + }
  2094 + default:
  2095 + ret = do_msgrcv(first, ptr, second, fifth, third);
  2096 + }
  2097 + break;
2037 2098
2038 case IPCOP_shmat: 2099 case IPCOP_shmat:
2039 { 2100 {