52 // As the socket is a UNIX domain socket it means that only clients on the 53 // local machine can connect. In addition there are two other aspects to 54 // the security: 55 // 1. The well known file that the socket is bound to has permission 400 56 // 2. When a client connect, the SO_PEERCRED socket option is used to 57 // obtain the credentials of client. We check that the effective uid 58 // of the client matches this process. 59 60 // forward reference 61 class LinuxAttachOperation; 62 63 class LinuxAttachListener: AllStatic { 64 private: 65 // the path to which we bind the UNIX domain socket 66 static char _path[UNIX_PATH_MAX]; 67 static bool _has_path; 68 69 // the file descriptor for the listening socket 70 static int _listener; 71 72 static void set_path(char* path) { 73 if (path == NULL) { 74 _has_path = false; 75 } else { 76 strncpy(_path, path, UNIX_PATH_MAX); 77 _path[UNIX_PATH_MAX-1] = '\0'; 78 _has_path = true; 79 } 80 } 81 82 static void set_listener(int s) { _listener = s; } 83 84 // reads a request from the given connected socket 85 static LinuxAttachOperation* read_request(int s); 86 87 public: 88 enum { 89 ATTACH_PROTOCOL_VER = 1 // protocol version 90 }; 91 enum { 92 ATTACH_ERROR_BADVERSION = 101 // error codes 93 }; 94 95 // initialize the listener, returns 0 if okay 96 static int init(); 97 98 static char* path() { return _path; } 99 static bool has_path() { return _has_path; } 100 static int listener() { return _listener; } 101 102 // write the given buffer to a socket 103 static int write_fully(int s, char* buf, int len); 104 105 static LinuxAttachOperation* dequeue(); 106 }; 107 108 class LinuxAttachOperation: public AttachOperation { 109 private: 110 // the connection to the client 111 int _socket; 112 113 public: 114 void complete(jint res, bufferedStream* st); 115 116 void set_socket(int s) { _socket = s; } 117 int socket() const { return _socket; } 118 119 LinuxAttachOperation(char* name) : AttachOperation(name) { 120 set_socket(-1); 121 } 122 }; 123 124 // statics 125 char LinuxAttachListener::_path[UNIX_PATH_MAX]; 126 bool LinuxAttachListener::_has_path; 127 int LinuxAttachListener::_listener = -1; 128 129 // Supporting class to help split a buffer into individual components 130 class ArgumentIterator : public StackObj { 131 private: 132 char* _pos; 133 char* _end; 134 public: 135 ArgumentIterator(char* arg_buffer, size_t arg_size) { 136 _pos = arg_buffer; 137 _end = _pos + arg_size - 1; 138 } 139 char* next() { 140 if (*_pos == '\0') { 141 // advance the iterator if possible (null arguments) 142 if (_pos < _end) { 143 _pos += 1; 144 } 145 return NULL; 146 } 147 char* res = _pos; 148 char* next_pos = strchr(_pos, '\0'); 149 if (next_pos < _end) { 150 next_pos++; 151 } 152 _pos = next_pos; 153 return res; 154 } 155 }; 156 157 158 // atexit hook to stop listener and unlink the file that it is 159 // bound too. 160 extern "C" { 161 static void listener_cleanup() { 162 static int cleanup_done; 163 if (!cleanup_done) { 164 cleanup_done = 1; 165 int s = LinuxAttachListener::listener(); 166 if (s != -1) { 167 ::close(s); 168 } 169 if (LinuxAttachListener::has_path()) { 170 ::unlink(LinuxAttachListener::path()); 171 } 172 } 173 } 174 } 175 176 // Initialization - create a listener socket and bind it to a file 177 178 int LinuxAttachListener::init() { 179 char path[UNIX_PATH_MAX]; // socket file 180 char initial_path[UNIX_PATH_MAX]; // socket file during setup 181 int listener; // listener socket (file descriptor) 182 183 // register function to cleanup 184 ::atexit(listener_cleanup); 185 186 int n = snprintf(path, UNIX_PATH_MAX, "%s/.java_pid%d", 187 os::get_temp_directory(), os::current_process_id()); 188 if (n < (int)UNIX_PATH_MAX) { 189 n = snprintf(initial_path, UNIX_PATH_MAX, "%s.tmp", path); 190 } 191 if (n >= (int)UNIX_PATH_MAX) { 192 return -1; 193 } 194 195 // create the listener socket 196 listener = ::socket(PF_UNIX, SOCK_STREAM, 0); 197 if (listener == -1) { 198 return -1; 199 } 200 201 // bind socket 202 struct sockaddr_un addr; 203 memset((void *)&addr, 0, sizeof(addr)); 204 addr.sun_family = AF_UNIX; 466 if (ret == -1) { 467 log_debug(attach)("Failed to remove stale attach pid file at %s", fn); 468 } 469 } 470 } 471 472 int AttachListener::pd_init() { 473 JavaThread* thread = JavaThread::current(); 474 ThreadBlockInVM tbivm(thread); 475 476 thread->set_suspend_equivalent(); 477 // cleared by handle_special_suspend_equivalent_condition() or 478 // java_suspend_self() via check_and_wait_while_suspended() 479 480 int ret_code = LinuxAttachListener::init(); 481 482 // were we externally suspended while we were waiting? 483 thread->check_and_wait_while_suspended(); 484 485 return ret_code; 486 } 487 488 // Attach Listener is started lazily except in the case when 489 // +ReduseSignalUsage is used 490 bool AttachListener::init_at_startup() { 491 if (ReduceSignalUsage) { 492 return true; 493 } else { 494 return false; 495 } 496 } 497 498 // If the file .attach_pid<pid> exists in the working directory 499 // or /tmp then this is the trigger to start the attach mechanism 500 bool AttachListener::is_init_trigger() { 501 if (init_at_startup() || is_initialized()) { 502 return false; // initialized at startup or already initialized 503 } 504 char fn[PATH_MAX + 1]; 505 int ret; | 52 // As the socket is a UNIX domain socket it means that only clients on the 53 // local machine can connect. In addition there are two other aspects to 54 // the security: 55 // 1. The well known file that the socket is bound to has permission 400 56 // 2. When a client connect, the SO_PEERCRED socket option is used to 57 // obtain the credentials of client. We check that the effective uid 58 // of the client matches this process. 59 60 // forward reference 61 class LinuxAttachOperation; 62 63 class LinuxAttachListener: AllStatic { 64 private: 65 // the path to which we bind the UNIX domain socket 66 static char _path[UNIX_PATH_MAX]; 67 static bool _has_path; 68 69 // the file descriptor for the listening socket 70 static int _listener; 71 72 // reads a request from the given connected socket 73 static LinuxAttachOperation* read_request(int s); 74 75 static bool _atexit_registered; 76 77 public: 78 enum { 79 ATTACH_PROTOCOL_VER = 1 // protocol version 80 }; 81 enum { 82 ATTACH_ERROR_BADVERSION = 101 // error codes 83 }; 84 85 static void set_path(char* path) { 86 if (path == NULL) { 87 _path[0] = '\0'; 88 _has_path = false; 89 } else { 90 strncpy(_path, path, UNIX_PATH_MAX); 91 _path[UNIX_PATH_MAX-1] = '\0'; 92 _has_path = true; 93 } 94 } 95 96 static void set_listener(int s) { _listener = s; } 97 98 // initialize the listener, returns 0 if okay 99 static int init(); 100 101 static char* path() { return _path; } 102 static bool has_path() { return _has_path; } 103 static int listener() { return _listener; } 104 105 // write the given buffer to a socket 106 static int write_fully(int s, char* buf, int len); 107 108 static LinuxAttachOperation* dequeue(); 109 }; 110 111 class LinuxAttachOperation: public AttachOperation { 112 private: 113 // the connection to the client 114 int _socket; 115 116 public: 117 void complete(jint res, bufferedStream* st); 118 119 void set_socket(int s) { _socket = s; } 120 int socket() const { return _socket; } 121 122 LinuxAttachOperation(char* name) : AttachOperation(name) { 123 set_socket(-1); 124 } 125 }; 126 127 // statics 128 char LinuxAttachListener::_path[UNIX_PATH_MAX]; 129 bool LinuxAttachListener::_has_path; 130 int LinuxAttachListener::_listener = -1; 131 bool LinuxAttachListener::_atexit_registered = false; 132 133 // Supporting class to help split a buffer into individual components 134 class ArgumentIterator : public StackObj { 135 private: 136 char* _pos; 137 char* _end; 138 public: 139 ArgumentIterator(char* arg_buffer, size_t arg_size) { 140 _pos = arg_buffer; 141 _end = _pos + arg_size - 1; 142 } 143 char* next() { 144 if (*_pos == '\0') { 145 // advance the iterator if possible (null arguments) 146 if (_pos < _end) { 147 _pos += 1; 148 } 149 return NULL; 150 } 151 char* res = _pos; 152 char* next_pos = strchr(_pos, '\0'); 153 if (next_pos < _end) { 154 next_pos++; 155 } 156 _pos = next_pos; 157 return res; 158 } 159 }; 160 161 162 // atexit hook to stop listener and unlink the file that it is 163 // bound too. 164 extern "C" { 165 static void listener_cleanup() { 166 int s = LinuxAttachListener::listener(); 167 if (s != -1) { 168 LinuxAttachListener::set_listener(-1); 169 ::shutdown(s, SHUT_RDWR); 170 ::close(s); 171 } 172 if (LinuxAttachListener::has_path()) { 173 ::unlink(LinuxAttachListener::path()); 174 LinuxAttachListener::set_path(NULL); 175 } 176 } 177 } 178 179 // Initialization - create a listener socket and bind it to a file 180 181 int LinuxAttachListener::init() { 182 char path[UNIX_PATH_MAX]; // socket file 183 char initial_path[UNIX_PATH_MAX]; // socket file during setup 184 int listener; // listener socket (file descriptor) 185 186 // register function to cleanup 187 if (!_atexit_registered) { 188 _atexit_registered = true; 189 ::atexit(listener_cleanup); 190 } 191 192 int n = snprintf(path, UNIX_PATH_MAX, "%s/.java_pid%d", 193 os::get_temp_directory(), os::current_process_id()); 194 if (n < (int)UNIX_PATH_MAX) { 195 n = snprintf(initial_path, UNIX_PATH_MAX, "%s.tmp", path); 196 } 197 if (n >= (int)UNIX_PATH_MAX) { 198 return -1; 199 } 200 201 // create the listener socket 202 listener = ::socket(PF_UNIX, SOCK_STREAM, 0); 203 if (listener == -1) { 204 return -1; 205 } 206 207 // bind socket 208 struct sockaddr_un addr; 209 memset((void *)&addr, 0, sizeof(addr)); 210 addr.sun_family = AF_UNIX; 472 if (ret == -1) { 473 log_debug(attach)("Failed to remove stale attach pid file at %s", fn); 474 } 475 } 476 } 477 478 int AttachListener::pd_init() { 479 JavaThread* thread = JavaThread::current(); 480 ThreadBlockInVM tbivm(thread); 481 482 thread->set_suspend_equivalent(); 483 // cleared by handle_special_suspend_equivalent_condition() or 484 // java_suspend_self() via check_and_wait_while_suspended() 485 486 int ret_code = LinuxAttachListener::init(); 487 488 // were we externally suspended while we were waiting? 489 thread->check_and_wait_while_suspended(); 490 491 return ret_code; 492 } 493 494 bool AttachListener::check_socket_file() { 495 int ret; 496 struct stat64 st; 497 ret = stat64(LinuxAttachListener::path(), &st); 498 if (ret == -1) { // need to restart attach listener. 499 log_debug(attach)("Socket file %s does not exist - Restart Attach Listener", 500 LinuxAttachListener::path()); 501 502 listener_cleanup(); 503 504 // wait to terminate current attach listener instance... 505 while(AttachListener::transit_state(AL_INITIALIZING, 506 AL_NOT_INITIALIZED) != AL_NOT_INITIALIZED) { 507 sched_yield(); 508 } 509 is_init_trigger(); 510 return true; 511 } 512 return false; 513 } 514 515 // Attach Listener is started lazily except in the case when 516 // +ReduseSignalUsage is used 517 bool AttachListener::init_at_startup() { 518 if (ReduceSignalUsage) { 519 return true; 520 } else { 521 return false; 522 } 523 } 524 525 // If the file .attach_pid<pid> exists in the working directory 526 // or /tmp then this is the trigger to start the attach mechanism 527 bool AttachListener::is_init_trigger() { 528 if (init_at_startup() || is_initialized()) { 529 return false; // initialized at startup or already initialized 530 } 531 char fn[PATH_MAX + 1]; 532 int ret; |