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