why strsep segment fault - strsep

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
char *buf = "2012/9/8";
char sep[] = "/";
char *token;
// char *bp = strdup(buf);
char *bp = buf;
while ((token = strsep(&bp,sep))) {
printf("tok = `%s'\n", token);
}
free(bp);
return 0;
}
If I don't use strdup. assign "char *bp = buf". then the above programe will segment fault.
gdb output below:
Program terminated with signal 11, Segmentation fault.
#0 0x00007fcc949c13b5 in strsep () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) bt
#0 0x00007fcc949c13b5 in strsep () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00000000004005d5 in main () at str_split.c:11
what's wrong with the program ?

If I don't use strdup. assign "char *bp = buf". then the above
programe will segment fault.
It might have to to something with buf pointing to memory which cannot be legally written, a string literal in this case. If you use strdup you'll be writing to your own writable copy.

Related

static pointer overflow in bss

I'm using w00w00 exercises on static pointer overflow in bss. I put the buffer and buffer pointer into static struct to force overflowing the pointer. Otherwise, it put the pointer before and buffer and no overflow happens.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#define BUFSIZE 16
#define ADDRLEN 4 /* # of bytes in an address */
int main()
{
u_long diff;
struct buf {
char buf[BUFSIZE];
char *bufptr ;
} ;
static struct buf a;
a.bufptr = a.buf, diff = (u_long)a.buf - (u_long)&a.bufptr;
printf("bufptr (%p) = %p, buf = %p, diff = 0x%x (%d) bytes\n",
&a.bufptr,a.bufptr, a.buf, diff, diff);
memset(a.buf, 'A', (u_int)(diff + ADDRLEN));
printf("bufptr (%p) = %p, buf = %p, diff = 0x%x (%d) bytes\n",
&a.bufptr, a.bufptr, a.buf, diff, diff);
return 0;
}
I'm currently getting this error when I used AddressSanitizer
==27643==ERROR: AddressSanitizer: negative-size-param: (size=-12)
SUMMARY: AddressSanitizer: negative-size-param ??:0 __asan_memset
==27643==ABORTING
Is there a flag or way to force the overflow?
Edit:
I figured out the problem. Diff result was -16.
I mad it look like this
diff = (u_long)&a.bufptr - (u_long)a.buf
Now it work fine.
Try size which is larger than struct size but not large enough to be interpreted as negative:
memset(a.buf, 'A', 1024);
Also be sure to compile with -fno-common as explained in Asan FAQ.

C program character return incorrect value

This code returns correct pointer address to main function but output is faulty
#include <stdio.h>
#include <stdlib.h>
char* ret();
int main()
{
char *na;
na = ret();
printf("%s \n",na);
return 0;
}
char* ret()
{
char c[15],*p;
scanf("%s",c);
p = c;
return p;
}
This gives wrong output in Code block with GNU GCC compiler.
when i give an input "goods" output produced is goo£Í"

LLVM error accessing loopinfo in function pass

I'm trying to get loop information from IR by writing a function pass. So I followed some examples and wrote like following. I'm not very familiar with writing passes and pass managers.
#include <iostream>
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "llvm/Function.h"
#include "llvm/BasicBlock.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Support/IRReader.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Pass.h"
#include "llvm/PassManager.h"
using namespace llvm;
namespace {
class DetectLoop: public FunctionPass {
public:
DetectLoop() : FunctionPass(ID) {}
static char ID;
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<LoopInfo>();//I'm not sure if it's correct here *****1*****
}
virtual bool runOnFunction(Function &F) {
if (!F.isDeclaration())
LoopInfo &li = getAnalysis<LoopInfo>(F);//*****2*****
for (Function::iterator I = F.begin(); I != F.end(); I++) {
BasicBlock *BB = I;
for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) {
Instruction &I = *BI++;
//did noting inside
}
}
return false;
}
};
}
char DetectLoop::ID = 0;
int main(int argc, char** argv)
{
if (argc < 2) {
errs() << "Expected an argument - IR file name\n";
exit(1);
}
SMDiagnostic Err;
std::cout<<argv[1]<<std::endl;
Module *Mod = ParseIRFile(argv[1], Err, getGlobalContext());
Err.Print(argv[0], errs());
if (Mod) {
PassManager PM;
PM.add(new DetectLoop());
PM.add(new LoopInfo());//*****3*****
PM.run(*Mod);
}
else {
std::cout << "Mod is null" << std::endl;
}
return 0;
}
While I was running this program, it just showed me segmentation error(core dumped),
but when I commented out addRequired the error msg I got was
IRparser: PassManager.cpp:1200: virtual llvm::Pass* llvm::PMDataManager::getOnTheFlyPass
(llvm::Pass*, llvm::AnalysisID, llvm::Function&): Assertion `0 && "Unable to find on the fly pass"' failed.
Stack dump:
0. Running pass 'Function Pass Manager' on module '../../testcase/forloop1.ll'.
1. Running pass 'Unnamed pass: implement Pass::getPassName()' on function '#main'
Aborted (core dumped)
I have marked 3 places I'm not sure which is correct or not. Can anyone help me with that?
If you use it in a Module:
LoopInfo &li = getAnalysis<LoopInfo>(F)
If you use it in a function:
LoopInfo &li = getAnalysis<LoopInfo>()
I had this question before. After searching several answers, I found the solution.
You should change the location of the two statements below:
PM.add(new DetectLoop());
PM.add(new LoopInfo());//*****3*****
Because LoopInfo Pass must be registed before your own pass.

How to properly insert a function call using LLVM?

I'm trying to set up a pass that will insert a couple of global variables as well as a couple of function calls at the beginning of main. However, I believe I have an issue with setting up the function description correctly. My code compiles, but when I try to run the pass I get this error:
void llvm::CallInst::init(llvm::Value*, llvm::ArrayRef<llvm::Value*>, const llvm::Twine&):
Assertion `(Args.size() == FTy->getNumParams() || (FTy->isVarArg() && Args.size() > FTy-
>getNumParams())) && "Calling a function with bad signature!"' failed.
Here is the code I have written so far:
#include "llvm/IR/Instructions.h"
#include "llvm/Pass.h"
#include "llvm/Support/InstIterator.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Value.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Module.h"
using namespace llvm;
namespace{
struct fun_insert : public FunctionPass{
static char ID;
fun_insert():FunctionPass(ID){}
virtual bool runOnFunction(Function &F){
if (F.getName() == "main"){
for (inst_iterator I = inst_begin(F), E= inst_end(F); I != E; ++I){
Instruction *inst = &*I;
if(dyn_cast<AllocaInst> (inst)){
errs() << "test" << "\n";
GlobalVariable *virtAddr = new GlobalVariable(*F.getParent(),
Type::getInt8PtrTy(F.getContext()), false,
GlobalValue::ExternalLinkage, 0, "virt_addr");
virtAddr->setAlignment(4);
Module *M = F.getParent();
Constant *c = M->getOrInsertFunction("open",
IntegerType::get(F.getContext(),32),
PointerType::get(Type::getInt8PtrTy(F.getContext(), 8),8),
IntegerType::get(F.getContext(),32), NULL);
Function *open = cast<Function>(c);
//ConstantInt *a = ConstantInt::get(M->getContext(), APInt(32, 9437184));
IRBuilder<> builder(inst);
Value *strPtr = builder.CreateGlobalStringPtr("/dev/mem", ".str");
ConstantInt *a = builder.getInt32(9437184);
//CallInst *openRet = builder.CreateCall2(open, strPtr, a, "open");
builder.CreateCall2(open, strPtr, a, "open");
}
errs() << *inst <<"\n";
}
}
return false;
}
};
}
char fun_insert::ID=0;
static RegisterPass<fun_insert>
X("fun_insert", "Insert Function Test", false, false);
Thanks for any help!
I believe I have resolved the issue. The issue did lie with the function declaration and call. I adjusted the code as follows:
Constant *c = M->getOrInsertFunction("open",
FunctionType::getInt32Ty(F.getContext()),
Type::getInt8PtrTy(F.getContext()),
Type::getInt32Ty(F.getContext()),
NULL);
Function *open = cast<Function>(c);
IRBuilder<> builder(inst);
Value *strPtr = builder.CreateGlobalStringPtr("/dev/mem", ".str");
ConstantInt *a = builder.getInt32(9437184);
builder.CreateCall2(open,strPtr,a);

Wrong codecvt result in ViualStudio 2010

The following code prints "failed" to console:
#include "stdafx.h"
#include <locale>
#include <memory>
#include <string>
#include <cstring>
#include <iostream>
int main(int argc, char* argv[])
{
typedef std::codecvt<wchar_t, char, mbstate_t> cvt;
// string to convert
const char cstr[] = "тест";
size_t sz = std::strlen(cstr);
mbstate_t state;
const char *cnext;
wchar_t *wnext;
// buffer to write
wchar_t *buffer = new wchar_t[sz + 1];
std::uninitialized_fill(buffer, buffer + sz + 1, 0);
// converting char* to wchar*, using locale
cvt::result res;
std::locale l(std::locale("Russian_Russia.1251"));
res = std::use_facet<cvt>(l).in(state,
cstr, cstr + sz, cnext,
buffer, buffer + sz + 1, wnext);
if(res == cvt::error)
std::wcout << L"failed" << std::endl;
else
std::wcout << buffer << std::wcout;
delete [] buffer;
return 0;
}
I looked into sources and found out that function in() fails because function _Mbrtowc (wmbtowc.c) returns -1:
if (___mb_cur_max_l_func(locale) <= 1 ||
(MultiByteToWideChar(codepage,
MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
(char *)pst,
2,
pwc,
(pwc) ? 1 : 0) == 0))
{ /* translation failed */
*pst = 0;
errno = EILSEQ;
return -1;
}
because ___mb_cur_max_l_func() (initctyp.c) returns 1 for Russian_Russa.1251 locale. What it means? I think it is not normal, that codecvt can't convert char* into wchar_t*.
mbstate_t state;
You forgot to initialize that. Fix:
mbstate_t state = { 0 };

Resources