Print this page
6474 getupeercred causes spurious event port wakeups on FIFOs


1109         tsignal(curthread, SIGPIPE);
1110         return (error);
1111 }
1112 
1113 /*ARGSUSED6*/
1114 static int
1115 fifo_ioctl(vnode_t *vp, int cmd, intptr_t arg, int mode,
1116         cred_t *cr, int *rvalp, caller_context_t *ct)
1117 {
1118         /*
1119          * Just a quick check
1120          * Once we go to streams mode we don't ever revert back
1121          * So we do this quick check so as not to incur the overhead
1122          * associated with acquiring the lock
1123          */
1124         return ((VTOF(vp)->fn_flag & FIFOFAST) ?
1125             fifo_fastioctl(vp, cmd, arg, mode, cr, rvalp) :
1126             fifo_strioctl(vp, cmd, arg, mode, cr, rvalp));
1127 }
1128 















1129 static int
1130 fifo_fastioctl(vnode_t *vp, int cmd, intptr_t arg, int mode,
1131         cred_t *cr, int *rvalp)
1132 {
1133         fifonode_t      *fnp            = VTOF(vp);
1134         fifonode_t      *fn_dest;
1135         int             error           = 0;
1136         fifolock_t      *fn_lock        = fnp->fn_lock;
1137         int             cnt;
1138 
1139         /*
1140          * tty operations not allowed
1141          */
1142         if (((cmd & IOCTYPE) == LDIOC) ||
1143             ((cmd & IOCTYPE) == tIOC) ||
1144             ((cmd & IOCTYPE) == TIOC)) {
1145                 return (EINVAL);
1146         }
1147 
1148         mutex_enter(&fn_lock->flk_lock);


1328                  * (waking readers probably doesn't make sense, but it
1329                  *  doesn't hurt; i.e. we just got rid of all the data
1330                  *  what's to read ?)
1331                  */
1332                 if (fn_dest->fn_flag & (FIFOWANTW | FIFOWANTR)) {
1333                         fn_dest->fn_flag &= ~(FIFOWANTW | FIFOWANTR);
1334                         cv_broadcast(&fn_dest->fn_wait_cv);
1335                 }
1336                 *rvalp = 0;
1337                 break;
1338 
1339         /*
1340          * Since no band data can ever get on a fifo in fast mode
1341          * just return 0.
1342          */
1343         case I_FLUSHBAND:
1344                 error = 0;
1345                 *rvalp = 0;
1346                 break;
1347 




1348         /*
1349          * invalid calls for stream head or fifos
1350          */
1351 
1352         case I_POP:             /* shouldn't happen */
1353         case I_LOOK:
1354         case I_LINK:
1355         case I_PLINK:
1356         case I_UNLINK:
1357         case I_PUNLINK:
1358 
1359         /*
1360          * more invalid tty type of ioctls
1361          */
1362 
1363         case SRIOCSREDIR:
1364         case SRIOCISREDIR:
1365                 error = EINVAL;
1366                 break;
1367 


1375 stream_mode:
1376         /*
1377          * streams mode
1378          */
1379         mutex_exit(&fn_lock->flk_lock);
1380         return (fifo_strioctl(vp, cmd, arg, mode, cr, rvalp));
1381 
1382 }
1383 
1384 /*
1385  * FIFO is in STREAMS mode; STREAMS framework does most of the work.
1386  */
1387 static int
1388 fifo_strioctl(vnode_t *vp, int cmd, intptr_t arg, int mode,
1389         cred_t *cr, int *rvalp)
1390 {
1391         fifonode_t      *fnp = VTOF(vp);
1392         int             error;
1393         fifolock_t      *fn_lock;
1394 
1395         if (cmd == _I_GETPEERCRED) {
1396                 if (mode == FKIOCTL && fnp->fn_pcredp != NULL) {
1397                         k_peercred_t *kp = (k_peercred_t *)arg;
1398                         crhold(fnp->fn_pcredp);
1399                         kp->pc_cr = fnp->fn_pcredp;
1400                         kp->pc_cpid = fnp->fn_cpid;
1401                         return (0);
1402                 } else {
1403                         return (ENOTSUP);
1404                 }
1405         }
1406 
1407         error = strioctl(vp, cmd, arg, mode, U_TO_K, cr, rvalp);
1408 
1409         switch (cmd) {
1410         /*
1411          * The FIFOSEND flag is set to inform other processes that a file
1412          * descriptor is pending at the stream head of this pipe.
1413          * The flag is cleared and the sending process is awoken when
1414          * this process has completed receiving the file descriptor.
1415          * XXX This could become out of sync if the process does I_SENDFDs
1416          * and opens on connld attached to the same pipe.
1417          */
1418         case I_RECVFD:
1419         case I_E_RECVFD:
1420                 if (error == 0) {
1421                         fn_lock = fnp->fn_lock;
1422                         mutex_enter(&fn_lock->flk_lock);
1423                         if (fnp->fn_flag & FIFOSEND) {
1424                                 fnp->fn_flag &= ~FIFOSEND;
1425                                 cv_broadcast(&fnp->fn_dest->fn_wait_cv);




1109         tsignal(curthread, SIGPIPE);
1110         return (error);
1111 }
1112 
1113 /*ARGSUSED6*/
1114 static int
1115 fifo_ioctl(vnode_t *vp, int cmd, intptr_t arg, int mode,
1116         cred_t *cr, int *rvalp, caller_context_t *ct)
1117 {
1118         /*
1119          * Just a quick check
1120          * Once we go to streams mode we don't ever revert back
1121          * So we do this quick check so as not to incur the overhead
1122          * associated with acquiring the lock
1123          */
1124         return ((VTOF(vp)->fn_flag & FIFOFAST) ?
1125             fifo_fastioctl(vp, cmd, arg, mode, cr, rvalp) :
1126             fifo_strioctl(vp, cmd, arg, mode, cr, rvalp));
1127 }
1128 
1129 static inline int
1130 fifo_ioctl_getpeercred(fifonode_t *fnp, intptr_t arg, int mode)
1131 {
1132         k_peercred_t *kp = (k_peercred_t *)arg;
1133 
1134         if (mode == FKIOCTL && fnp->fn_pcredp != NULL) {
1135                 crhold(fnp->fn_pcredp);
1136                 kp->pc_cr = fnp->fn_pcredp;
1137                 kp->pc_cpid = fnp->fn_cpid;
1138                 return (0);
1139         } else {
1140                 return (ENOTSUP);
1141         }
1142 }
1143 
1144 static int
1145 fifo_fastioctl(vnode_t *vp, int cmd, intptr_t arg, int mode,
1146         cred_t *cr, int *rvalp)
1147 {
1148         fifonode_t      *fnp            = VTOF(vp);
1149         fifonode_t      *fn_dest;
1150         int             error           = 0;
1151         fifolock_t      *fn_lock        = fnp->fn_lock;
1152         int             cnt;
1153 
1154         /*
1155          * tty operations not allowed
1156          */
1157         if (((cmd & IOCTYPE) == LDIOC) ||
1158             ((cmd & IOCTYPE) == tIOC) ||
1159             ((cmd & IOCTYPE) == TIOC)) {
1160                 return (EINVAL);
1161         }
1162 
1163         mutex_enter(&fn_lock->flk_lock);


1343                  * (waking readers probably doesn't make sense, but it
1344                  *  doesn't hurt; i.e. we just got rid of all the data
1345                  *  what's to read ?)
1346                  */
1347                 if (fn_dest->fn_flag & (FIFOWANTW | FIFOWANTR)) {
1348                         fn_dest->fn_flag &= ~(FIFOWANTW | FIFOWANTR);
1349                         cv_broadcast(&fn_dest->fn_wait_cv);
1350                 }
1351                 *rvalp = 0;
1352                 break;
1353 
1354         /*
1355          * Since no band data can ever get on a fifo in fast mode
1356          * just return 0.
1357          */
1358         case I_FLUSHBAND:
1359                 error = 0;
1360                 *rvalp = 0;
1361                 break;
1362 
1363         case _I_GETPEERCRED:
1364                 error = fifo_ioctl_getpeercred(fnp, arg, mode);
1365                 break;
1366 
1367         /*
1368          * invalid calls for stream head or fifos
1369          */
1370 
1371         case I_POP:             /* shouldn't happen */
1372         case I_LOOK:
1373         case I_LINK:
1374         case I_PLINK:
1375         case I_UNLINK:
1376         case I_PUNLINK:
1377 
1378         /*
1379          * more invalid tty type of ioctls
1380          */
1381 
1382         case SRIOCSREDIR:
1383         case SRIOCISREDIR:
1384                 error = EINVAL;
1385                 break;
1386 


1394 stream_mode:
1395         /*
1396          * streams mode
1397          */
1398         mutex_exit(&fn_lock->flk_lock);
1399         return (fifo_strioctl(vp, cmd, arg, mode, cr, rvalp));
1400 
1401 }
1402 
1403 /*
1404  * FIFO is in STREAMS mode; STREAMS framework does most of the work.
1405  */
1406 static int
1407 fifo_strioctl(vnode_t *vp, int cmd, intptr_t arg, int mode,
1408         cred_t *cr, int *rvalp)
1409 {
1410         fifonode_t      *fnp = VTOF(vp);
1411         int             error;
1412         fifolock_t      *fn_lock;
1413 
1414         if (cmd == _I_GETPEERCRED)
1415                 return (fifo_ioctl_getpeercred(fnp, arg, mode));









1416 
1417         error = strioctl(vp, cmd, arg, mode, U_TO_K, cr, rvalp);
1418 
1419         switch (cmd) {
1420         /*
1421          * The FIFOSEND flag is set to inform other processes that a file
1422          * descriptor is pending at the stream head of this pipe.
1423          * The flag is cleared and the sending process is awoken when
1424          * this process has completed receiving the file descriptor.
1425          * XXX This could become out of sync if the process does I_SENDFDs
1426          * and opens on connld attached to the same pipe.
1427          */
1428         case I_RECVFD:
1429         case I_E_RECVFD:
1430                 if (error == 0) {
1431                         fn_lock = fnp->fn_lock;
1432                         mutex_enter(&fn_lock->flk_lock);
1433                         if (fnp->fn_flag & FIFOSEND) {
1434                                 fnp->fn_flag &= ~FIFOSEND;
1435                                 cv_broadcast(&fnp->fn_dest->fn_wait_cv);