WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit 9cb52c3

Browse files
committed
Add setuid fork action
1 parent 8f7f82d commit 9cb52c3

File tree

9 files changed

+57
-11
lines changed

9 files changed

+57
-11
lines changed

lib_eio/process.ml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ module Pi = struct
7171
val spawn :
7272
t ->
7373
sw:Switch.t ->
74+
?uid:int ->
7475
?cwd:Fs.dir_ty Path.t ->
7576
?stdin:Flow.source_ty r ->
7677
?stdout:Flow.sink_ty r ->
@@ -121,20 +122,21 @@ let signal (type tag) (t : [> tag ty] r) s =
121122
let module X = (val (Resource.get ops Pi.Process)) in
122123
X.signal v s
123124

124-
let spawn (type tag) ~sw (t : [> tag mgr_ty] r) ?cwd ?stdin ?stdout ?stderr ?env ?executable args : tag ty r =
125+
let spawn (type tag) ~sw (t : [> tag mgr_ty] r) ?uid ?cwd ?stdin ?stdout ?stderr ?env ?executable args : tag ty r =
125126
let (Resource.T (v, ops)) = t in
126127
let module X = (val (Resource.get ops Pi.Mgr)) in
127128
X.spawn v ~sw
129+
?uid
128130
?cwd:(cwd :> Fs.dir_ty Path.t option)
129131
?env
130132
?executable args
131133
?stdin:(stdin :> Flow.source_ty r option)
132134
?stdout:(stdout :> Flow.sink_ty r option)
133135
?stderr:(stderr :> Flow.sink_ty r option)
134136

135-
let run t ?cwd ?stdin ?stdout ?stderr ?(is_success = Int.equal 0) ?env ?executable args =
137+
let run t ?uid ?cwd ?stdin ?stdout ?stderr ?(is_success = Int.equal 0) ?env ?executable args =
136138
Switch.run ~name:"Process.run" @@ fun sw ->
137-
let child = spawn ~sw t ?cwd ?stdin ?stdout ?stderr ?env ?executable args in
139+
let child = spawn ~sw t ?uid ?cwd ?stdin ?stdout ?stderr ?env ?executable args in
138140
match await child with
139141
| `Exited code when is_success code -> ()
140142
| status ->
@@ -145,11 +147,11 @@ let pipe (type tag) ~sw ((Resource.T (v, ops)) : [> tag mgr_ty] r) =
145147
let module X = (val (Resource.get ops Pi.Mgr)) in
146148
X.pipe v ~sw
147149

148-
let parse_out (type tag) (t : [> tag mgr_ty] r) parse ?cwd ?stdin ?stderr ?is_success ?env ?executable args =
150+
let parse_out (type tag) (t : [> tag mgr_ty] r) parse ?uid ?cwd ?stdin ?stderr ?is_success ?env ?executable args =
149151
Switch.run ~name:"Process.parse_out" @@ fun sw ->
150152
let r, w = pipe t ~sw in
151153
try
152-
let child = spawn ~sw t ?cwd ?stdin ~stdout:w ?stderr ?env ?executable args in
154+
let child = spawn ~sw t ?uid ?cwd ?stdin ~stdout:w ?stderr ?env ?executable args in
153155
Flow.close w;
154156
let output = Buf_read.parse_exn parse r ~max_size:max_int in
155157
Flow.close r;

lib_eio/process.mli

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ val signal : _ t -> int -> unit
7575
val spawn :
7676
sw:Switch.t ->
7777
[> 'tag mgr_ty] r ->
78+
?uid:int ->
7879
?cwd:Fs.dir_ty Path.t ->
7980
?stdin:_ Flow.source ->
8081
?stdout:_ Flow.sink ->
@@ -90,6 +91,7 @@ val spawn :
9091
this also creates pipes and spawns fibers to copy the data as necessary.
9192
If you need more control over file descriptors, see {!Eio_unix.Process}.
9293
94+
@param uid The uid for the child process (default: same as parent process).
9395
@param cwd The current working directory of the process (default: same as parent process).
9496
@param stdin The flow to attach to the process's standard input (default: same as parent process).
9597
@param stdout A flow that the process's standard output goes to (default: same as parent process).
@@ -101,6 +103,7 @@ val spawn :
101103

102104
val run :
103105
_ mgr ->
106+
?uid:int ->
104107
?cwd:_ Path.t ->
105108
?stdin:_ Flow.source ->
106109
?stdout:_ Flow.sink ->
@@ -120,6 +123,7 @@ val run :
120123
val parse_out :
121124
_ mgr ->
122125
'a Buf_read.parser ->
126+
?uid:int ->
123127
?cwd:_ Path.t ->
124128
?stdin:_ Flow.source ->
125129
?stderr:_ Flow.sink ->
@@ -176,6 +180,7 @@ module Pi : sig
176180
val spawn :
177181
t ->
178182
sw:Switch.t ->
183+
?uid:int ->
179184
?cwd:Fs.dir_ty Path.t ->
180185
?stdin:Flow.source_ty r ->
181186
?stdout:Flow.sink_ty r ->

lib_eio/unix/fork_action.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,3 +237,21 @@ static void action_dups(int errors, value v_config) {
237237
CAMLprim value eio_unix_fork_dups(value v_unit) {
238238
return Val_fork_fn(action_dups);
239239
}
240+
241+
static void action_setuid(int errors, value v_config) {
242+
#ifdef _WIN32
243+
eio_unix_fork_error(errors, "action_setuid", "Unsupported operation on windows");
244+
#else
245+
value v_uid = Field(v_config, 1);
246+
int r;
247+
r = setuid(Int_val(v_uid));
248+
if (r != 0) {
249+
eio_unix_fork_error(errors, "setuid", strerror(errno));
250+
_exit(1);
251+
}
252+
#endif
253+
}
254+
255+
CAMLprim value eio_unix_fork_setuid(value v_unit) {
256+
return Val_fork_fn(action_setuid);
257+
}

lib_eio/unix/fork_action.ml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,8 @@ let inherit_fds m =
6868
with_fds m @@ fun m ->
6969
let plan : action list = Inherit_fds.plan m in
7070
{ run = fun k -> k (Obj.repr (action_dups, plan, blocking)) }
71+
72+
external action_setuid : unit -> fork_fn = "eio_unix_fork_setuid"
73+
let action_setuid = action_setuid ()
74+
let setuid uid = {
75+
run = fun k -> k (Obj.repr (action_setuid, uid)) }

lib_eio/unix/fork_action.mli

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ val chdir : string -> t
4444
val fchdir : Fd.t -> t
4545
(** [fchdir fd] changes directory to [fd]. *)
4646

47+
val setuid : int -> t
48+
(** [setuid uid] sets the user ID to [uid]. *)
49+
4750
type blocking = [
4851
| `Blocking (** Clear the [O_NONBLOCK] flag in the child process. *)
4952
| `Nonblocking (** Set the [O_NONBLOCK] flag in the child process. *)

lib_eio/unix/process.ml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ module Pi = struct
8282
val spawn_unix :
8383
t ->
8484
sw:Switch.t ->
85+
?uid:int ->
8586
?cwd:Eio.Fs.dir_ty Eio.Path.t ->
8687
env:string array ->
8788
fds:(int * Fd.t * Fork_action.blocking) list ->
@@ -106,6 +107,7 @@ module Make_mgr (X : sig
106107
val spawn_unix :
107108
t ->
108109
sw:Switch.t ->
110+
?uid:int ->
109111
?cwd:Eio.Fs.dir_ty Eio.Path.t ->
110112
env:string array ->
111113
fds:(int * Fd.t * Fork_action.blocking) list ->
@@ -121,7 +123,7 @@ end) = struct
121123
(Private.pipe sw :> ([Eio.Resource.close_ty | Eio.Flow.source_ty] r *
122124
[Eio.Resource.close_ty | Eio.Flow.sink_ty] r))
123125

124-
let spawn v ~sw ?cwd ?stdin ?stdout ?stderr ?env ?executable args =
126+
let spawn v ~sw ?uid ?cwd ?stdin ?stdout ?stderr ?env ?executable args =
125127
let executable = get_executable executable ~args in
126128
let env = get_env env in
127129
with_close_list @@ fun to_close ->
@@ -133,16 +135,16 @@ end) = struct
133135
1, stdout_fd, `Blocking;
134136
2, stderr_fd, `Blocking;
135137
] in
136-
X.spawn_unix v ~sw ?cwd ~env ~fds ~executable args
138+
X.spawn_unix v ~sw ?uid ?cwd ~env ~fds ~executable args
137139

138140
let spawn_unix = X.spawn_unix
139141
end
140142

141-
let spawn_unix ~sw (Eio.Resource.T (v, ops)) ?cwd ~fds ?env ?executable args =
143+
let spawn_unix ~sw (Eio.Resource.T (v, ops)) ?uid ?cwd ~fds ?env ?executable args =
142144
let module X = (val (Eio.Resource.get ops Pi.Mgr_unix)) in
143145
let executable = get_executable executable ~args in
144146
let env = get_env env in
145-
X.spawn_unix v ~sw ?cwd ~fds ~env ~executable args
147+
X.spawn_unix v ~sw ?uid ?cwd ~fds ~env ~executable args
146148

147149
let sigchld = Eio.Condition.create ()
148150

lib_eio/unix/process.mli

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ module Pi : sig
1919
val spawn_unix :
2020
t ->
2121
sw:Switch.t ->
22+
?uid:int ->
2223
?cwd:Eio.Fs.dir_ty Eio.Path.t ->
2324
env:string array ->
2425
fds:(int * Fd.t * Fork_action.blocking) list ->
@@ -41,6 +42,7 @@ module Make_mgr (X : sig
4142
val spawn_unix :
4243
t ->
4344
sw:Switch.t ->
45+
?uid:int ->
4446
?cwd:Eio.Fs.dir_ty Eio.Path.t ->
4547
env:string array ->
4648
fds:(int * Fd.t * Fork_action.blocking) list ->
@@ -52,6 +54,7 @@ end) : Pi.MGR with type t = X.t and type tag = [`Generic | `Unix]
5254
val spawn_unix :
5355
sw:Switch.t ->
5456
_ mgr ->
57+
?uid:int ->
5558
?cwd:Eio.Fs.dir_ty Eio.Path.t ->
5659
fds:(int * Fd.t * Fork_action.blocking) list ->
5760
?env:string array ->

lib_eio_linux/eio_linux.ml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,11 +219,15 @@ module Process_mgr = struct
219219
module T = struct
220220
type t = unit
221221

222-
let spawn_unix () ~sw ?cwd ~env ~fds ~executable args =
222+
let spawn_unix () ~sw ?uid ?cwd ~env ~fds ~executable args =
223223
let actions = Low_level.Process.Fork_action.[
224224
Eio_unix.Private.Fork_action.inherit_fds fds;
225225
execve executable ~argv:(Array.of_list args) ~env
226226
] in
227+
let actions = match uid with
228+
| None -> actions
229+
| Some uid -> Eio_unix.Private.Fork_action.setuid uid :: actions
230+
in
227231
let with_actions cwd fn = match cwd with
228232
| None -> fn actions
229233
| Some (fd, s) ->

lib_eio_posix/process.ml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,15 @@ module Impl = struct
2323
module T = struct
2424
type t = unit
2525

26-
let spawn_unix () ~sw ?cwd ~env ~fds ~executable args =
26+
let spawn_unix () ~sw ?uid ?cwd ~env ~fds ~executable args =
2727
let actions = Low_level.Process.Fork_action.[
2828
inherit_fds fds;
2929
execve executable ~argv:(Array.of_list args) ~env
3030
] in
31+
let actions = match uid with
32+
| None -> actions
33+
| Some uid -> Eio_unix.Private.Fork_action.setuid uid :: actions
34+
in
3135
let with_actions cwd fn = match cwd with
3236
| None -> fn actions
3337
| Some ((dir, path) : Eio.Fs.dir_ty Eio.Path.t) ->

0 commit comments

Comments
 (0)