1 /*
2 * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
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;
|
1 /*
2 * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
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 bool _atexit_registered;
73
74 // reads a request from the given connected socket
75 static LinuxAttachOperation* read_request(int s);
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 os::naked_yield();
508 }
509 return is_init_trigger();
510 }
511 return false;
512 }
513
514 // Attach Listener is started lazily except in the case when
515 // +ReduseSignalUsage is used
516 bool AttachListener::init_at_startup() {
517 if (ReduceSignalUsage) {
518 return true;
519 } else {
520 return false;
521 }
522 }
523
524 // If the file .attach_pid<pid> exists in the working directory
525 // or /tmp then this is the trigger to start the attach mechanism
526 bool AttachListener::is_init_trigger() {
527 if (init_at_startup() || is_initialized()) {
528 return false; // initialized at startup or already initialized
529 }
530 char fn[PATH_MAX + 1];
531 int ret;
|