1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package libcore.io; 18 19 import android.compat.annotation.UnsupportedAppUsage; 20 import android.system.ErrnoException; 21 import android.system.GaiException; 22 import android.system.Int64Ref; 23 import android.system.OsConstants; 24 import android.system.StructAddrinfo; 25 import android.system.StructLinger; 26 import android.system.StructMsghdr; 27 import android.system.StructPollfd; 28 import android.system.StructStat; 29 import android.system.StructStatVfs; 30 31 import java.io.FileDescriptor; 32 import java.io.InterruptedIOException; 33 import java.net.InetAddress; 34 import java.net.InetSocketAddress; 35 import java.net.SocketAddress; 36 import java.net.SocketException; 37 import java.nio.ByteBuffer; 38 39 import dalvik.system.BlockGuard; 40 import dalvik.system.SocketTagger; 41 42 import static android.system.OsConstants.*; 43 44 /** 45 * Informs BlockGuard of any activity it should be aware of. 46 */ 47 public class BlockGuardOs extends ForwardingOs { 48 @UnsupportedAppUsage BlockGuardOs(Os os)49 public BlockGuardOs(Os os) { 50 super(os); 51 } 52 tagSocket(FileDescriptor fd)53 private FileDescriptor tagSocket(FileDescriptor fd) throws ErrnoException { 54 try { 55 SocketTagger.get().tag(fd); 56 return fd; 57 } catch (SocketException e) { 58 throw new ErrnoException("socket", EINVAL, e); 59 } 60 } 61 accept(FileDescriptor fd, SocketAddress peerAddress)62 @Override public FileDescriptor accept(FileDescriptor fd, SocketAddress peerAddress) throws ErrnoException, SocketException { 63 if (!(isUnixSocket(fd) && isNonBlockingFile(fd))) { 64 BlockGuard.getThreadPolicy().onNetwork(); 65 } 66 final FileDescriptor acceptFd = super.accept(fd, peerAddress); 67 if (acceptFd != null && isInetSocket(acceptFd)) { 68 tagSocket(acceptFd); 69 } 70 return acceptFd; 71 } 72 access(String path, int mode)73 @Override public boolean access(String path, int mode) throws ErrnoException { 74 BlockGuard.getThreadPolicy().onReadFromDisk(); 75 BlockGuard.getVmPolicy().onPathAccess(path); 76 return super.access(path, mode); 77 } 78 79 @UnsupportedAppUsage chmod(String path, int mode)80 @Override public void chmod(String path, int mode) throws ErrnoException { 81 BlockGuard.getThreadPolicy().onWriteToDisk(); 82 BlockGuard.getVmPolicy().onPathAccess(path); 83 super.chmod(path, mode); 84 } 85 86 @UnsupportedAppUsage chown(String path, int uid, int gid)87 @Override public void chown(String path, int uid, int gid) throws ErrnoException { 88 BlockGuard.getThreadPolicy().onWriteToDisk(); 89 BlockGuard.getVmPolicy().onPathAccess(path); 90 super.chown(path, uid, gid); 91 } 92 93 @UnsupportedAppUsage close(FileDescriptor fd)94 @Override public void close(FileDescriptor fd) throws ErrnoException { 95 try { 96 // The usual case is that this _isn't_ a socket, so the getsockopt(2) call in 97 // isLingerSocket will throw, and that's really expensive. Try to avoid asking 98 // if we don't care. 99 if (fd.isSocket$()) { 100 if (isLingerSocket(fd)) { 101 // If the fd is a socket with SO_LINGER set, we might block indefinitely. 102 // We allow non-linger sockets so that apps can close their network 103 // connections in methods like onDestroy which will run on the UI thread. 104 BlockGuard.getThreadPolicy().onNetwork(); 105 } 106 } 107 } catch (ErrnoException ignored) { 108 // We're called via Socket.close (which doesn't ask for us to be called), so we 109 // must not throw here, because Socket.close must not throw if asked to close an 110 // already-closed socket. Also, the passed-in FileDescriptor isn't necessarily 111 // a socket at all. 112 } 113 super.close(fd); 114 } 115 isNonBlockingFile(FileDescriptor fd)116 public static boolean isNonBlockingFile(FileDescriptor fd) throws ErrnoException { 117 int flag = android.system.Os.fcntlInt(fd, F_GETFL, 0); 118 if ((flag & O_NONBLOCK) != 0) { 119 return true; 120 } 121 return false; 122 } 123 isUnixSocket(FileDescriptor fd)124 public static boolean isUnixSocket(FileDescriptor fd) throws ErrnoException { 125 return isUnixDomain(Libcore.os.getsockoptInt(fd, SOL_SOCKET, SO_DOMAIN)); 126 } 127 isUnixDomain(int domain)128 private static boolean isUnixDomain(int domain) { 129 return (domain == AF_UNIX); 130 } 131 isInetSocket(FileDescriptor fd)132 private static boolean isInetSocket(FileDescriptor fd) throws ErrnoException{ 133 return isInetDomain(Libcore.os.getsockoptInt(fd, SOL_SOCKET, SO_DOMAIN)); 134 } 135 isInetDomain(int domain)136 private static boolean isInetDomain(int domain) { 137 return (domain == AF_INET) || (domain == AF_INET6); 138 } 139 isLingerSocket(FileDescriptor fd)140 private static boolean isLingerSocket(FileDescriptor fd) throws ErrnoException { 141 StructLinger linger = Libcore.os.getsockoptLinger(fd, SOL_SOCKET, SO_LINGER); 142 return linger.isOn() && linger.l_linger > 0; 143 } 144 isUdpSocket(FileDescriptor fd)145 private static boolean isUdpSocket(FileDescriptor fd) throws ErrnoException { 146 return Libcore.os.getsockoptInt(fd, SOL_SOCKET, SO_PROTOCOL) == IPPROTO_UDP; 147 } 148 connect(FileDescriptor fd, InetAddress address, int port)149 @Override public void connect(FileDescriptor fd, InetAddress address, int port) 150 throws ErrnoException, SocketException { 151 boolean skipGuard = false; 152 try { 153 skipGuard = isUdpSocket(fd); 154 } catch (ErrnoException ignored) { 155 } 156 if (!skipGuard) BlockGuard.getThreadPolicy().onNetwork(); 157 super.connect(fd, address, port); 158 } 159 connect(FileDescriptor fd, SocketAddress address)160 @Override public void connect(FileDescriptor fd, SocketAddress address) throws ErrnoException, 161 SocketException { 162 boolean skipGuard = false; 163 try { 164 skipGuard = isUdpSocket(fd); 165 } catch (ErrnoException ignored) { 166 } 167 if (!skipGuard) BlockGuard.getThreadPolicy().onNetwork(); 168 super.connect(fd, address); 169 } 170 171 @UnsupportedAppUsage fchmod(FileDescriptor fd, int mode)172 @Override public void fchmod(FileDescriptor fd, int mode) throws ErrnoException { 173 BlockGuard.getThreadPolicy().onWriteToDisk(); 174 super.fchmod(fd, mode); 175 } 176 177 @UnsupportedAppUsage fchown(FileDescriptor fd, int uid, int gid)178 @Override public void fchown(FileDescriptor fd, int uid, int gid) throws ErrnoException { 179 BlockGuard.getThreadPolicy().onWriteToDisk(); 180 super.fchown(fd, uid, gid); 181 } 182 183 // TODO: Untag newFd when needed for dup2(FileDescriptor oldFd, int newFd) 184 185 @UnsupportedAppUsage fdatasync(FileDescriptor fd)186 @Override public void fdatasync(FileDescriptor fd) throws ErrnoException { 187 BlockGuard.getThreadPolicy().onWriteToDisk(); 188 super.fdatasync(fd); 189 } 190 191 @UnsupportedAppUsage fstat(FileDescriptor fd)192 @Override public StructStat fstat(FileDescriptor fd) throws ErrnoException { 193 BlockGuard.getThreadPolicy().onReadFromDisk(); 194 return super.fstat(fd); 195 } 196 197 @UnsupportedAppUsage fstatvfs(FileDescriptor fd)198 @Override public StructStatVfs fstatvfs(FileDescriptor fd) throws ErrnoException { 199 BlockGuard.getThreadPolicy().onReadFromDisk(); 200 return super.fstatvfs(fd); 201 } 202 fsync(FileDescriptor fd)203 @Override public void fsync(FileDescriptor fd) throws ErrnoException { 204 BlockGuard.getThreadPolicy().onWriteToDisk(); 205 super.fsync(fd); 206 } 207 ftruncate(FileDescriptor fd, long length)208 @Override public void ftruncate(FileDescriptor fd, long length) throws ErrnoException { 209 BlockGuard.getThreadPolicy().onWriteToDisk(); 210 super.ftruncate(fd, length); 211 } 212 android_getaddrinfo(String node, StructAddrinfo hints, int netId)213 @Override public InetAddress[] android_getaddrinfo(String node, StructAddrinfo hints, int netId) throws GaiException { 214 // With AI_NUMERICHOST flag set, the node must a numerical network address, therefore no 215 // host address lookups will be performed. In this case, it is fine to perform on main 216 // thread. 217 boolean isNumericHost = (hints.ai_flags & AI_NUMERICHOST) != 0; 218 if (!isNumericHost) { 219 BlockGuard.getThreadPolicy().onNetwork(); 220 } 221 return super.android_getaddrinfo(node, hints, netId); 222 } 223 224 @UnsupportedAppUsage lchown(String path, int uid, int gid)225 @Override public void lchown(String path, int uid, int gid) throws ErrnoException { 226 BlockGuard.getThreadPolicy().onWriteToDisk(); 227 BlockGuard.getVmPolicy().onPathAccess(path); 228 super.lchown(path, uid, gid); 229 } 230 231 @UnsupportedAppUsage link(String oldPath, String newPath)232 @Override public void link(String oldPath, String newPath) throws ErrnoException { 233 BlockGuard.getThreadPolicy().onWriteToDisk(); 234 BlockGuard.getVmPolicy().onPathAccess(oldPath); 235 BlockGuard.getVmPolicy().onPathAccess(newPath); 236 super.link(oldPath, newPath); 237 } 238 239 @UnsupportedAppUsage lseek(FileDescriptor fd, long offset, int whence)240 @Override public long lseek(FileDescriptor fd, long offset, int whence) throws ErrnoException { 241 BlockGuard.getThreadPolicy().onReadFromDisk(); 242 return super.lseek(fd, offset, whence); 243 } 244 245 @UnsupportedAppUsage lstat(String path)246 @Override public StructStat lstat(String path) throws ErrnoException { 247 BlockGuard.getThreadPolicy().onReadFromDisk(); 248 BlockGuard.getVmPolicy().onPathAccess(path); 249 return super.lstat(path); 250 } 251 252 @UnsupportedAppUsage mkdir(String path, int mode)253 @Override public void mkdir(String path, int mode) throws ErrnoException { 254 BlockGuard.getThreadPolicy().onWriteToDisk(); 255 BlockGuard.getVmPolicy().onPathAccess(path); 256 super.mkdir(path, mode); 257 } 258 259 @UnsupportedAppUsage mkfifo(String path, int mode)260 @Override public void mkfifo(String path, int mode) throws ErrnoException { 261 BlockGuard.getThreadPolicy().onWriteToDisk(); 262 BlockGuard.getVmPolicy().onPathAccess(path); 263 super.mkfifo(path, mode); 264 } 265 266 @UnsupportedAppUsage open(String path, int flags, int mode)267 @Override public FileDescriptor open(String path, int flags, int mode) throws ErrnoException { 268 BlockGuard.getThreadPolicy().onReadFromDisk(); 269 BlockGuard.getVmPolicy().onPathAccess(path); 270 if ((flags & O_ACCMODE) != O_RDONLY) { 271 BlockGuard.getThreadPolicy().onWriteToDisk(); 272 } 273 return super.open(path, flags, mode); 274 } 275 poll(StructPollfd[] fds, int timeoutMs)276 @Override public int poll(StructPollfd[] fds, int timeoutMs) throws ErrnoException { 277 // Greater than 0 is a timeout in milliseconds and -1 means "block forever", 278 // but 0 means "poll and return immediately", which shouldn't be subject to BlockGuard. 279 if (timeoutMs != 0) { 280 BlockGuard.getThreadPolicy().onNetwork(); 281 } 282 return super.poll(fds, timeoutMs); 283 } 284 285 @UnsupportedAppUsage posix_fallocate(FileDescriptor fd, long offset, long length)286 @Override public void posix_fallocate(FileDescriptor fd, long offset, long length) throws ErrnoException { 287 BlockGuard.getThreadPolicy().onWriteToDisk(); 288 super.posix_fallocate(fd, offset, length); 289 } 290 291 @UnsupportedAppUsage pread(FileDescriptor fd, ByteBuffer buffer, long offset)292 @Override public int pread(FileDescriptor fd, ByteBuffer buffer, long offset) throws ErrnoException, InterruptedIOException { 293 BlockGuard.getThreadPolicy().onReadFromDisk(); 294 return super.pread(fd, buffer, offset); 295 } 296 297 @UnsupportedAppUsage pread(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, long offset)298 @Override public int pread(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, long offset) throws ErrnoException, InterruptedIOException { 299 BlockGuard.getThreadPolicy().onReadFromDisk(); 300 return super.pread(fd, bytes, byteOffset, byteCount, offset); 301 } 302 303 @UnsupportedAppUsage pwrite(FileDescriptor fd, ByteBuffer buffer, long offset)304 @Override public int pwrite(FileDescriptor fd, ByteBuffer buffer, long offset) throws ErrnoException, InterruptedIOException { 305 BlockGuard.getThreadPolicy().onWriteToDisk(); 306 return super.pwrite(fd, buffer, offset); 307 } 308 309 @UnsupportedAppUsage pwrite(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, long offset)310 @Override public int pwrite(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, long offset) throws ErrnoException, InterruptedIOException { 311 BlockGuard.getThreadPolicy().onWriteToDisk(); 312 return super.pwrite(fd, bytes, byteOffset, byteCount, offset); 313 } 314 315 @UnsupportedAppUsage read(FileDescriptor fd, ByteBuffer buffer)316 @Override public int read(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException, InterruptedIOException { 317 BlockGuard.getThreadPolicy().onReadFromDisk(); 318 return super.read(fd, buffer); 319 } 320 321 @UnsupportedAppUsage read(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount)322 @Override public int read(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) throws ErrnoException, InterruptedIOException { 323 BlockGuard.getThreadPolicy().onReadFromDisk(); 324 return super.read(fd, bytes, byteOffset, byteCount); 325 } 326 327 @UnsupportedAppUsage readlink(String path)328 @Override public String readlink(String path) throws ErrnoException { 329 BlockGuard.getThreadPolicy().onReadFromDisk(); 330 BlockGuard.getVmPolicy().onPathAccess(path); 331 return super.readlink(path); 332 } 333 334 @UnsupportedAppUsage realpath(String path)335 @Override public String realpath(String path) throws ErrnoException { 336 BlockGuard.getThreadPolicy().onReadFromDisk(); 337 BlockGuard.getVmPolicy().onPathAccess(path); 338 return super.realpath(path); 339 } 340 341 @UnsupportedAppUsage readv(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts)342 @Override public int readv(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts) throws ErrnoException, InterruptedIOException { 343 BlockGuard.getThreadPolicy().onReadFromDisk(); 344 return super.readv(fd, buffers, offsets, byteCounts); 345 } 346 recvfrom(FileDescriptor fd, ByteBuffer buffer, int flags, InetSocketAddress srcAddress)347 @Override public int recvfrom(FileDescriptor fd, ByteBuffer buffer, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException { 348 BlockGuard.getThreadPolicy().onNetwork(); 349 return super.recvfrom(fd, buffer, flags, srcAddress); 350 } 351 recvfrom(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetSocketAddress srcAddress)352 @Override public int recvfrom(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException { 353 BlockGuard.getThreadPolicy().onNetwork(); 354 return super.recvfrom(fd, bytes, byteOffset, byteCount, flags, srcAddress); 355 } 356 recvmsg(FileDescriptor fd, StructMsghdr msg, int flags)357 @Override public int recvmsg(FileDescriptor fd, StructMsghdr msg, int flags) throws ErrnoException, SocketException { 358 BlockGuard.getThreadPolicy().onNetwork(); 359 return super.recvmsg(fd, msg, flags); 360 } 361 362 @UnsupportedAppUsage remove(String path)363 @Override public void remove(String path) throws ErrnoException { 364 BlockGuard.getThreadPolicy().onWriteToDisk(); 365 BlockGuard.getVmPolicy().onPathAccess(path); 366 super.remove(path); 367 } 368 369 @UnsupportedAppUsage rename(String oldPath, String newPath)370 @Override public void rename(String oldPath, String newPath) throws ErrnoException { 371 BlockGuard.getThreadPolicy().onWriteToDisk(); 372 BlockGuard.getVmPolicy().onPathAccess(oldPath); 373 BlockGuard.getVmPolicy().onPathAccess(newPath); 374 super.rename(oldPath, newPath); 375 } 376 sendfile(FileDescriptor outFd, FileDescriptor inFd, Int64Ref offset, long byteCount)377 @Override public long sendfile(FileDescriptor outFd, FileDescriptor inFd, Int64Ref offset, long byteCount) throws ErrnoException { 378 BlockGuard.getThreadPolicy().onWriteToDisk(); 379 return super.sendfile(outFd, inFd, offset, byteCount); 380 } 381 sendmsg(FileDescriptor fd, StructMsghdr msg, int flags)382 @Override public int sendmsg(FileDescriptor fd, StructMsghdr msg, int flags) throws ErrnoException, SocketException { 383 BlockGuard.getThreadPolicy().onNetwork(); 384 return super.sendmsg(fd, msg, flags); 385 } 386 sendto(FileDescriptor fd, ByteBuffer buffer, int flags, InetAddress inetAddress, int port)387 @Override public int sendto(FileDescriptor fd, ByteBuffer buffer, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException { 388 BlockGuard.getThreadPolicy().onNetwork(); 389 return super.sendto(fd, buffer, flags, inetAddress, port); 390 } 391 sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetAddress inetAddress, int port)392 @Override public int sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException { 393 // We permit datagrams without hostname lookups. 394 if (inetAddress != null) { 395 BlockGuard.getThreadPolicy().onNetwork(); 396 } 397 return super.sendto(fd, bytes, byteOffset, byteCount, flags, inetAddress, port); 398 } 399 socket(int domain, int type, int protocol)400 @Override public FileDescriptor socket(int domain, int type, int protocol) throws ErrnoException { 401 final FileDescriptor fd = super.socket(domain, type, protocol); 402 if (isInetDomain(domain)) { 403 tagSocket(fd); 404 } 405 return fd; 406 } 407 socketpair(int domain, int type, int protocol, FileDescriptor fd1, FileDescriptor fd2)408 @Override public void socketpair(int domain, int type, int protocol, FileDescriptor fd1, FileDescriptor fd2) throws ErrnoException { 409 super.socketpair(domain, type, protocol, fd1, fd2); 410 if (isInetDomain(domain)) { 411 tagSocket(fd1); 412 tagSocket(fd2); 413 } 414 } 415 416 @UnsupportedAppUsage stat(String path)417 @Override public StructStat stat(String path) throws ErrnoException { 418 BlockGuard.getThreadPolicy().onReadFromDisk(); 419 BlockGuard.getVmPolicy().onPathAccess(path); 420 return super.stat(path); 421 } 422 423 @UnsupportedAppUsage statvfs(String path)424 @Override public StructStatVfs statvfs(String path) throws ErrnoException { 425 BlockGuard.getThreadPolicy().onReadFromDisk(); 426 BlockGuard.getVmPolicy().onPathAccess(path); 427 return super.statvfs(path); 428 } 429 430 @UnsupportedAppUsage symlink(String oldPath, String newPath)431 @Override public void symlink(String oldPath, String newPath) throws ErrnoException { 432 BlockGuard.getThreadPolicy().onWriteToDisk(); 433 BlockGuard.getVmPolicy().onPathAccess(oldPath); 434 BlockGuard.getVmPolicy().onPathAccess(newPath); 435 super.symlink(oldPath, newPath); 436 } 437 438 @UnsupportedAppUsage write(FileDescriptor fd, ByteBuffer buffer)439 @Override public int write(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException, InterruptedIOException { 440 BlockGuard.getThreadPolicy().onWriteToDisk(); 441 return super.write(fd, buffer); 442 } 443 444 @UnsupportedAppUsage write(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount)445 @Override public int write(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) throws ErrnoException, InterruptedIOException { 446 BlockGuard.getThreadPolicy().onWriteToDisk(); 447 return super.write(fd, bytes, byteOffset, byteCount); 448 } 449 450 @UnsupportedAppUsage writev(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts)451 @Override public int writev(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts) throws ErrnoException, InterruptedIOException { 452 BlockGuard.getThreadPolicy().onWriteToDisk(); 453 return super.writev(fd, buffers, offsets, byteCounts); 454 } 455 execv(String filename, String[] argv)456 @Override public void execv(String filename, String[] argv) throws ErrnoException { 457 BlockGuard.getThreadPolicy().onReadFromDisk(); 458 BlockGuard.getVmPolicy().onPathAccess(filename); 459 super.execv(filename, argv); 460 } 461 execve(String filename, String[] argv, String[] envp)462 @Override public void execve(String filename, String[] argv, String[] envp) 463 throws ErrnoException { 464 BlockGuard.getThreadPolicy().onReadFromDisk(); 465 BlockGuard.getVmPolicy().onPathAccess(filename); 466 super.execve(filename, argv, envp); 467 } 468 getxattr(String path, String name)469 @Override public byte[] getxattr(String path, String name) throws ErrnoException { 470 BlockGuard.getThreadPolicy().onReadFromDisk(); 471 BlockGuard.getVmPolicy().onPathAccess(path); 472 return super.getxattr(path, name); 473 } 474 msync(long address, long byteCount, int flags)475 @Override public void msync(long address, long byteCount, int flags) throws ErrnoException { 476 if ((flags & OsConstants.MS_SYNC) != 0) { 477 BlockGuard.getThreadPolicy().onWriteToDisk(); 478 } 479 super.msync(address, byteCount, flags); 480 } 481 removexattr(String path, String name)482 @Override public void removexattr(String path, String name) throws ErrnoException { 483 BlockGuard.getThreadPolicy().onWriteToDisk(); 484 BlockGuard.getVmPolicy().onPathAccess(path); 485 super.removexattr(path, name); 486 } 487 setxattr(String path, String name, byte[] value, int flags)488 @Override public void setxattr(String path, String name, byte[] value, int flags) 489 throws ErrnoException { 490 BlockGuard.getThreadPolicy().onWriteToDisk(); 491 BlockGuard.getVmPolicy().onPathAccess(path); 492 super.setxattr(path, name, value, flags); 493 } 494 sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, SocketAddress address)495 @Override public int sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, 496 int flags, SocketAddress address) throws ErrnoException, SocketException { 497 BlockGuard.getThreadPolicy().onNetwork(); 498 return super.sendto(fd, bytes, byteOffset, byteCount, flags, address); 499 } 500 unlink(String pathname)501 @Override public void unlink(String pathname) throws ErrnoException { 502 BlockGuard.getThreadPolicy().onWriteToDisk(); 503 BlockGuard.getVmPolicy().onPathAccess(pathname); 504 super.unlink(pathname); 505 } 506 splice(FileDescriptor fdIn, Int64Ref offIn, FileDescriptor fdOut, Int64Ref offOut, long len, int flags)507 @Override public long splice(FileDescriptor fdIn, Int64Ref offIn, FileDescriptor fdOut, Int64Ref offOut, long len, int flags) throws ErrnoException { 508 // It's infeasible to figure out if splice will result in read or write (would require fstat to figure out which fd is pipe). 509 // So, signal both read and write. 510 BlockGuard.getThreadPolicy().onWriteToDisk(); 511 BlockGuard.getThreadPolicy().onReadFromDisk(); 512 return super.splice(fdIn, offIn, fdOut, offOut, len, flags); 513 } 514 } 515