file-exec.lisp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. (in-package :hurd-translator)
  2. (defcfun ("do_exec_exec" %do-exec-exec)
  3. pid-t
  4. (execserver port)
  5. (file port)
  6. (file-type msg-type-name)
  7. (oldtask task)
  8. (flags exec-flags)
  9. (argv :pointer)
  10. (argvlen msg-type-number)
  11. (envp :pointer)
  12. (envplen msg-type-number)
  13. (dtable :pointer)
  14. (dtable-type msg-type-name)
  15. (dtablelen msg-type-number)
  16. (portarray :pointer)
  17. (portarray-type msg-type-name)
  18. (portarraylen msg-type-number)
  19. (intarray :pointer)
  20. (intarraylen msg-type-number)
  21. (deallocnames :pointer)
  22. (deallocnameslen msg-type-number)
  23. (destroynames :pointer)
  24. (destroynameslen msg-type-number))
  25. (defcfun ("exec_finished" %exec-finished)
  26. :boolean
  27. (pid pid-t)
  28. (status :pointer))
  29. (def-fs-interface :file-exec ((file port)
  30. (task task)
  31. (flags exec-flags)
  32. (argv :pointer)
  33. (argvlen :unsigned-int)
  34. (envp :pointer)
  35. (envplen :unsigned-int)
  36. (fds :pointer)
  37. (fdslen :unsigned-int)
  38. (portarray :pointer)
  39. (portarraylen :unsigned-int)
  40. (intarray :pointer)
  41. (intarray-len :unsigned-int)
  42. (deallocnames :pointer)
  43. (deallocnameslen :unsigned-int)
  44. (destroynames :pointer)
  45. (destroynameslen :unsigned-int))
  46. (with-lookup protid file
  47. (block file-exec
  48. (let ((node (get-node protid))
  49. (open (open-node protid))
  50. (user (get-user protid)))
  51. (unless (flag-is-p (flags open) :exec)
  52. (return-from file-exec :bad-fd))
  53. (unless (has-access-p node user :exec)
  54. (return-from file-exec :permission-denied))
  55. (when (is-dir-p (stat node))
  56. (return-from file-exec :permission-denied))
  57. (let ((use-uid-p (is-uid-p (stat node)))
  58. (use-gid-p (is-gid-p (stat node))))
  59. (when (or use-uid-p use-gid-p)
  60. (warn "suid/sgid executables not supported.")))
  61. (let* ((new-user (make-iouser :old user))
  62. (new-open (make-open-node node
  63. '(:read)
  64. :copy open))
  65. (new-protid (new-protid *translator*
  66. new-user
  67. new-open)))
  68. (with-port-deallocate (right (get-send-right new-protid))
  69. (let ((pid
  70. (%do-exec-exec +exec-server+
  71. right
  72. :copy-send
  73. task
  74. (enable-flags flags :newtask)
  75. argv argvlen
  76. envp envplen
  77. fds :copy-send fdslen
  78. portarray :copy-send portarraylen
  79. intarray intarray-len
  80. deallocnames deallocnameslen
  81. destroynames destroynameslen)))
  82. (when (zerop pid)
  83. (return-from file-exec :gratuitous-error))
  84. (with-foreign-pointer (status (foreign-type-size :int))
  85. (loop for ret = (%exec-finished pid status)
  86. when ret
  87. return (mem-ref status 'err)
  88. do (wait :miliseconds 200))))))))))