@@ -996,12 +996,19 @@ SYSCALL_DEFINE1(exit_group, int, error_code)
996
996
return 0 ;
997
997
}
998
998
999
+ struct waitid_info {
1000
+ pid_t pid ;
1001
+ uid_t uid ;
1002
+ int status ;
1003
+ int cause ;
1004
+ };
1005
+
999
1006
struct wait_opts {
1000
1007
enum pid_type wo_type ;
1001
1008
int wo_flags ;
1002
1009
struct pid * wo_pid ;
1003
1010
1004
- struct siginfo __user * wo_info ;
1011
+ struct waitid_info * wo_info ;
1005
1012
int wo_stat ;
1006
1013
struct rusage * wo_rusage ;
1007
1014
@@ -1053,31 +1060,20 @@ eligible_child(struct wait_opts *wo, bool ptrace, struct task_struct *p)
1053
1060
static int wait_noreap_copyout (struct wait_opts * wo , struct task_struct * p ,
1054
1061
pid_t pid , uid_t uid , int why , int status )
1055
1062
{
1056
- struct siginfo __user * infop ;
1057
- int retval = 0 ;
1063
+ struct waitid_info * infop ;
1058
1064
1059
1065
if (wo -> wo_rusage )
1060
1066
getrusage (p , RUSAGE_BOTH , wo -> wo_rusage );
1061
1067
1062
1068
put_task_struct (p );
1063
1069
infop = wo -> wo_info ;
1064
1070
if (infop ) {
1065
- if (!retval )
1066
- retval = put_user (SIGCHLD , & infop -> si_signo );
1067
- if (!retval )
1068
- retval = put_user (0 , & infop -> si_errno );
1069
- if (!retval )
1070
- retval = put_user ((short )why , & infop -> si_code );
1071
- if (!retval )
1072
- retval = put_user (pid , & infop -> si_pid );
1073
- if (!retval )
1074
- retval = put_user (uid , & infop -> si_uid );
1075
- if (!retval )
1076
- retval = put_user (status , & infop -> si_status );
1071
+ infop -> cause = why ;
1072
+ infop -> pid = pid ;
1073
+ infop -> uid = uid ;
1074
+ infop -> status = status ;
1077
1075
}
1078
- if (!retval )
1079
- retval = pid ;
1080
- return retval ;
1076
+ return pid ;
1081
1077
}
1082
1078
1083
1079
/*
@@ -1088,10 +1084,10 @@ static int wait_noreap_copyout(struct wait_opts *wo, struct task_struct *p,
1088
1084
*/
1089
1085
static int wait_task_zombie (struct wait_opts * wo , struct task_struct * p )
1090
1086
{
1091
- int state , retval , status ;
1087
+ int state , status ;
1092
1088
pid_t pid = task_pid_vnr (p );
1093
1089
uid_t uid = from_kuid_munged (current_user_ns (), task_uid (p ));
1094
- struct siginfo __user * infop ;
1090
+ struct waitid_info * infop ;
1095
1091
1096
1092
if (!likely (wo -> wo_flags & WEXITED ))
1097
1093
return 0 ;
@@ -1186,36 +1182,22 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p)
1186
1182
1187
1183
if (wo -> wo_rusage )
1188
1184
getrusage (p , RUSAGE_BOTH , wo -> wo_rusage );
1189
- retval = 0 ;
1190
1185
status = (p -> signal -> flags & SIGNAL_GROUP_EXIT )
1191
1186
? p -> signal -> group_exit_code : p -> exit_code ;
1192
1187
wo -> wo_stat = status ;
1193
1188
1194
1189
infop = wo -> wo_info ;
1195
- if (!retval && infop )
1196
- retval = put_user (SIGCHLD , & infop -> si_signo );
1197
- if (!retval && infop )
1198
- retval = put_user (0 , & infop -> si_errno );
1199
- if (!retval && infop ) {
1200
- int why ;
1201
-
1190
+ if (infop ) {
1202
1191
if ((status & 0x7f ) == 0 ) {
1203
- why = CLD_EXITED ;
1204
- status >>= 8 ;
1192
+ infop -> cause = CLD_EXITED ;
1193
+ infop -> status = status >> 8 ;
1205
1194
} else {
1206
- why = (status & 0x80 ) ? CLD_DUMPED : CLD_KILLED ;
1207
- status &= 0x7f ;
1195
+ infop -> cause = (status & 0x80 ) ? CLD_DUMPED : CLD_KILLED ;
1196
+ infop -> status = status & 0x7f ;
1208
1197
}
1209
- retval = put_user ((short )why , & infop -> si_code );
1210
- if (!retval )
1211
- retval = put_user (status , & infop -> si_status );
1198
+ infop -> pid = pid ;
1199
+ infop -> uid = uid ;
1212
1200
}
1213
- if (!retval && infop )
1214
- retval = put_user (pid , & infop -> si_pid );
1215
- if (!retval && infop )
1216
- retval = put_user (uid , & infop -> si_uid );
1217
- if (!retval )
1218
- retval = pid ;
1219
1201
1220
1202
if (state == EXIT_TRACE ) {
1221
1203
write_lock_irq (& tasklist_lock );
@@ -1232,7 +1214,7 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p)
1232
1214
if (state == EXIT_DEAD )
1233
1215
release_task (p );
1234
1216
1235
- return retval ;
1217
+ return pid ;
1236
1218
}
1237
1219
1238
1220
static int * task_stopped_code (struct task_struct * p , bool ptrace )
@@ -1268,8 +1250,8 @@ static int *task_stopped_code(struct task_struct *p, bool ptrace)
1268
1250
static int wait_task_stopped (struct wait_opts * wo ,
1269
1251
int ptrace , struct task_struct * p )
1270
1252
{
1271
- struct siginfo __user * infop ;
1272
- int retval , exit_code , * p_code , why ;
1253
+ struct waitid_info * infop ;
1254
+ int exit_code , * p_code , why ;
1273
1255
uid_t uid = 0 ; /* unneeded, required by compiler */
1274
1256
pid_t pid ;
1275
1257
@@ -1320,28 +1302,19 @@ static int wait_task_stopped(struct wait_opts *wo,
1320
1302
1321
1303
if (wo -> wo_rusage )
1322
1304
getrusage (p , RUSAGE_BOTH , wo -> wo_rusage );
1323
- retval = 0 ;
1324
1305
wo -> wo_stat = (exit_code << 8 ) | 0x7f ;
1325
1306
1326
1307
infop = wo -> wo_info ;
1327
- if (!retval && infop )
1328
- retval = put_user (SIGCHLD , & infop -> si_signo );
1329
- if (!retval && infop )
1330
- retval = put_user (0 , & infop -> si_errno );
1331
- if (!retval && infop )
1332
- retval = put_user ((short )why , & infop -> si_code );
1333
- if (!retval && infop )
1334
- retval = put_user (exit_code , & infop -> si_status );
1335
- if (!retval && infop )
1336
- retval = put_user (pid , & infop -> si_pid );
1337
- if (!retval && infop )
1338
- retval = put_user (uid , & infop -> si_uid );
1339
- if (!retval )
1340
- retval = pid ;
1308
+ if (infop ) {
1309
+ infop -> cause = why ;
1310
+ infop -> status = exit_code ;
1311
+ infop -> pid = pid ;
1312
+ infop -> uid = uid ;
1313
+ }
1341
1314
put_task_struct (p );
1342
1315
1343
- BUG_ON (!retval );
1344
- return retval ;
1316
+ BUG_ON (!pid );
1317
+ return pid ;
1345
1318
}
1346
1319
1347
1320
/*
@@ -1618,7 +1591,7 @@ static long do_wait(struct wait_opts *wo)
1618
1591
return retval ;
1619
1592
}
1620
1593
1621
- static long kernel_waitid (int which , pid_t upid , struct siginfo __user * infop ,
1594
+ static long kernel_waitid (int which , pid_t upid , struct waitid_info * infop ,
1622
1595
int options , struct rusage * ru )
1623
1596
{
1624
1597
struct wait_opts wo ;
@@ -1660,27 +1633,8 @@ static long kernel_waitid(int which, pid_t upid, struct siginfo __user *infop,
1660
1633
wo .wo_rusage = ru ;
1661
1634
ret = do_wait (& wo );
1662
1635
1663
- if (ret > 0 ) {
1636
+ if (ret > 0 )
1664
1637
ret = 0 ;
1665
- } else if (infop ) {
1666
- /*
1667
- * For a WNOHANG return, clear out all the fields
1668
- * we would set so the user can easily tell the
1669
- * difference.
1670
- */
1671
- if (!ret )
1672
- ret = put_user (0 , & infop -> si_signo );
1673
- if (!ret )
1674
- ret = put_user (0 , & infop -> si_errno );
1675
- if (!ret )
1676
- ret = put_user (0 , & infop -> si_code );
1677
- if (!ret )
1678
- ret = put_user (0 , & infop -> si_pid );
1679
- if (!ret )
1680
- ret = put_user (0 , & infop -> si_uid );
1681
- if (!ret )
1682
- ret = put_user (0 , & infop -> si_status );
1683
- }
1684
1638
1685
1639
put_pid (pid );
1686
1640
return ret ;
@@ -1690,12 +1644,24 @@ SYSCALL_DEFINE5(waitid, int, which, pid_t, upid, struct siginfo __user *,
1690
1644
infop , int , options , struct rusage __user * , ru )
1691
1645
{
1692
1646
struct rusage r ;
1693
- long err = kernel_waitid (which , upid , infop , options , ru ? & r : NULL );
1647
+ struct waitid_info info = {.status = 0 };
1648
+ long err = kernel_waitid (which , upid , & info , options , ru ? & r : NULL );
1694
1649
1695
1650
if (!err ) {
1696
1651
if (ru && copy_to_user (ru , & r , sizeof (struct rusage )))
1697
1652
return - EFAULT ;
1698
1653
}
1654
+ if (!infop )
1655
+ return err ;
1656
+
1657
+ if (put_user (err ? 0 : SIGCHLD , & infop -> si_signo ) ||
1658
+ put_user (0 , & infop -> si_errno ) ||
1659
+ put_user ((short )info .cause , & infop -> si_code ) ||
1660
+ put_user (info .pid , & infop -> si_pid ) ||
1661
+ put_user (info .uid , & infop -> si_uid ) ||
1662
+ put_user (info .status , & infop -> si_status ))
1663
+ err = - EFAULT ;
1664
+
1699
1665
return err ;
1700
1666
}
1701
1667
@@ -1785,33 +1751,27 @@ COMPAT_SYSCALL_DEFINE5(waitid,
1785
1751
struct compat_siginfo __user * , infop , int , options ,
1786
1752
struct compat_rusage __user * , uru )
1787
1753
{
1788
- siginfo_t info ;
1789
1754
struct rusage ru ;
1790
- long ret ;
1791
- mm_segment_t old_fs = get_fs ();
1792
-
1793
- memset (& info , 0 , sizeof (info ));
1755
+ struct waitid_info info = {.status = 0 };
1756
+ long err = kernel_waitid (which , pid , & info , options , uru ? & ru : NULL );
1794
1757
1795
- set_fs (KERNEL_DS );
1796
- ret = kernel_waitid (which , pid , (siginfo_t __user * )& info , options ,
1797
- uru ? & ru : NULL );
1798
- set_fs (old_fs );
1799
-
1800
- if ((ret < 0 ) || (info .si_signo == 0 ))
1801
- return ret ;
1802
-
1803
- if (uru ) {
1804
- /* sys_waitid() overwrites everything in ru */
1758
+ if (!err && uru ) {
1759
+ /* kernel_waitid() overwrites everything in ru */
1805
1760
if (COMPAT_USE_64BIT_TIME )
1806
- ret = copy_to_user (uru , & ru , sizeof (ru ));
1761
+ err = copy_to_user (uru , & ru , sizeof (ru ));
1807
1762
else
1808
- ret = put_compat_rusage (& ru , uru );
1809
- if (ret )
1763
+ err = put_compat_rusage (& ru , uru );
1764
+ if (err )
1810
1765
return - EFAULT ;
1811
1766
}
1812
1767
1813
- BUG_ON (info .si_code & __SI_MASK );
1814
- info .si_code |= __SI_CHLD ;
1815
- return copy_siginfo_to_user32 (infop , & info );
1768
+ if (put_user (err ? 0 : SIGCHLD , & infop -> si_signo ) ||
1769
+ put_user (0 , & infop -> si_errno ) ||
1770
+ put_user ((short )info .cause , & infop -> si_code ) ||
1771
+ put_user (info .pid , & infop -> si_pid ) ||
1772
+ put_user (info .uid , & infop -> si_uid ) ||
1773
+ put_user (info .status , & infop -> si_status ))
1774
+ err = - EFAULT ;
1775
+ return err ;
1816
1776
}
1817
1777
#endif
0 commit comments