attachListener_linux.cpp revision 1472:c18cbe5936b8
1/*
2 * Copyright (c) 2005, 2008, 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 *
23 */
24
25# include "incls/_precompiled.incl"
26# include "incls/_attachListener_linux.cpp.incl"
27
28#include <unistd.h>
29#include <signal.h>
30#include <sys/types.h>
31#include <sys/socket.h>
32#include <sys/un.h>
33#include <sys/stat.h>
34
35// The attach mechanism on Linux uses a UNIX domain socket. An attach listener
36// thread is created at startup or is created on-demand via a signal from
37// the client tool. The attach listener creates a socket and binds it to a file
38// in the filesystem. The attach listener then acts as a simple (single-
39// threaded) server - tt waits for a client to connect, reads the request,
40// executes it, and returns the response to the client via the socket
41// connection.
42//
43// As the socket is a UNIX domain socket it means that only clients on the
44// local machine can connect. In addition there are two other aspects to
45// the security:
46// 1. The well known file that the socket is bound to has permission 400
47// 2. When a client connect, the SO_PEERCRED socket option is used to
48//    obtain the credentials of client. We check that the effective uid
49//    of the client matches this process.
50
51// forward reference
52class LinuxAttachOperation;
53
54class LinuxAttachListener: AllStatic {
55 private:
56  // the path to which we bind the UNIX domain socket
57  static char _path[PATH_MAX+1];
58  static bool _has_path;
59
60  // the file descriptor for the listening socket
61  static int _listener;
62
63  static void set_path(char* path) {
64    if (path == NULL) {
65      _has_path = false;
66    } else {
67      strncpy(_path, path, PATH_MAX);
68      _path[PATH_MAX] = '\0';
69      _has_path = true;
70    }
71  }
72
73  static void set_listener(int s)               { _listener = s; }
74
75  // reads a request from the given connected socket
76  static LinuxAttachOperation* read_request(int s);
77
78 public:
79  enum {
80    ATTACH_PROTOCOL_VER = 1                     // protocol version
81  };
82  enum {
83    ATTACH_ERROR_BADVERSION     = 101           // error codes
84  };
85
86  // initialize the listener, returns 0 if okay
87  static int init();
88
89  static char* path()                   { return _path; }
90  static bool has_path()                { return _has_path; }
91  static int listener()                 { return _listener; }
92
93  // write the given buffer to a socket
94  static int write_fully(int s, char* buf, int len);
95
96  static LinuxAttachOperation* dequeue();
97};
98
99class LinuxAttachOperation: public AttachOperation {
100 private:
101  // the connection to the client
102  int _socket;
103
104 public:
105  void complete(jint res, bufferedStream* st);
106
107  void set_socket(int s)                                { _socket = s; }
108  int socket() const                                    { return _socket; }
109
110  LinuxAttachOperation(char* name) : AttachOperation(name) {
111    set_socket(-1);
112  }
113};
114
115// statics
116char LinuxAttachListener::_path[PATH_MAX+1];
117bool LinuxAttachListener::_has_path;
118int LinuxAttachListener::_listener = -1;
119
120// Supporting class to help split a buffer into individual components
121class ArgumentIterator : public StackObj {
122 private:
123  char* _pos;
124  char* _end;
125 public:
126  ArgumentIterator(char* arg_buffer, size_t arg_size) {
127    _pos = arg_buffer;
128    _end = _pos + arg_size - 1;
129  }
130  char* next() {
131    if (*_pos == '\0') {
132      return NULL;
133    }
134    char* res = _pos;
135    char* next_pos = strchr(_pos, '\0');
136    if (next_pos < _end)  {
137      next_pos++;
138    }
139    _pos = next_pos;
140    return res;
141  }
142};
143
144
145// atexit hook to stop listener and unlink the file that it is
146// bound too.
147extern "C" {
148  static void listener_cleanup() {
149    static int cleanup_done;
150    if (!cleanup_done) {
151      cleanup_done = 1;
152      int s = LinuxAttachListener::listener();
153      if (s != -1) {
154        ::close(s);
155      }
156      if (LinuxAttachListener::has_path()) {
157        ::unlink(LinuxAttachListener::path());
158      }
159    }
160  }
161}
162
163// Initialization - create a listener socket and bind it to a file
164
165int LinuxAttachListener::init() {
166  char path[PATH_MAX+1];        // socket file
167  int listener;                 // listener socket (file descriptor)
168
169  // register function to cleanup
170  ::atexit(listener_cleanup);
171
172  // create the listener socket
173  listener = ::socket(PF_UNIX, SOCK_STREAM, 0);
174  if (listener == -1) {
175    return -1;
176  }
177
178  int res = -1;
179  struct sockaddr_un addr;
180  addr.sun_family = AF_UNIX;
181
182  // FIXME: Prior to b39 the tool-side API expected to find the well
183  // known file in the working directory. To allow this libjvm.so work with
184  // a pre-b39 SDK we create it in the working directory if
185  // +StartAttachListener is used is used. All unit tests for this feature
186  // currently used this flag. Once b39 SDK has been promoted we can remove
187  // this code.
188  if (StartAttachListener) {
189    sprintf(path, ".java_pid%d", os::current_process_id());
190    strcpy(addr.sun_path, path);
191    ::unlink(path);
192    res = ::bind(listener, (struct sockaddr*)&addr, sizeof(addr));
193  }
194  if (res == -1) {
195    snprintf(path, PATH_MAX+1, "%s/.java_pid%d",
196             os::get_temp_directory(), os::current_process_id());
197    strcpy(addr.sun_path, path);
198    ::unlink(path);
199    res = ::bind(listener, (struct sockaddr*)&addr, sizeof(addr));
200  }
201  if (res == -1) {
202    RESTARTABLE(::close(listener), res);
203    return -1;
204  }
205  set_path(path);
206
207  // put in listen mode and set permission
208  if ((::listen(listener, 5) == -1) || (::chmod(path, S_IREAD|S_IWRITE) == -1)) {
209    RESTARTABLE(::close(listener), res);
210    ::unlink(path);
211    set_path(NULL);
212    return -1;
213  }
214  set_listener(listener);
215
216  return 0;
217}
218
219// Given a socket that is connected to a peer we read the request and
220// create an AttachOperation. As the socket is blocking there is potential
221// for a denial-of-service if the peer does not response. However this happens
222// after the peer credentials have been checked and in the worst case it just
223// means that the attach listener thread is blocked.
224//
225LinuxAttachOperation* LinuxAttachListener::read_request(int s) {
226  char ver_str[8];
227  sprintf(ver_str, "%d", ATTACH_PROTOCOL_VER);
228
229  // The request is a sequence of strings so we first figure out the
230  // expected count and the maximum possible length of the request.
231  // The request is:
232  //   <ver>0<cmd>0<arg>0<arg>0<arg>0
233  // where <ver> is the protocol version (1), <cmd> is the command
234  // name ("load", "datadump", ...), and <arg> is an argument
235  int expected_str_count = 2 + AttachOperation::arg_count_max;
236  const int max_len = (sizeof(ver_str) + 1) + (AttachOperation::name_length_max + 1) +
237    AttachOperation::arg_count_max*(AttachOperation::arg_length_max + 1);
238
239  char buf[max_len];
240  int str_count = 0;
241
242  // Read until all (expected) strings have been read, the buffer is
243  // full, or EOF.
244
245  int off = 0;
246  int left = max_len;
247
248  do {
249    int n;
250    RESTARTABLE(read(s, buf+off, left), n);
251    if (n == -1) {
252      return NULL;      // reset by peer or other error
253    }
254    if (n == 0) {
255      break;
256    }
257    for (int i=0; i<n; i++) {
258      if (buf[off+i] == 0) {
259        // EOS found
260        str_count++;
261
262        // The first string is <ver> so check it now to
263        // check for protocol mis-match
264        if (str_count == 1) {
265          if ((strlen(buf) != strlen(ver_str)) ||
266              (atoi(buf) != ATTACH_PROTOCOL_VER)) {
267            char msg[32];
268            sprintf(msg, "%d\n", ATTACH_ERROR_BADVERSION);
269            write_fully(s, msg, strlen(msg));
270            return NULL;
271          }
272        }
273      }
274    }
275    off += n;
276    left -= n;
277  } while (left > 0 && str_count < expected_str_count);
278
279  if (str_count != expected_str_count) {
280    return NULL;        // incomplete request
281  }
282
283  // parse request
284
285  ArgumentIterator args(buf, (max_len)-left);
286
287  // version already checked
288  char* v = args.next();
289
290  char* name = args.next();
291  if (name == NULL || strlen(name) > AttachOperation::name_length_max) {
292    return NULL;
293  }
294
295  LinuxAttachOperation* op = new LinuxAttachOperation(name);
296
297  for (int i=0; i<AttachOperation::arg_count_max; i++) {
298    char* arg = args.next();
299    if (arg == NULL) {
300      op->set_arg(i, NULL);
301    } else {
302      if (strlen(arg) > AttachOperation::arg_length_max) {
303        delete op;
304        return NULL;
305      }
306      op->set_arg(i, arg);
307    }
308  }
309
310  op->set_socket(s);
311  return op;
312}
313
314
315// Dequeue an operation
316//
317// In the Linux implementation there is only a single operation and clients
318// cannot queue commands (except at the socket level).
319//
320LinuxAttachOperation* LinuxAttachListener::dequeue() {
321  for (;;) {
322    int s;
323
324    // wait for client to connect
325    struct sockaddr addr;
326    socklen_t len = sizeof(addr);
327    RESTARTABLE(::accept(listener(), &addr, &len), s);
328    if (s == -1) {
329      return NULL;      // log a warning?
330    }
331
332    // get the credentials of the peer and check the effective uid/guid
333    // - check with jeff on this.
334    struct ucred cred_info;
335    socklen_t optlen = sizeof(cred_info);
336    if (::getsockopt(s, SOL_SOCKET, SO_PEERCRED, (void*)&cred_info, &optlen) == -1) {
337      int res;
338      RESTARTABLE(::close(s), res);
339      continue;
340    }
341    uid_t euid = geteuid();
342    gid_t egid = getegid();
343
344    if (cred_info.uid != euid || cred_info.gid != egid) {
345      int res;
346      RESTARTABLE(::close(s), res);
347      continue;
348    }
349
350    // peer credential look okay so we read the request
351    LinuxAttachOperation* op = read_request(s);
352    if (op == NULL) {
353      int res;
354      RESTARTABLE(::close(s), res);
355      continue;
356    } else {
357      return op;
358    }
359  }
360}
361
362// write the given buffer to the socket
363int LinuxAttachListener::write_fully(int s, char* buf, int len) {
364  do {
365    int n = ::write(s, buf, len);
366    if (n == -1) {
367      if (errno != EINTR) return -1;
368    } else {
369      buf += n;
370      len -= n;
371    }
372  }
373  while (len > 0);
374  return 0;
375}
376
377// Complete an operation by sending the operation result and any result
378// output to the client. At this time the socket is in blocking mode so
379// potentially we can block if there is a lot of data and the client is
380// non-responsive. For most operations this is a non-issue because the
381// default send buffer is sufficient to buffer everything. In the future
382// if there are operations that involves a very big reply then it the
383// socket could be made non-blocking and a timeout could be used.
384
385void LinuxAttachOperation::complete(jint result, bufferedStream* st) {
386  JavaThread* thread = JavaThread::current();
387  ThreadBlockInVM tbivm(thread);
388
389  thread->set_suspend_equivalent();
390  // cleared by handle_special_suspend_equivalent_condition() or
391  // java_suspend_self() via check_and_wait_while_suspended()
392
393  // write operation result
394  char msg[32];
395  sprintf(msg, "%d\n", result);
396  int rc = LinuxAttachListener::write_fully(this->socket(), msg, strlen(msg));
397
398  // write any result data
399  if (rc == 0) {
400    LinuxAttachListener::write_fully(this->socket(), (char*) st->base(), st->size());
401    ::shutdown(this->socket(), 2);
402  }
403
404  // done
405  RESTARTABLE(::close(this->socket()), rc);
406
407  // were we externally suspended while we were waiting?
408  thread->check_and_wait_while_suspended();
409
410  delete this;
411}
412
413
414// AttachListener functions
415
416AttachOperation* AttachListener::dequeue() {
417  JavaThread* thread = JavaThread::current();
418  ThreadBlockInVM tbivm(thread);
419
420  thread->set_suspend_equivalent();
421  // cleared by handle_special_suspend_equivalent_condition() or
422  // java_suspend_self() via check_and_wait_while_suspended()
423
424  AttachOperation* op = LinuxAttachListener::dequeue();
425
426  // were we externally suspended while we were waiting?
427  thread->check_and_wait_while_suspended();
428
429  return op;
430}
431
432int AttachListener::pd_init() {
433  JavaThread* thread = JavaThread::current();
434  ThreadBlockInVM tbivm(thread);
435
436  thread->set_suspend_equivalent();
437  // cleared by handle_special_suspend_equivalent_condition() or
438  // java_suspend_self() via check_and_wait_while_suspended()
439
440  int ret_code = LinuxAttachListener::init();
441
442  // were we externally suspended while we were waiting?
443  thread->check_and_wait_while_suspended();
444
445  return ret_code;
446}
447
448// Attach Listener is started lazily except in the case when
449// +ReduseSignalUsage is used
450bool AttachListener::init_at_startup() {
451  if (ReduceSignalUsage) {
452    return true;
453  } else {
454    return false;
455  }
456}
457
458// If the file .attach_pid<pid> exists in the working directory
459// or /tmp then this is the trigger to start the attach mechanism
460bool AttachListener::is_init_trigger() {
461  if (init_at_startup() || is_initialized()) {
462    return false;               // initialized at startup or already initialized
463  }
464  char fn[PATH_MAX+1];
465  sprintf(fn, ".attach_pid%d", os::current_process_id());
466  int ret;
467  struct stat64 st;
468  RESTARTABLE(::stat64(fn, &st), ret);
469  if (ret == -1) {
470    snprintf(fn, sizeof(fn), "%s/.attach_pid%d",
471             os::get_temp_directory(), os::current_process_id());
472    RESTARTABLE(::stat64(fn, &st), ret);
473  }
474  if (ret == 0) {
475    // simple check to avoid starting the attach mechanism when
476    // a bogus user creates the file
477    if (st.st_uid == geteuid()) {
478      init();
479      return true;
480    }
481  }
482  return false;
483}
484
485// if VM aborts then remove listener
486void AttachListener::abort() {
487  listener_cleanup();
488}
489
490void AttachListener::pd_data_dump() {
491  os::signal_notify(SIGQUIT);
492}
493
494AttachOperationFunctionInfo* AttachListener::pd_find_operation(const char* n) {
495  return NULL;
496}
497
498jint AttachListener::pd_set_flag(AttachOperation* op, outputStream* out) {
499  out->print_cr("flag '%s' cannot be changed", op->arg(0));
500  return JNI_ERR;
501}
502
503void AttachListener::pd_detachall() {
504  // do nothing for now
505}
506