1

I'm new to Linux kernel development, and I have a question that I don't think has been addressed previously:

How do you find a sub-string within a buffer inside a kernel function?

Imagine that I read in a decently size file to a buffer (ls -lart says the file size is around 3000). I would like to find, and print the line where a sub-string exists within that buffer. Because we are in the kernel, most standard stdio.h or string.h functions like strstr or fgets are not available. So many current stack overflow questions like: Check substring exists in a string in C are not as valid. However, I did find a question like: Check for substring in a buffer, but is using memmem() the best alternative? While I can cheat, and manually hard code where in the buffer I'm looking, it's not the programmer way.

S.S. Anne
  • 15,171
  • 8
  • 38
  • 76
Billy Thorton
  • 213
  • 1
  • 4
  • 12
  • I'm pretty sure that the kernel provides most of the string functions, including `strstr`. – S.S. Anne Oct 13 '19 at 21:37
  • And it's "Thanks in advance!", not "Thanks in advanced!". – S.S. Anne Oct 13 '19 at 21:38
  • When I, try to include `string.h`, I get an error saying no such file or directory. Apparently, unless I specifically include it as a `-I` in the `gcc` compile, it's not explicitly added. It makes me think it's not how it should be done... – Billy Thorton Oct 13 '19 at 21:41
  • That's not the right header. Hang on, let me `grep` the kernel sources. – S.S. Anne Oct 13 '19 at 21:42

1 Answers1

1

strstr is available in the Linux kernel. It's declared in linux/string.h.

However, using memmem could possibly be safer if the buffer that you've read the "file" into isn't nul-terminated.

If you want to search for a full line, you can add \n to the beginning and end of the string that you're searching for.

Alternatively, if you don't want to include the full line that you want to search, you can rewind (using a char pointer or similar) to the \n before the result of strstr.

If you want to print this string, use printk from linux/printk.h. It's similar to printf except that it has a few extensions to the %p format -- though you probably won't have to bother with printing pointers.

S.S. Anne
  • 15,171
  • 8
  • 38
  • 76
  • 1
    ah! That makes sense - I thought it strange that string manipulation wouldn't be available in the kernel. Quite an easy answer. May I expand your answer - how would you best print the line that matches a substring within the buffer? – Billy Thorton Oct 13 '19 at 21:46
  • @BillyThorton `kprint`, I believe. – S.S. Anne Oct 13 '19 at 21:47
  • Sorry, not the function to perform the printing. I'm asking how you would loop through the buffer to match the line with the substring. Using `strstr` you can find existence, but a bit trickier when you want the full line that matches. – Billy Thorton Oct 13 '19 at 21:48
  • @BillyThorton I would say add `\n` to the beginning and end of the string that you're searching for. – S.S. Anne Oct 13 '19 at 21:50
  • And just use the full line as the substring, rather than just a substring within that line? – Billy Thorton Oct 13 '19 at 21:52
  • @BillyThorton Yeah. Although you *could* rewind to the byte just after the `\n`. – S.S. Anne Oct 13 '19 at 21:53
  • Where would rewind be? Since `stdio.h`, like `string.h` is hidden in another linux include file, and file streams in the kernel aren't the same as in userland (as the `filp` function demonstrates? – Billy Thorton Oct 13 '19 at 22:42
  • @BillyThorton Not the `rewind` function. Just decrement the pointer until it points to `\n`, and then increment it again. – S.S. Anne Oct 13 '19 at 22:42