@@ -1660,49 +1660,23 @@ protected ForOpenJ9(Socket socket) {
1660
1660
* @throws IOException If an IO exception occurs during establishing the connection.
1661
1661
*/
1662
1662
public static VirtualMachine attach (String processId ) throws IOException {
1663
- return attach (processId , false );
1664
- }
1665
-
1666
- /**
1667
- * Attaches to the supplied process id using the default JNA implementation.
1668
- *
1669
- * @param processId The process id.
1670
- * @param ignoreUser {@code true} if VM processes that are owned by different users should be considered.
1671
- * @return A suitable virtual machine implementation.
1672
- * @throws IOException If an IO exception occurs during establishing the connection.
1673
- */
1674
- public static VirtualMachine attach (String processId , boolean ignoreUser ) throws IOException {
1675
1663
return attach (processId , 5000 , Platform .isWindows ()
1676
1664
? new Dispatcher .ForJnaWindowsEnvironment ()
1677
1665
: new Dispatcher .ForJnaPosixEnvironment (15 , 100 , TimeUnit .MILLISECONDS ));
1678
1666
}
1679
1667
1680
- /**
1681
- * Attaches to the supplied process id. This method will not consider attaching to VMs owned by
1682
- * different users than the current user.
1683
- *
1684
- * @param processId The process id.
1685
- * @param timeout The timeout for establishing the socket connection.
1686
- * @param dispatcher The connector to use to communicate with the target VM.
1687
- * @return A suitable virtual machine implementation.
1688
- * @throws IOException If an IO exception occurs during establishing the connection.
1689
- */
1690
- public static VirtualMachine attach (String processId , int timeout , Dispatcher dispatcher ) throws IOException {
1691
- return attach (processId , timeout , dispatcher , false );
1692
- }
1693
-
1694
1668
/**
1695
1669
* Attaches to the supplied process id.
1696
1670
*
1697
1671
* @param processId The process id.
1698
1672
* @param timeout The timeout for establishing the socket connection.
1699
1673
* @param dispatcher The connector to use to communicate with the target VM.
1700
- * @param ignoreUser {@code true} if VM processes that are owned by different users should be considered.
1701
1674
* @return A suitable virtual machine implementation.
1702
1675
* @throws IOException If an IO exception occurs during establishing the connection.
1703
1676
*/
1704
- public static VirtualMachine attach (String processId , int timeout , Dispatcher dispatcher , boolean ignoreUser ) throws IOException {
1677
+ public static VirtualMachine attach (String processId , int timeout , Dispatcher dispatcher ) throws IOException {
1705
1678
File directory = new File (System .getProperty (IBM_TEMPORARY_FOLDER , dispatcher .getTemporaryFolder (processId )), ".com_ibm_tools_attach" );
1679
+ long userId = dispatcher .userId ();
1706
1680
RandomAccessFile attachLock = new RandomAccessFile (new File (directory , "_attachlock" ), "rw" );
1707
1681
try {
1708
1682
FileLock attachLockLock = attachLock .getChannel ().lock ();
@@ -1716,10 +1690,9 @@ public static VirtualMachine attach(String processId, int timeout, Dispatcher di
1716
1690
if (vmFolder == null ) {
1717
1691
throw new IllegalStateException ("No descriptor files found in " + directory );
1718
1692
}
1719
- long userId = dispatcher .userId ();
1720
1693
virtualMachines = new ArrayList <Properties >();
1721
1694
for (File aVmFolder : vmFolder ) {
1722
- if (aVmFolder .isDirectory () && ( ignoreUser || dispatcher . getOwnerIdOf ( aVmFolder ) == userId )) {
1695
+ if (aVmFolder .isDirectory () && isFileOwnedByUid ( dispatcher , aVmFolder , userId )) {
1723
1696
File attachInfo = new File (aVmFolder , "attachInfo" );
1724
1697
if (attachInfo .isFile ()) {
1725
1698
Properties virtualMachine = new Properties ();
@@ -1730,12 +1703,7 @@ public static VirtualMachine attach(String processId, int timeout, Dispatcher di
1730
1703
inputStream .close ();
1731
1704
}
1732
1705
int targetProcessId = Integer .parseInt (virtualMachine .getProperty ("processId" ));
1733
- long targetUserId ;
1734
- try {
1735
- targetUserId = Long .parseLong (virtualMachine .getProperty ("userUid" ));
1736
- } catch (NumberFormatException ignored ) {
1737
- targetUserId = 0L ;
1738
- }
1706
+ long targetUserId = getUserId (virtualMachine );
1739
1707
if (userId != 0L && targetUserId == 0L ) {
1740
1708
targetUserId = dispatcher .getOwnerIdOf (attachInfo );
1741
1709
}
@@ -1782,10 +1750,14 @@ public static VirtualMachine attach(String processId, int timeout, Dispatcher di
1782
1750
key = Long .toHexString (SECURE_RANDOM .nextLong ());
1783
1751
}
1784
1752
File reply = new File (receiver , "replyInfo" );
1753
+ long targetUserId = getUserId (target );
1785
1754
try {
1786
1755
if (reply .createNewFile ()) {
1787
1756
dispatcher .setPermissions (reply , 0600 );
1788
1757
}
1758
+ if (0 == userId && 0 != targetUserId ) {
1759
+ dispatcher .chownFileToTargetUid (reply , targetUserId );
1760
+ }
1789
1761
FileOutputStream outputStream = new FileOutputStream (reply );
1790
1762
try {
1791
1763
outputStream .write (key .getBytes ("UTF-8" ));
@@ -1867,6 +1839,31 @@ public static VirtualMachine attach(String processId, int timeout, Dispatcher di
1867
1839
}
1868
1840
}
1869
1841
1842
+ /**
1843
+ * Returns the userUid present in the virtualMachine properties file
1844
+ * @param virtualMachine Properties of the J9 attachInfo file
1845
+ * @return the userUid if it can be parsed, <code>0L</code> otherwise.
1846
+ */
1847
+ private static long getUserId (Properties virtualMachine ) {
1848
+ long targetUserId ;
1849
+ try {
1850
+ targetUserId = Long .parseLong (virtualMachine .getProperty ("userUid" ));
1851
+ } catch (NumberFormatException ignored ) {
1852
+ targetUserId = 0L ;
1853
+ }
1854
+ return targetUserId ;
1855
+ }
1856
+
1857
+ /**
1858
+ * Check if the file is owned by the UID. Note that UID 0 "owns" all files.
1859
+ * @param aVmFolder File or directory
1860
+ * @param userId user UID.
1861
+ * @return true if the uid owns the file or uid == 0.
1862
+ */
1863
+ private static boolean isFileOwnedByUid (Dispatcher dispatcher , File aVmFolder , long userId ) {
1864
+ return 0 == userId || dispatcher .getOwnerIdOf (aVmFolder ) == userId ;
1865
+ }
1866
+
1870
1867
/**
1871
1868
* {@inheritDoc}
1872
1869
*/
@@ -2077,6 +2074,13 @@ public interface Dispatcher {
2077
2074
*/
2078
2075
void decrementSemaphore (File directory , String name , boolean global , int count );
2079
2076
2077
+ /**
2078
+ * change the ownership of a file. Can be called only if this process is owned by root.
2079
+ * @param path path to the file
2080
+ * @param targetUserId effective userid
2081
+ */
2082
+ void chownFileToTargetUid (File path , long targetUserId );
2083
+
2080
2084
/**
2081
2085
* A connector implementation for a POSIX environment using JNA.
2082
2086
*/
@@ -2214,6 +2218,14 @@ public void decrementSemaphore(File directory, String name, boolean global, int
2214
2218
notifySemaphore (directory , name , count , (short ) -1 , (short ) (PosixLibrary .SEM_UNDO | PosixLibrary .IPC_NOWAIT ), true );
2215
2219
}
2216
2220
2221
+ /**
2222
+ * {@inheritDoc}
2223
+ */
2224
+ @ Override
2225
+ public void chownFileToTargetUid (File file , long targetUserId ) {
2226
+ library .chown (file .getAbsolutePath (), targetUserId );
2227
+ }
2228
+
2217
2229
/**
2218
2230
* Notifies a POSIX semaphore.
2219
2231
*
@@ -2319,6 +2331,16 @@ protected interface PosixLibrary extends Library {
2319
2331
*/
2320
2332
int chmod (String path , int mode ) throws LastErrorException ;
2321
2333
2334
+ /**
2335
+ * Runs the {@code chown} command.
2336
+ *
2337
+ * @param path The file path.
2338
+ * @param uid The userid to set.
2339
+ * @return The return code.
2340
+ * @throws LastErrorException If an error occurred.
2341
+ */
2342
+ int chown (String path , long uid ) throws LastErrorException ;
2343
+
2322
2344
/**
2323
2345
* Runs the {@code ftok} command.
2324
2346
*
@@ -2502,6 +2524,14 @@ public void decrementSemaphore(File directory, String name, boolean global, int
2502
2524
}
2503
2525
}
2504
2526
2527
+ /**
2528
+ * {@inheritDoc}
2529
+ */
2530
+ @ Override
2531
+ public void chownFileToTargetUid (File path , long targetUserId ) {
2532
+ /* do nothing */
2533
+ }
2534
+
2505
2535
/**
2506
2536
* Opens a semaphore for signaling another process that an attachment is performed.
2507
2537
*
0 commit comments