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