@@ -209,26 +209,53 @@ static int socket_accept(int serv_fd)
209
209
return fd ;
210
210
}
211
211
212
- static int socket_receive_result (int serv_fd , char * result , ssize_t result_len )
212
+ static int socket_send_request (int fd , struct su_initiator * from , struct su_request * to )
213
+ {
214
+ size_t len ;
215
+ size_t bin_size , cmd_size ;
216
+
217
+ #define write_token (fd , data ) \
218
+ do { \
219
+ uint32_t __data = htonl(data); \
220
+ size_t __count = sizeof(__data); \
221
+ size_t __len = write((fd), &__data, __count); \
222
+ if (__len != __count) { \
223
+ PLOGE("write(" #data ")"); \
224
+ return -1; \
225
+ } \
226
+ } while (0)
227
+
228
+ write_token (fd , PROTO_VERSION );
229
+ write_token (fd , PATH_MAX );
230
+ write_token (fd , ARG_MAX );
231
+ write_token (fd , from -> uid );
232
+ write_token (fd , to -> uid );
233
+ bin_size = strlen (from -> bin ) + 1 ;
234
+ write_token (fd , bin_size );
235
+ len = write (fd , from -> bin , bin_size );
236
+ if (len != bin_size ) {
237
+ PLOGE ("write(bin)" );
238
+ return -1 ;
239
+ }
240
+ cmd_size = strlen (to -> command ) + 1 ;
241
+ write_token (fd , cmd_size );
242
+ len = write (fd , to -> command , cmd_size );
243
+ if (len != cmd_size ) {
244
+ PLOGE ("write(cmd)" );
245
+ return -1 ;
246
+ }
247
+ return 0 ;
248
+ }
249
+
250
+ static int socket_receive_result (int fd , char * result , ssize_t result_len )
213
251
{
214
252
ssize_t len ;
215
253
216
- for (;;) {
217
- int fd = socket_accept (serv_fd );
218
- if (fd < 0 )
219
- return -1 ;
220
-
221
- len = read (fd , result , result_len - 1 );
222
- if (len < 0 ) {
223
- PLOGE ("read(result)" );
224
- return -1 ;
225
- }
226
-
227
- if (len > 0 ) {
228
- break ;
229
- }
254
+ len = read (fd , result , result_len - 1 );
255
+ if (len < 0 ) {
256
+ PLOGE ("read(result)" );
257
+ return -1 ;
230
258
}
231
-
232
259
result [len ] = '\0' ;
233
260
234
261
return 0 ;
@@ -293,7 +320,7 @@ static void allow(char *shell, mode_t mask)
293
320
int main (int argc , char * argv [])
294
321
{
295
322
struct stat st ;
296
- static int socket_serv_fd = -1 ;
323
+ int socket_serv_fd , fd ;
297
324
char buf [64 ], shell [PATH_MAX ], * result ;
298
325
int i , dballow ;
299
326
mode_t orig_umask ;
@@ -408,15 +435,29 @@ int main(int argc, char *argv[])
408
435
deny ();
409
436
}
410
437
411
- if (socket_receive_result (socket_serv_fd , buf , sizeof (buf )) < 0 ) {
438
+ fd = socket_accept (socket_serv_fd );
439
+ if (fd < 0 ) {
440
+ deny ();
441
+ }
442
+ if (socket_send_request (fd , & su_from , & su_to )) {
443
+ deny ();
444
+ }
445
+ if (socket_receive_result (fd , buf , sizeof (buf ))) {
412
446
deny ();
413
447
}
414
448
449
+ close (fd );
415
450
close (socket_serv_fd );
416
451
socket_cleanup ();
417
452
418
453
result = buf ;
419
454
455
+ #define SOCKET_RESPONSE "socket:"
456
+ if (strncmp (result , SOCKET_RESPONSE , sizeof (SOCKET_RESPONSE ) - 1 ))
457
+ LOGW ("SECURITY RISK: Requestor still receives credentials in intent" );
458
+ else
459
+ result += sizeof (SOCKET_RESPONSE ) - 1 ;
460
+
420
461
if (!strcmp (result , "DENY" )) {
421
462
deny ();
422
463
} else if (!strcmp (result , "ALLOW" )) {
0 commit comments