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


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















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


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




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


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




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


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


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









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