next = msghdr->msg_spot; for (len = 0; len < msgsz; len += msginfo.msgssz) { size_t tlen;
/* compare input (size_t) value against restrict (int) value */ if (msgsz > (size_t)msginfo.msgssz) { tlen = msginfo.msgssz; } else { tlen = msgsz; } if (next <= -1) { panic("next too low #3"); } if (next >= msginfo.msgseg) { panic("next out of range #3"); } SYSV_MSG_SUBSYS_UNLOCK(); eval = copyout(&msgpool[next * msginfo.msgssz], user_msgp, tlen); SYSV_MSG_SUBSYS_LOCK(); if (eval != 0) { #ifdef MSG_DEBUG_OK printf("error (%d) copying out message segment\\n", eval); #endif msg_freehdr(msghdr); wakeup((caddr_t)msqptr); goto msgrcvout; } user_msgp = user_msgp + tlen; /* ptr math */ next = msgmaps[next].next; }
Patch
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
for (len = 0; len < msgsz; len += msginfo.msgssz) { size_t tlen;
/* * copy the full segment, or less if we're at the end * of the message */ tlen = MIN(msgsz - len, (size_t)msginfo.msgssz); if (next <= -1) { panic("next too low #3"); } if (next >= msginfo.msgseg) { panic("next out of range #3"); } SYSV_MSG_SUBSYS_UNLOCK(); eval = copyout(&msgpool[next * msginfo.msgssz], user_msgp, tlen);
class Config extends TaintTracking::Configuration { Config() { this = "taint size to copy size" }
override predicate isSource(DataFlow::Node source) { exists(LocalVariable lv, Function f | isSYSCall(f) and lv.getFunction() = f and ( not source.asExpr().(Literal).isConstant() ) and lv.getAnAccess() = source.asExpr() ) }
override predicate isSink(DataFlow::Node sink) { exists (FunctionCall fc | fc.getTarget().getName() = "copyout" and fc.getArgument(2) = sink.asExpr() ) } }
from Config cfg, DataFlow::PathNode source, DataFlow::PathNode sink where cfg.hasFlowPath(source, sink) selectsource, " to ", sink, " in ", source.getNode().getFunction().getName()